# HG changeset patch # User kizune # Date 1386247049 -14400 # Node ID e254e5940c195e75343f5187f6e60eaba476c0c5 # Parent 0611ce949aaac26c17eed532a3efd53b95a9eff0# Parent a3dc98dc4d21adda679b382ebaecebccea5ef136 Merge diff -r 0611ce949aaa -r e254e5940c19 .hgtags --- a/.hgtags Tue Dec 03 14:13:06 2013 +0400 +++ b/.hgtags Thu Dec 05 16:37:29 2013 +0400 @@ -398,3 +398,5 @@ f573d00213b7170c2ff856f9cd83cd148437f5b9 jdk8-b117 abad3b2d905d9e1ad767c94baa94aba6ed5b207b hs25-b60 c9f439732b18ea16f7e65815327d5ea7092cc258 jdk8-b118 +b2426da30009cd3069d03de073f351e6432c7682 hs25-b61 +ce42d815dd2130250acf6132b51b624001638f0d jdk8-b119 diff -r 0611ce949aaa -r e254e5940c19 make/hotspot_version --- a/make/hotspot_version Tue Dec 03 14:13:06 2013 +0400 +++ b/make/hotspot_version Thu Dec 05 16:37:29 2013 +0400 @@ -35,7 +35,7 @@ HS_MAJOR_VER=25 HS_MINOR_VER=0 -HS_BUILD_NUMBER=60 +HS_BUILD_NUMBER=61 JDK_MAJOR_VER=1 JDK_MINOR_VER=8 diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/classfile/classFileParser.cpp --- a/src/share/vm/classfile/classFileParser.cpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/classfile/classFileParser.cpp Thu Dec 05 16:37:29 2013 +0400 @@ -4483,8 +4483,8 @@ for (int index = 0; index < num_methods; index++) { Method* m = methods->at(index); - // skip static and methods - if ((!m->is_static()) && + // skip private, static, and methods + if ((!m->is_private() && !m->is_static()) && (m->name() != vmSymbols::object_initializer_name())) { Symbol* name = m->name(); diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/classfile/classLoaderData.cpp --- a/src/share/vm/classfile/classLoaderData.cpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/classfile/classLoaderData.cpp Thu Dec 05 16:37:29 2013 +0400 @@ -62,13 +62,13 @@ #include "runtime/safepoint.hpp" #include "runtime/synchronizer.hpp" #include "utilities/growableArray.hpp" +#include "utilities/macros.hpp" #include "utilities/ostream.hpp" #if INCLUDE_TRACE #include "trace/tracing.hpp" #endif - ClassLoaderData * ClassLoaderData::_the_null_class_loader_data = NULL; ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_anonymous, Dependencies dependencies) : @@ -754,7 +754,7 @@ if (Tracing::enabled()) { if (Tracing::is_event_enabled(TraceClassUnloadEvent)) { assert(_unloading != NULL, "need class loader data unload list!"); - _class_unload_time = Tracing::time(); + _class_unload_time = Ticks::now(); classes_unloading_do(&class_unload_event); } Tracing::on_unloading_classes(); @@ -832,7 +832,7 @@ #if INCLUDE_TRACE -TracingTime ClassLoaderDataGraph::_class_unload_time; +Ticks ClassLoaderDataGraph::_class_unload_time; void ClassLoaderDataGraph::class_unload_event(Klass* const k) { diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/classfile/classLoaderData.hpp --- a/src/share/vm/classfile/classLoaderData.hpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/classfile/classLoaderData.hpp Thu Dec 05 16:37:29 2013 +0400 @@ -33,7 +33,7 @@ #include "utilities/growableArray.hpp" #if INCLUDE_TRACE -# include "trace/traceTime.hpp" +# include "utilities/ticks.hpp" #endif // @@ -98,7 +98,7 @@ #if INCLUDE_TRACE private: - static TracingTime _class_unload_time; + static Ticks _class_unload_time; static void class_unload_event(Klass* const k); #endif }; diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/classfile/systemDictionary.cpp --- a/src/share/vm/classfile/systemDictionary.cpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/classfile/systemDictionary.cpp Thu Dec 05 16:37:29 2013 +0400 @@ -55,13 +55,13 @@ #include "runtime/signature.hpp" #include "services/classLoadingService.hpp" #include "services/threadService.hpp" +#include "utilities/macros.hpp" +#include "utilities/ticks.hpp" #if INCLUDE_TRACE #include "trace/tracing.hpp" - #include "trace/traceMacros.hpp" #endif - Dictionary* SystemDictionary::_dictionary = NULL; PlaceholderTable* SystemDictionary::_placeholders = NULL; Dictionary* SystemDictionary::_shared_dictionary = NULL; @@ -598,7 +598,7 @@ assert(name != NULL && !FieldType::is_array(name) && !FieldType::is_obj(name), "invalid class name"); - TracingTime class_load_start_time = Tracing::time(); + Ticks class_load_start_time = Ticks::now(); // UseNewReflection // Fix for 4474172; see evaluation for more details @@ -1006,7 +1006,7 @@ TRAPS) { TempNewSymbol parsed_name = NULL; - TracingTime class_load_start_time = Tracing::time(); + Ticks class_load_start_time = Ticks::now(); ClassLoaderData* loader_data; if (host_klass.not_null()) { @@ -2665,13 +2665,12 @@ } // utility function for class load event -void SystemDictionary::post_class_load_event(TracingTime start_time, +void SystemDictionary::post_class_load_event(const Ticks& start_time, instanceKlassHandle k, Handle initiating_loader) { #if INCLUDE_TRACE EventClassLoad event(UNTIMED); if (event.should_commit()) { - event.set_endtime(Tracing::time()); event.set_starttime(start_time); event.set_loadedClass(k()); oop defining_class_loader = k->class_loader(); diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/classfile/systemDictionary.hpp Thu Dec 05 16:37:29 2013 +0400 @@ -31,7 +31,6 @@ #include "oops/symbol.hpp" #include "runtime/java.hpp" #include "runtime/reflectionUtils.hpp" -#include "trace/traceTime.hpp" #include "utilities/hashtable.hpp" #include "utilities/hashtable.inline.hpp" @@ -78,6 +77,7 @@ template class HashtableBucket; class ResolutionErrorTable; class SymbolPropertyTable; +class Ticks; // Certain classes are preloaded, such as java.lang.Object and java.lang.String. // They are all "well-known", in the sense that no class loader is allowed @@ -165,6 +165,7 @@ \ do_klass(StringBuffer_klass, java_lang_StringBuffer, Pre ) \ do_klass(StringBuilder_klass, java_lang_StringBuilder, Pre ) \ + do_klass(misc_Unsafe_klass, sun_misc_Unsafe, Pre ) \ \ /* It's NULL in non-1.4 JDKs. */ \ do_klass(StackTraceElement_klass, java_lang_StackTraceElement, Opt ) \ @@ -637,7 +638,7 @@ static void add_to_hierarchy(instanceKlassHandle k, TRAPS); // event based tracing - static void post_class_load_event(TracingTime start_time, instanceKlassHandle k, + static void post_class_load_event(const Ticks& start_time, instanceKlassHandle k, Handle initiating_loader); // We pass in the hashtable index so we can calculate it outside of // the SystemDictionary_lock. diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/classfile/verifier.cpp --- a/src/share/vm/classfile/verifier.cpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/classfile/verifier.cpp Thu Dec 05 16:37:29 2013 +0400 @@ -2302,6 +2302,24 @@ } } +bool ClassVerifier::is_same_or_direct_interface( + instanceKlassHandle klass, + VerificationType klass_type, + VerificationType ref_class_type) { + if (ref_class_type.equals(klass_type)) return true; + Array* local_interfaces = klass->local_interfaces(); + if (local_interfaces != NULL) { + for (int x = 0; x < local_interfaces->length(); x++) { + Klass* k = local_interfaces->at(x); + assert (k != NULL && k->is_interface(), "invalid interface"); + if (ref_class_type.equals(VerificationType::reference_type(k->name()))) { + return true; + } + } + } + return false; +} + void ClassVerifier::verify_invoke_instructions( RawBytecodeStream* bcs, u4 code_length, StackMapFrame* current_frame, bool *this_uninit, VerificationType return_type, @@ -2432,23 +2450,38 @@ return; } } else if (opcode == Bytecodes::_invokespecial - && !ref_class_type.equals(current_type()) + && !is_same_or_direct_interface(current_class(), current_type(), ref_class_type) && !ref_class_type.equals(VerificationType::reference_type( current_class()->super()->name()))) { bool subtype = false; + bool have_imr_indirect = cp->tag_at(index).value() == JVM_CONSTANT_InterfaceMethodref; if (!current_class()->is_anonymous()) { subtype = ref_class_type.is_assignable_from( current_type(), this, CHECK_VERIFY(this)); } else { - subtype = ref_class_type.is_assignable_from(VerificationType::reference_type( - current_class()->host_klass()->name()), this, CHECK_VERIFY(this)); + VerificationType host_klass_type = + VerificationType::reference_type(current_class()->host_klass()->name()); + subtype = ref_class_type.is_assignable_from(host_klass_type, this, CHECK_VERIFY(this)); + + // If invokespecial of IMR, need to recheck for same or + // direct interface relative to the host class + have_imr_indirect = (have_imr_indirect && + !is_same_or_direct_interface( + InstanceKlass::cast(current_class()->host_klass()), + host_klass_type, ref_class_type)); } if (!subtype) { verify_error(ErrorContext::bad_code(bci), "Bad invokespecial instruction: " "current class isn't assignable to reference class."); return; + } else if (have_imr_indirect) { + verify_error(ErrorContext::bad_code(bci), + "Bad invokespecial instruction: " + "interface method reference is in an indirect superinterface."); + return; } + } // Match method descriptor with operand stack for (int i = nargs - 1; i >= 0; i--) { // Run backwards diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/classfile/verifier.hpp --- a/src/share/vm/classfile/verifier.hpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/classfile/verifier.hpp Thu Dec 05 16:37:29 2013 +0400 @@ -345,6 +345,9 @@ // that a class has been verified and prepared for execution. bool was_recursively_verified() { return _klass->is_rewritten(); } + bool is_same_or_direct_interface(instanceKlassHandle klass, + VerificationType klass_type, VerificationType ref_class_type); + public: enum { BYTECODE_OFFSET = 1, diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/classfile/vmSymbols.hpp Thu Dec 05 16:37:29 2013 +0400 @@ -331,6 +331,7 @@ template(findNative_name, "findNative") \ template(deadChild_name, "deadChild") \ template(addClass_name, "addClass") \ + template(throwIllegalAccessError_name, "throwIllegalAccessError") \ template(getFromClass_name, "getFromClass") \ template(dispatch_name, "dispatch") \ template(getSystemClassLoader_name, "getSystemClassLoader") \ diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Thu Dec 05 16:37:29 2013 +0400 @@ -1993,7 +1993,7 @@ GenCollectedHeap* gch = GenCollectedHeap::heap(); STWGCTimer* gc_timer = GenMarkSweep::gc_timer(); - gc_timer->register_gc_start(os::elapsed_counter()); + gc_timer->register_gc_start(); SerialOldTracer* gc_tracer = GenMarkSweep::gc_tracer(); gc_tracer->report_gc_start(gch->gc_cause(), gc_timer->gc_start()); @@ -2089,7 +2089,7 @@ size_policy()->msc_collection_end(gch->gc_cause()); } - gc_timer->register_gc_end(os::elapsed_counter()); + gc_timer->register_gc_end(); gc_tracer->report_gc_end(gc_timer->gc_end(), gc_timer->time_partitions()); @@ -2475,7 +2475,7 @@ void CMSCollector::register_gc_start(GCCause::Cause cause) { _cms_start_registered = true; - _gc_timer_cm->register_gc_start(os::elapsed_counter()); + _gc_timer_cm->register_gc_start(); _gc_tracer_cm->report_gc_start(cause, _gc_timer_cm->gc_start()); } @@ -2483,7 +2483,7 @@ if (_cms_start_registered) { report_heap_summary(GCWhen::AfterGC); - _gc_timer_cm->register_gc_end(os::elapsed_counter()); + _gc_timer_cm->register_gc_end(); _gc_tracer_cm->report_gc_end(_gc_timer_cm->gc_end(), _gc_timer_cm->time_partitions()); _cms_start_registered = false; } diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp Thu Dec 05 16:37:29 2013 +0400 @@ -145,7 +145,7 @@ ); #endif /* USDT2 */ - _collector->_gc_timer_cm->register_gc_pause_start("Initial Mark", os::elapsed_counter()); + _collector->_gc_timer_cm->register_gc_pause_start("Initial Mark"); GenCollectedHeap* gch = GenCollectedHeap::heap(); GCCauseSetter gccs(gch, GCCause::_cms_initial_mark); @@ -157,7 +157,7 @@ VM_CMS_Operation::verify_after_gc(); - _collector->_gc_timer_cm->register_gc_pause_end(os::elapsed_counter()); + _collector->_gc_timer_cm->register_gc_pause_end(); #ifndef USDT2 HS_DTRACE_PROBE(hs_private, cms__initmark__end); @@ -182,7 +182,7 @@ ); #endif /* USDT2 */ - _collector->_gc_timer_cm->register_gc_pause_start("Final Mark", os::elapsed_counter()); + _collector->_gc_timer_cm->register_gc_pause_start("Final Mark"); GenCollectedHeap* gch = GenCollectedHeap::heap(); GCCauseSetter gccs(gch, GCCause::_cms_final_remark); @@ -195,7 +195,7 @@ VM_CMS_Operation::verify_after_gc(); _collector->save_heap_summary(); - _collector->_gc_timer_cm->register_gc_pause_end(os::elapsed_counter()); + _collector->_gc_timer_cm->register_gc_pause_end(); #ifndef USDT2 HS_DTRACE_PROBE(hs_private, cms__remark__end); diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Thu Dec 05 16:37:29 2013 +0400 @@ -56,6 +56,7 @@ #include "oops/oop.inline.hpp" #include "oops/oop.pcgc.inline.hpp" #include "runtime/vmThread.hpp" +#include "utilities/ticks.hpp" size_t G1CollectedHeap::_humongous_object_threshold_in_words = 0; @@ -1284,7 +1285,7 @@ } STWGCTimer* gc_timer = G1MarkSweep::gc_timer(); - gc_timer->register_gc_start(os::elapsed_counter()); + gc_timer->register_gc_start(); SerialOldTracer* gc_tracer = G1MarkSweep::gc_tracer(); gc_tracer->report_gc_start(gc_cause(), gc_timer->gc_start()); @@ -1552,7 +1553,7 @@ post_full_gc_dump(gc_timer); - gc_timer->register_gc_end(os::elapsed_counter()); + gc_timer->register_gc_end(); gc_tracer->report_gc_end(gc_timer->gc_end(), gc_timer->time_partitions()); } @@ -2482,7 +2483,7 @@ FullGCCount_lock->notify_all(); } -void G1CollectedHeap::register_concurrent_cycle_start(jlong start_time) { +void G1CollectedHeap::register_concurrent_cycle_start(const Ticks& start_time) { _concurrent_cycle_started = true; _gc_timer_cm->register_gc_start(start_time); @@ -2496,7 +2497,7 @@ _gc_tracer_cm->report_concurrent_mode_failure(); } - _gc_timer_cm->register_gc_end(os::elapsed_counter()); + _gc_timer_cm->register_gc_end(); _gc_tracer_cm->report_gc_end(_gc_timer_cm->gc_end(), _gc_timer_cm->time_partitions()); _concurrent_cycle_started = false; @@ -3887,7 +3888,7 @@ return false; } - _gc_timer_stw->register_gc_start(os::elapsed_counter()); + _gc_timer_stw->register_gc_start(); _gc_tracer_stw->report_gc_start(gc_cause(), _gc_timer_stw->gc_start()); @@ -4265,7 +4266,7 @@ _gc_tracer_stw->report_evacuation_info(&evacuation_info); _gc_tracer_stw->report_tenuring_threshold(_g1_policy->tenuring_threshold()); - _gc_timer_stw->register_gc_end(os::elapsed_counter()); + _gc_timer_stw->register_gc_end(); _gc_tracer_stw->report_gc_end(_gc_timer_stw->gc_end(), _gc_timer_stw->time_partitions()); } // It should now be safe to tell the concurrent mark thread to start diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Thu Dec 05 16:37:29 2013 +0400 @@ -72,6 +72,7 @@ class G1OldTracer; class EvacuationFailedInfo; class nmethod; +class Ticks; typedef OverflowTaskQueue RefToScanQueue; typedef GenericTaskQueueSet RefToScanQueueSet; @@ -746,7 +747,7 @@ return _old_marking_cycles_completed; } - void register_concurrent_cycle_start(jlong start_time); + void register_concurrent_cycle_start(const Ticks& start_time); void register_concurrent_cycle_end(); void trace_heap_after_concurrent_cycle(); diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/gc_implementation/parNew/parNewGeneration.cpp --- a/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp Thu Dec 05 16:37:29 2013 +0400 @@ -915,7 +915,7 @@ GenCollectedHeap* gch = GenCollectedHeap::heap(); - _gc_timer->register_gc_start(os::elapsed_counter()); + _gc_timer->register_gc_start(); assert(gch->kind() == CollectedHeap::GenCollectedHeap, "not a CMS generational heap"); @@ -1091,7 +1091,7 @@ gch->trace_heap_after_gc(&gc_tracer); gc_tracer.report_tenuring_threshold(tenuring_threshold()); - _gc_timer->register_gc_end(os::elapsed_counter()); + _gc_timer->register_gc_end(); gc_tracer.report_gc_end(_gc_timer->gc_end(), _gc_timer->time_partitions()); } diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp --- a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp Thu Dec 05 16:37:29 2013 +0400 @@ -114,7 +114,7 @@ assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); GCCause::Cause gc_cause = heap->gc_cause(); - _gc_timer->register_gc_start(os::elapsed_counter()); + _gc_timer->register_gc_start(); _gc_tracer->report_gc_start(gc_cause, _gc_timer->gc_start()); PSAdaptiveSizePolicy* size_policy = heap->size_policy(); @@ -390,7 +390,7 @@ ParallelTaskTerminator::print_termination_counts(); #endif - _gc_timer->register_gc_end(os::elapsed_counter()); + _gc_timer->register_gc_end(); _gc_tracer->report_gc_end(_gc_timer->gc_end(), _gc_timer->time_partitions()); diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp --- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Thu Dec 05 16:37:29 2013 +0400 @@ -2006,7 +2006,7 @@ ParallelScavengeHeap* heap = gc_heap(); - _gc_timer.register_gc_start(os::elapsed_counter()); + _gc_timer.register_gc_start(); _gc_tracer.report_gc_start(heap->gc_cause(), _gc_timer.gc_start()); TimeStamp marking_start; @@ -2244,7 +2244,7 @@ ParallelTaskTerminator::print_termination_counts(); #endif - _gc_timer.register_gc_end(os::elapsed_counter()); + _gc_timer.register_gc_end(); _gc_tracer.report_dense_prefix(dense_prefix(old_space_id)); _gc_tracer.report_gc_end(_gc_timer.gc_end(), _gc_timer.time_partitions()); diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp --- a/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp Thu Dec 05 16:37:29 2013 +0400 @@ -263,7 +263,7 @@ assert(_preserved_mark_stack.is_empty(), "should be empty"); assert(_preserved_oop_stack.is_empty(), "should be empty"); - _gc_timer.register_gc_start(os::elapsed_counter()); + _gc_timer.register_gc_start(); TimeStamp scavenge_entry; TimeStamp scavenge_midpoint; @@ -691,7 +691,7 @@ #endif - _gc_timer.register_gc_end(os::elapsed_counter()); + _gc_timer.register_gc_end(); _gc_tracer.report_gc_end(_gc_timer.gc_end(), _gc_timer.time_partitions()); diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/gc_implementation/shared/gcTimer.cpp --- a/src/share/vm/gc_implementation/shared/gcTimer.cpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/gc_implementation/shared/gcTimer.cpp Thu Dec 05 16:37:29 2013 +0400 @@ -25,52 +25,55 @@ #include "precompiled.hpp" #include "gc_implementation/shared/gcTimer.hpp" #include "utilities/growableArray.hpp" +#include "utilities/ticks.inline.hpp" -void GCTimer::register_gc_start(jlong time) { +// the "time" parameter for most functions +// has a default value set by Ticks::now() + +void GCTimer::register_gc_start(const Ticks& time) { _time_partitions.clear(); _gc_start = time; } -void GCTimer::register_gc_end(jlong time) { +void GCTimer::register_gc_end(const Ticks& time) { assert(!_time_partitions.has_active_phases(), "We should have ended all started phases, before ending the GC"); _gc_end = time; } -void GCTimer::register_gc_pause_start(const char* name, jlong time) { +void GCTimer::register_gc_pause_start(const char* name, const Ticks& time) { _time_partitions.report_gc_phase_start(name, time); } -void GCTimer::register_gc_pause_end(jlong time) { +void GCTimer::register_gc_pause_end(const Ticks& time) { _time_partitions.report_gc_phase_end(time); } -void GCTimer::register_gc_phase_start(const char* name, jlong time) { +void GCTimer::register_gc_phase_start(const char* name, const Ticks& time) { _time_partitions.report_gc_phase_start(name, time); } -void GCTimer::register_gc_phase_end(jlong time) { +void GCTimer::register_gc_phase_end(const Ticks& time) { _time_partitions.report_gc_phase_end(time); } - -void STWGCTimer::register_gc_start(jlong time) { +void STWGCTimer::register_gc_start(const Ticks& time) { GCTimer::register_gc_start(time); register_gc_pause_start("GC Pause", time); } -void STWGCTimer::register_gc_end(jlong time) { +void STWGCTimer::register_gc_end(const Ticks& time) { register_gc_pause_end(time); GCTimer::register_gc_end(time); } -void ConcurrentGCTimer::register_gc_pause_start(const char* name, jlong time) { - GCTimer::register_gc_pause_start(name, time); +void ConcurrentGCTimer::register_gc_pause_start(const char* name) { + GCTimer::register_gc_pause_start(name); } -void ConcurrentGCTimer::register_gc_pause_end(jlong time) { - GCTimer::register_gc_pause_end(time); +void ConcurrentGCTimer::register_gc_pause_end() { + GCTimer::register_gc_pause_end(); } void PhasesStack::clear() { @@ -111,11 +114,11 @@ void TimePartitions::clear() { _phases->clear(); _active_phases.clear(); - _sum_of_pauses = 0; - _longest_pause = 0; + _sum_of_pauses = Tickspan(); + _longest_pause = Tickspan(); } -void TimePartitions::report_gc_phase_start(const char* name, jlong time) { +void TimePartitions::report_gc_phase_start(const char* name, const Ticks& time) { assert(_phases->length() <= 1000, "Too many recored phases?"); int level = _active_phases.count(); @@ -133,13 +136,13 @@ void TimePartitions::update_statistics(GCPhase* phase) { // FIXME: This should only be done for pause phases if (phase->level() == 0) { - jlong pause = phase->end() - phase->start(); + const Tickspan pause = phase->end() - phase->start(); _sum_of_pauses += pause; _longest_pause = MAX2(pause, _longest_pause); } } -void TimePartitions::report_gc_phase_end(jlong time) { +void TimePartitions::report_gc_phase_end(const Ticks& time) { int phase_index = _active_phases.pop(); GCPhase* phase = _phases->adr_at(phase_index); phase->set_end(time); @@ -157,14 +160,6 @@ return _phases->adr_at(index); } -jlong TimePartitions::sum_of_pauses() { - return _sum_of_pauses; -} - -jlong TimePartitions::longest_pause() { - return _longest_pause; -} - bool TimePartitions::has_active_phases() { return _active_phases.count() > 0; } @@ -194,7 +189,7 @@ max_nested_pause_phases(); } - static void validate_pause_phase(GCPhase* phase, int level, const char* name, jlong start, jlong end) { + static void validate_pause_phase(GCPhase* phase, int level, const char* name, const Ticks& start, const Ticks& end) { assert(phase->level() == level, "Incorrect level"); assert(strcmp(phase->name(), name) == 0, "Incorrect name"); assert(phase->start() == start, "Incorrect start"); @@ -209,8 +204,8 @@ TimePartitionPhasesIterator iter(&time_partitions); validate_pause_phase(iter.next(), 0, "PausePhase", 2, 8); - assert(time_partitions.sum_of_pauses() == 8-2, "Incorrect"); - assert(time_partitions.longest_pause() == 8-2, "Incorrect"); + assert(time_partitions.sum_of_pauses() == Ticks(8) - Ticks(2), "Incorrect"); + assert(time_partitions.longest_pause() == Ticks(8) - Ticks(2), "Incorrect"); assert(!iter.has_next(), "Too many elements"); } @@ -227,8 +222,8 @@ validate_pause_phase(iter.next(), 0, "PausePhase1", 2, 3); validate_pause_phase(iter.next(), 0, "PausePhase2", 4, 6); - assert(time_partitions.sum_of_pauses() == 3, "Incorrect"); - assert(time_partitions.longest_pause() == 2, "Incorrect"); + assert(time_partitions.sum_of_pauses() == Ticks(3) - Ticks(0), "Incorrect"); + assert(time_partitions.longest_pause() == Ticks(2) - Ticks(0), "Incorrect"); assert(!iter.has_next(), "Too many elements"); } @@ -245,8 +240,8 @@ validate_pause_phase(iter.next(), 0, "PausePhase", 2, 5); validate_pause_phase(iter.next(), 1, "SubPhase", 3, 4); - assert(time_partitions.sum_of_pauses() == 3, "Incorrect"); - assert(time_partitions.longest_pause() == 3, "Incorrect"); + assert(time_partitions.sum_of_pauses() == Ticks(3) - Ticks(0), "Incorrect"); + assert(time_partitions.longest_pause() == Ticks(3) - Ticks(0), "Incorrect"); assert(!iter.has_next(), "Too many elements"); } @@ -269,8 +264,8 @@ validate_pause_phase(iter.next(), 2, "SubPhase2", 4, 7); validate_pause_phase(iter.next(), 3, "SubPhase3", 5, 6); - assert(time_partitions.sum_of_pauses() == 7, "Incorrect"); - assert(time_partitions.longest_pause() == 7, "Incorrect"); + assert(time_partitions.sum_of_pauses() == Ticks(7) - Ticks(0), "Incorrect"); + assert(time_partitions.longest_pause() == Ticks(7) - Ticks(0), "Incorrect"); assert(!iter.has_next(), "Too many elements"); } @@ -298,8 +293,8 @@ validate_pause_phase(iter.next(), 1, "SubPhase3", 7, 8); validate_pause_phase(iter.next(), 1, "SubPhase4", 9, 10); - assert(time_partitions.sum_of_pauses() == 9, "Incorrect"); - assert(time_partitions.longest_pause() == 9, "Incorrect"); + assert(time_partitions.sum_of_pauses() == Ticks(9) - Ticks(0), "Incorrect"); + assert(time_partitions.longest_pause() == Ticks(9) - Ticks(0), "Incorrect"); assert(!iter.has_next(), "Too many elements"); } @@ -336,8 +331,8 @@ validate_pause_phase(iter.next(), 2, "SubPhase22", 12, 13); validate_pause_phase(iter.next(), 1, "SubPhase3", 15, 16); - assert(time_partitions.sum_of_pauses() == 15, "Incorrect"); - assert(time_partitions.longest_pause() == 15, "Incorrect"); + assert(time_partitions.sum_of_pauses() == Ticks(15) - Ticks(0), "Incorrect"); + assert(time_partitions.longest_pause() == Ticks(15) - Ticks(0), "Incorrect"); assert(!iter.has_next(), "Too many elements"); } diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/gc_implementation/shared/gcTimer.hpp --- a/src/share/vm/gc_implementation/shared/gcTimer.hpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/gc_implementation/shared/gcTimer.hpp Thu Dec 05 16:37:29 2013 +0400 @@ -28,6 +28,7 @@ #include "memory/allocation.hpp" #include "prims/jni_md.h" #include "utilities/macros.hpp" +#include "utilities/ticks.hpp" class ConcurrentPhase; class GCPhase; @@ -45,21 +46,21 @@ class GCPhase { const char* _name; int _level; - jlong _start; - jlong _end; + Ticks _start; + Ticks _end; public: void set_name(const char* name) { _name = name; } - const char* name() { return _name; } + const char* name() const { return _name; } - int level() { return _level; } + int level() const { return _level; } void set_level(int level) { _level = level; } - jlong start() { return _start; } - void set_start(jlong time) { _start = time; } + const Ticks start() const { return _start; } + void set_start(const Ticks& time) { _start = time; } - jlong end() { return _end; } - void set_end(jlong time) { _end = time; } + const Ticks end() const { return _end; } + void set_end(const Ticks& time) { _end = time; } virtual void accept(PhaseVisitor* visitor) = 0; }; @@ -102,22 +103,22 @@ GrowableArray* _phases; PhasesStack _active_phases; - jlong _sum_of_pauses; - jlong _longest_pause; + Tickspan _sum_of_pauses; + Tickspan _longest_pause; public: TimePartitions(); ~TimePartitions(); void clear(); - void report_gc_phase_start(const char* name, jlong time); - void report_gc_phase_end(jlong time); + void report_gc_phase_start(const char* name, const Ticks& time); + void report_gc_phase_end(const Ticks& time); int num_phases() const; GCPhase* phase_at(int index) const; - jlong sum_of_pauses(); - jlong longest_pause(); + const Tickspan sum_of_pauses() const { return _sum_of_pauses; } + const Tickspan longest_pause() const { return _longest_pause; } bool has_active_phases(); private: @@ -133,40 +134,37 @@ class GCTimer : public ResourceObj { NOT_PRODUCT(friend class GCTimerTest;) protected: - jlong _gc_start; - jlong _gc_end; + Ticks _gc_start; + Ticks _gc_end; TimePartitions _time_partitions; public: - virtual void register_gc_start(jlong time); - virtual void register_gc_end(jlong time); + virtual void register_gc_start(const Ticks& time = Ticks::now()); + virtual void register_gc_end(const Ticks& time = Ticks::now()); - void register_gc_phase_start(const char* name, jlong time); - void register_gc_phase_end(jlong time); + void register_gc_phase_start(const char* name, const Ticks& time); + void register_gc_phase_end(const Ticks& time); - jlong gc_start() { return _gc_start; } - jlong gc_end() { return _gc_end; } + const Ticks gc_start() const { return _gc_start; } + const Ticks gc_end() const { return _gc_end; } TimePartitions* time_partitions() { return &_time_partitions; } - long longest_pause(); - long sum_of_pauses(); - protected: - void register_gc_pause_start(const char* name, jlong time); - void register_gc_pause_end(jlong time); + void register_gc_pause_start(const char* name, const Ticks& time = Ticks::now()); + void register_gc_pause_end(const Ticks& time = Ticks::now()); }; class STWGCTimer : public GCTimer { public: - virtual void register_gc_start(jlong time); - virtual void register_gc_end(jlong time); + virtual void register_gc_start(const Ticks& time = Ticks::now()); + virtual void register_gc_end(const Ticks& time = Ticks::now()); }; class ConcurrentGCTimer : public GCTimer { public: - void register_gc_pause_start(const char* name, jlong time); - void register_gc_pause_end(jlong time); + void register_gc_pause_start(const char* name); + void register_gc_pause_end(); }; class TimePartitionPhasesIterator { diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/gc_implementation/shared/gcTrace.cpp --- a/src/share/vm/gc_implementation/shared/gcTrace.cpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/gc_implementation/shared/gcTrace.cpp Thu Dec 05 16:37:29 2013 +0400 @@ -32,6 +32,7 @@ #include "memory/referenceProcessorStats.hpp" #include "runtime/os.hpp" #include "utilities/globalDefinitions.hpp" +#include "utilities/ticks.inline.hpp" #if INCLUDE_ALL_GCS #include "gc_implementation/g1/evacuationInfo.hpp" @@ -45,7 +46,7 @@ return GCTracer_next_gc_id++; } -void GCTracer::report_gc_start_impl(GCCause::Cause cause, jlong timestamp) { +void GCTracer::report_gc_start_impl(GCCause::Cause cause, const Ticks& timestamp) { assert_unset_gc_id(); GCId gc_id = create_new_gc_id(); @@ -54,7 +55,7 @@ _shared_gc_info.set_start_timestamp(timestamp); } -void GCTracer::report_gc_start(GCCause::Cause cause, jlong timestamp) { +void GCTracer::report_gc_start(GCCause::Cause cause, const Ticks& timestamp) { assert_unset_gc_id(); report_gc_start_impl(cause, timestamp); @@ -64,7 +65,7 @@ return _shared_gc_info.id() != SharedGCInfo::UNSET_GCID; } -void GCTracer::report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions) { +void GCTracer::report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions) { assert_set_gc_id(); _shared_gc_info.set_sum_of_pauses(time_partitions->sum_of_pauses()); @@ -75,7 +76,7 @@ send_garbage_collection_event(); } -void GCTracer::report_gc_end(jlong timestamp, TimePartitions* time_partitions) { +void GCTracer::report_gc_end(const Ticks& timestamp, TimePartitions* time_partitions) { assert_set_gc_id(); report_gc_end_impl(timestamp, time_partitions); @@ -97,10 +98,10 @@ const GCId _gc_id; const double _size_threshold_percentage; const size_t _total_size_in_words; - const jlong _timestamp; + const Ticks _timestamp; public: - ObjectCountEventSenderClosure(GCId gc_id, size_t total_size_in_words, jlong timestamp) : + ObjectCountEventSenderClosure(GCId gc_id, size_t total_size_in_words, const Ticks& timestamp) : _gc_id(gc_id), _size_threshold_percentage(ObjectCountCutOffPercent / 100), _total_size_in_words(total_size_in_words), @@ -131,9 +132,7 @@ if (!cit.allocation_failed()) { HeapInspection hi(false, false, false, NULL); hi.populate_table(&cit, is_alive_cl); - - jlong timestamp = os::elapsed_counter(); - ObjectCountEventSenderClosure event_sender(_shared_gc_info.id(), cit.size_of_instances_in_words(), timestamp); + ObjectCountEventSenderClosure event_sender(_shared_gc_info.id(), cit.size_of_instances_in_words(), Ticks::now()); cit.iterate(&event_sender); } } @@ -147,7 +146,7 @@ send_meta_space_summary_event(when, meta_space_summary); } -void YoungGCTracer::report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions) { +void YoungGCTracer::report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions) { assert_set_gc_id(); assert(_tenuring_threshold != UNSET_TENURING_THRESHOLD, "Tenuring threshold has not been reported"); @@ -167,14 +166,14 @@ _tenuring_threshold = tenuring_threshold; } -void OldGCTracer::report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions) { +void OldGCTracer::report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions) { assert_set_gc_id(); GCTracer::report_gc_end_impl(timestamp, time_partitions); send_old_gc_event(); } -void ParallelOldTracer::report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions) { +void ParallelOldTracer::report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions) { assert_set_gc_id(); OldGCTracer::report_gc_end_impl(timestamp, time_partitions); @@ -200,7 +199,7 @@ _g1_young_gc_info.set_type(type); } -void G1NewTracer::report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions) { +void G1NewTracer::report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions) { assert_set_gc_id(); YoungGCTracer::report_gc_end_impl(timestamp, time_partitions); diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/gc_implementation/shared/gcTrace.hpp --- a/src/share/vm/gc_implementation/shared/gcTrace.hpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/gc_implementation/shared/gcTrace.hpp Thu Dec 05 16:37:29 2013 +0400 @@ -35,6 +35,7 @@ #include "gc_implementation/g1/g1YCTypes.hpp" #endif #include "utilities/macros.hpp" +#include "utilities/ticks.hpp" typedef uint GCId; @@ -47,8 +48,6 @@ class BoolObjectClosure; class SharedGCInfo VALUE_OBJ_CLASS_SPEC { - static const jlong UNSET_TIMESTAMP = -1; - public: static const GCId UNSET_GCID = (GCId)-1; @@ -56,23 +55,30 @@ GCId _id; GCName _name; GCCause::Cause _cause; - jlong _start_timestamp; - jlong _end_timestamp; - jlong _sum_of_pauses; - jlong _longest_pause; + Ticks _start_timestamp; + Ticks _end_timestamp; + Tickspan _sum_of_pauses; + Tickspan _longest_pause; public: - SharedGCInfo(GCName name) : _id(UNSET_GCID), _name(name), _cause(GCCause::_last_gc_cause), - _start_timestamp(UNSET_TIMESTAMP), _end_timestamp(UNSET_TIMESTAMP), _sum_of_pauses(0), _longest_pause(0) {} + SharedGCInfo(GCName name) : + _id(UNSET_GCID), + _name(name), + _cause(GCCause::_last_gc_cause), + _start_timestamp(), + _end_timestamp(), + _sum_of_pauses(), + _longest_pause() { + } void set_id(GCId id) { _id = id; } GCId id() const { return _id; } - void set_start_timestamp(jlong timestamp) { _start_timestamp = timestamp; } - jlong start_timestamp() const { return _start_timestamp; } + void set_start_timestamp(const Ticks& timestamp) { _start_timestamp = timestamp; } + const Ticks start_timestamp() const { return _start_timestamp; } - void set_end_timestamp(jlong timestamp) { _end_timestamp = timestamp; } - jlong end_timestamp() const { return _end_timestamp; } + void set_end_timestamp(const Ticks& timestamp) { _end_timestamp = timestamp; } + const Ticks end_timestamp() const { return _end_timestamp; } void set_name(GCName name) { _name = name; } GCName name() const { return _name; } @@ -80,11 +86,11 @@ void set_cause(GCCause::Cause cause) { _cause = cause; } GCCause::Cause cause() const { return _cause; } - void set_sum_of_pauses(jlong duration) { _sum_of_pauses = duration; } - jlong sum_of_pauses() const { return _sum_of_pauses; } + void set_sum_of_pauses(const Tickspan& duration) { _sum_of_pauses = duration; } + const Tickspan sum_of_pauses() const { return _sum_of_pauses; } - void set_longest_pause(jlong duration) { _longest_pause = duration; } - jlong longest_pause() const { return _longest_pause; } + void set_longest_pause(const Tickspan& duration) { _longest_pause = duration; } + const Tickspan longest_pause() const { return _longest_pause; } }; class ParallelOldGCInfo VALUE_OBJ_CLASS_SPEC { @@ -116,8 +122,8 @@ SharedGCInfo _shared_gc_info; public: - void report_gc_start(GCCause::Cause cause, jlong timestamp); - void report_gc_end(jlong timestamp, TimePartitions* time_partitions); + void report_gc_start(GCCause::Cause cause, const Ticks& timestamp); + void report_gc_end(const Ticks& timestamp, TimePartitions* time_partitions); void report_gc_heap_summary(GCWhen::Type when, const GCHeapSummary& heap_summary, const MetaspaceSummary& meta_space_summary) const; void report_gc_reference_stats(const ReferenceProcessorStats& rp) const; void report_object_count_after_gc(BoolObjectClosure* object_filter) NOT_SERVICES_RETURN; @@ -125,8 +131,8 @@ protected: GCTracer(GCName name) : _shared_gc_info(name) {} - virtual void report_gc_start_impl(GCCause::Cause cause, jlong timestamp); - virtual void report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions); + virtual void report_gc_start_impl(GCCause::Cause cause, const Ticks& timestamp); + virtual void report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions); private: void send_garbage_collection_event() const; @@ -143,7 +149,7 @@ protected: YoungGCTracer(GCName name) : GCTracer(name), _tenuring_threshold(UNSET_TENURING_THRESHOLD) {} - virtual void report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions); + virtual void report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions); public: void report_promotion_failed(const PromotionFailedInfo& pf_info); @@ -157,7 +163,7 @@ class OldGCTracer : public GCTracer { protected: OldGCTracer(GCName name) : GCTracer(name) {} - virtual void report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions); + virtual void report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions); public: void report_concurrent_mode_failure(); @@ -175,7 +181,7 @@ void report_dense_prefix(void* dense_prefix); protected: - void report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions); + void report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions); private: void send_parallel_old_event() const; @@ -209,7 +215,7 @@ G1NewTracer() : YoungGCTracer(G1New) {} void report_yc_type(G1YCType type); - void report_gc_end_impl(jlong timestamp, TimePartitions* time_partitions); + void report_gc_end_impl(const Ticks& timestamp, TimePartitions* time_partitions); void report_evacuation_info(EvacuationInfo* info); void report_evacuation_failed(EvacuationFailedInfo& ef_info); diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/gc_implementation/shared/gcTraceSend.cpp --- a/src/share/vm/gc_implementation/shared/gcTraceSend.cpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/gc_implementation/shared/gcTraceSend.cpp Thu Dec 05 16:37:29 2013 +0400 @@ -55,12 +55,11 @@ } void GCTracer::send_reference_stats_event(ReferenceType type, size_t count) const { - EventGCReferenceStatistics e(UNTIMED); + EventGCReferenceStatistics e; if (e.should_commit()) { e.set_gcId(_shared_gc_info.id()); e.set_type((u1)type); e.set_count(count); - e.set_endtime(os::elapsed_counter()); e.commit(); } } @@ -107,22 +106,20 @@ } void YoungGCTracer::send_promotion_failed_event(const PromotionFailedInfo& pf_info) const { - EventPromotionFailed e(UNTIMED); + EventPromotionFailed e; if (e.should_commit()) { e.set_gcId(_shared_gc_info.id()); e.set_data(to_trace_struct(pf_info)); e.set_thread(pf_info.thread()->thread_id()); - e.set_endtime(os::elapsed_counter()); e.commit(); } } // Common to CMS and G1 void OldGCTracer::send_concurrent_mode_failure_event() { - EventConcurrentModeFailure e(UNTIMED); + EventConcurrentModeFailure e; if (e.should_commit()) { e.set_gcId(_shared_gc_info.id()); - e.set_endtime(os::elapsed_counter()); e.commit(); } } @@ -140,7 +137,7 @@ } void G1NewTracer::send_evacuation_info_event(EvacuationInfo* info) { - EventEvacuationInfo e(UNTIMED); + EventEvacuationInfo e; if (e.should_commit()) { e.set_gcId(_shared_gc_info.id()); e.set_cSetRegions(info->collectionset_regions()); @@ -151,17 +148,15 @@ e.set_allocRegionsUsedAfter(info->alloc_regions_used_before() + info->bytes_copied()); e.set_bytesCopied(info->bytes_copied()); e.set_regionsFreed(info->regions_freed()); - e.set_endtime(os::elapsed_counter()); e.commit(); } } void G1NewTracer::send_evacuation_failed_event(const EvacuationFailedInfo& ef_info) const { - EventEvacuationFailed e(UNTIMED); + EventEvacuationFailed e; if (e.should_commit()) { e.set_gcId(_shared_gc_info.id()); e.set_data(to_trace_struct(ef_info)); - e.set_endtime(os::elapsed_counter()); e.commit(); } } @@ -195,13 +190,12 @@ void visit(const GCHeapSummary* heap_summary) const { const VirtualSpaceSummary& heap_space = heap_summary->heap(); - EventGCHeapSummary e(UNTIMED); + EventGCHeapSummary e; if (e.should_commit()) { e.set_gcId(_id); e.set_when((u1)_when); e.set_heapSpace(to_trace_struct(heap_space)); e.set_heapUsed(heap_summary->used()); - e.set_endtime(os::elapsed_counter()); e.commit(); } } @@ -216,7 +210,7 @@ const SpaceSummary& from_space = ps_heap_summary->from(); const SpaceSummary& to_space = ps_heap_summary->to(); - EventPSHeapSummary e(UNTIMED); + EventPSHeapSummary e; if (e.should_commit()) { e.set_gcId(_id); e.set_when((u1)_when); @@ -227,7 +221,6 @@ e.set_edenSpace(to_trace_struct(ps_heap_summary->eden())); e.set_fromSpace(to_trace_struct(ps_heap_summary->from())); e.set_toSpace(to_trace_struct(ps_heap_summary->to())); - e.set_endtime(os::elapsed_counter()); e.commit(); } } @@ -249,14 +242,13 @@ } void GCTracer::send_meta_space_summary_event(GCWhen::Type when, const MetaspaceSummary& meta_space_summary) const { - EventMetaspaceSummary e(UNTIMED); + EventMetaspaceSummary e; if (e.should_commit()) { e.set_gcId(_shared_gc_info.id()); e.set_when((u1) when); e.set_metaspace(to_trace_struct(meta_space_summary.meta_space())); e.set_dataSpace(to_trace_struct(meta_space_summary.data_space())); e.set_classSpace(to_trace_struct(meta_space_summary.class_space())); - e.set_endtime(os::elapsed_counter()); e.commit(); } } diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/gc_implementation/shared/gcTraceTime.cpp --- a/src/share/vm/gc_implementation/shared/gcTraceTime.cpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/gc_implementation/shared/gcTraceTime.cpp Thu Dec 05 16:37:29 2013 +0400 @@ -31,12 +31,13 @@ #include "runtime/thread.inline.hpp" #include "runtime/timer.hpp" #include "utilities/ostream.hpp" +#include "utilities/ticks.inline.hpp" GCTraceTime::GCTraceTime(const char* title, bool doit, bool print_cr, GCTimer* timer) : - _title(title), _doit(doit), _print_cr(print_cr), _timer(timer) { + _title(title), _doit(doit), _print_cr(print_cr), _timer(timer), _start_counter() { if (_doit || _timer != NULL) { - _start_counter = os::elapsed_counter(); + _start_counter.stamp(); } if (_timer != NULL) { @@ -57,10 +58,10 @@ } GCTraceTime::~GCTraceTime() { - jlong stop_counter = 0; + Ticks stop_counter; if (_doit || _timer != NULL) { - stop_counter = os::elapsed_counter(); + stop_counter.stamp(); } if (_timer != NULL) { @@ -68,11 +69,12 @@ } if (_doit) { - double seconds = TimeHelper::counter_to_seconds(stop_counter - _start_counter); + const Tickspan duration = stop_counter - _start_counter; + double duration_in_seconds = TicksToTimeHelper::seconds(duration); if (_print_cr) { - gclog_or_tty->print_cr(", %3.7f secs]", seconds); + gclog_or_tty->print_cr(", %3.7f secs]", duration_in_seconds); } else { - gclog_or_tty->print(", %3.7f secs]", seconds); + gclog_or_tty->print(", %3.7f secs]", duration_in_seconds); } gclog_or_tty->flush(); } diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/gc_implementation/shared/gcTraceTime.hpp --- a/src/share/vm/gc_implementation/shared/gcTraceTime.hpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/gc_implementation/shared/gcTraceTime.hpp Thu Dec 05 16:37:29 2013 +0400 @@ -26,6 +26,7 @@ #define SHARE_VM_GC_IMPLEMENTATION_SHARED_GCTRACETIME_HPP #include "prims/jni_md.h" +#include "utilities/ticks.hpp" class GCTimer; @@ -34,7 +35,7 @@ bool _doit; bool _print_cr; GCTimer* _timer; - jlong _start_counter; + Ticks _start_counter; public: GCTraceTime(const char* title, bool doit, bool print_cr, GCTimer* timer); diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/gc_implementation/shared/objectCountEventSender.cpp --- a/src/share/vm/gc_implementation/shared/objectCountEventSender.cpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/gc_implementation/shared/objectCountEventSender.cpp Thu Dec 05 16:37:29 2013 +0400 @@ -28,10 +28,11 @@ #include "memory/heapInspection.hpp" #include "trace/tracing.hpp" #include "utilities/globalDefinitions.hpp" +#include "utilities/ticks.hpp" #if INCLUDE_SERVICES -void ObjectCountEventSender::send(const KlassInfoEntry* entry, GCId gc_id, jlong timestamp) { +void ObjectCountEventSender::send(const KlassInfoEntry* entry, GCId gc_id, const Ticks& timestamp) { #if INCLUDE_TRACE assert(Tracing::is_event_enabled(EventObjectCountAfterGC::eventId), "Only call this method if the event is enabled"); diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/gc_implementation/shared/objectCountEventSender.hpp --- a/src/share/vm/gc_implementation/shared/objectCountEventSender.hpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/gc_implementation/shared/objectCountEventSender.hpp Thu Dec 05 16:37:29 2013 +0400 @@ -32,10 +32,11 @@ #if INCLUDE_SERVICES class KlassInfoEntry; +class Ticks; class ObjectCountEventSender : public AllStatic { public: - static void send(const KlassInfoEntry* entry, GCId gc_id, jlong timestamp); + static void send(const KlassInfoEntry* entry, GCId gc_id, const Ticks& timestamp); static bool should_send_event(); }; diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/interpreter/linkResolver.cpp --- a/src/share/vm/interpreter/linkResolver.cpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/interpreter/linkResolver.cpp Thu Dec 05 16:37:29 2013 +0400 @@ -915,6 +915,25 @@ return; } + // check if invokespecial's interface method reference is in an indirect superinterface + if (!current_klass.is_null() && resolved_klass->is_interface()) { + Klass *klass_to_check = !InstanceKlass::cast(current_klass())->is_anonymous() ? + current_klass() : + InstanceKlass::cast(current_klass())->host_klass(); + + if (!InstanceKlass::cast(klass_to_check)->is_same_or_direct_interface(resolved_klass())) { + ResourceMark rm(THREAD); + char buf[200]; + jio_snprintf(buf, sizeof(buf), + "Interface method reference: %s, is in an indirect superinterface of %s", + Method::name_and_sig_as_C_string(resolved_klass(), + resolved_method->name(), + resolved_method->signature()), + current_klass->external_name()); + THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); + } + } + // check if not static if (resolved_method->is_static()) { ResourceMark rm(THREAD); diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/memory/defNewGeneration.cpp --- a/src/share/vm/memory/defNewGeneration.cpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/memory/defNewGeneration.cpp Thu Dec 05 16:37:29 2013 +0400 @@ -562,7 +562,7 @@ GenCollectedHeap* gch = GenCollectedHeap::heap(); - _gc_timer->register_gc_start(os::elapsed_counter()); + _gc_timer->register_gc_start(); DefNewTracer gc_tracer; gc_tracer.report_gc_start(gch->gc_cause(), _gc_timer->gc_start()); @@ -709,7 +709,7 @@ gch->trace_heap_after_gc(&gc_tracer); gc_tracer.report_tenuring_threshold(tenuring_threshold()); - _gc_timer->register_gc_end(os::elapsed_counter()); + _gc_timer->register_gc_end(); gc_tracer.report_gc_end(_gc_timer->gc_end(), _gc_timer->time_partitions()); } diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/memory/generation.cpp --- a/src/share/vm/memory/generation.cpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/memory/generation.cpp Thu Dec 05 16:37:29 2013 +0400 @@ -635,16 +635,16 @@ x(ref_processor(), gch->reserved_region()); STWGCTimer* gc_timer = GenMarkSweep::gc_timer(); - gc_timer->register_gc_start(os::elapsed_counter()); + gc_timer->register_gc_start(); SerialOldTracer* gc_tracer = GenMarkSweep::gc_tracer(); gc_tracer->report_gc_start(gch->gc_cause(), gc_timer->gc_start()); GenMarkSweep::invoke_at_safepoint(_level, ref_processor(), clear_all_soft_refs); - gc_timer->register_gc_end(os::elapsed_counter()); + gc_timer->register_gc_end(); - gc_tracer->report_gc_end(os::elapsed_counter(), gc_timer->time_partitions()); + gc_tracer->report_gc_end(gc_timer->gc_end(), gc_timer->time_partitions()); SpecializationStats::print(); } diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/memory/universe.cpp --- a/src/share/vm/memory/universe.cpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/memory/universe.cpp Thu Dec 05 16:37:29 2013 +0400 @@ -120,6 +120,7 @@ oop Universe::_arithmetic_exception_instance = NULL; oop Universe::_virtual_machine_error_instance = NULL; oop Universe::_vm_exception = NULL; +Method* Universe::_throw_illegal_access_error = NULL; Array* Universe::_the_empty_int_array = NULL; Array* Universe::_the_empty_short_array = NULL; Array* Universe::_the_empty_klass_array = NULL; @@ -1096,6 +1097,18 @@ Universe::_finalizer_register_cache->init( SystemDictionary::Finalizer_klass(), m); + InstanceKlass::cast(SystemDictionary::misc_Unsafe_klass())->link_class(CHECK_false); + m = InstanceKlass::cast(SystemDictionary::misc_Unsafe_klass())->find_method( + vmSymbols::throwIllegalAccessError_name(), + vmSymbols::void_method_signature()); + if (m != NULL && !m->is_static()) { + // Note null is okay; this method is used in itables, and if it is null, + // then AbstractMethodError is thrown instead. + tty->print_cr("Unable to link/verify Unsafe.throwIllegalAccessError method"); + return false; // initialization failed (cannot throw exception yet) + } + Universe::_throw_illegal_access_error = m; + // Setup method for registering loaded classes in class loader vector InstanceKlass::cast(SystemDictionary::ClassLoader_klass())->link_class(CHECK_false); m = InstanceKlass::cast(SystemDictionary::ClassLoader_klass())->find_method(vmSymbols::addClass_name(), vmSymbols::class_void_signature()); diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/memory/universe.hpp --- a/src/share/vm/memory/universe.hpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/memory/universe.hpp Thu Dec 05 16:37:29 2013 +0400 @@ -149,6 +149,8 @@ static LatestMethodCache* _loader_addClass_cache; // method for registering loaded classes in class loader vector static LatestMethodCache* _pd_implies_cache; // method for checking protection domain attributes + static Method* _throw_illegal_access_error; + // preallocated error objects (no backtrace) static oop _out_of_memory_error_java_heap; static oop _out_of_memory_error_metaspace; @@ -305,6 +307,7 @@ static oop arithmetic_exception_instance() { return _arithmetic_exception_instance; } static oop virtual_machine_error_instance() { return _virtual_machine_error_instance; } static oop vm_exception() { return _vm_exception; } + static Method* throw_illegal_access_error() { return _throw_illegal_access_error; } static Array* the_empty_int_array() { return _the_empty_int_array; } static Array* the_empty_short_array() { return _the_empty_short_array; } diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/oops/instanceKlass.cpp --- a/src/share/vm/oops/instanceKlass.cpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/oops/instanceKlass.cpp Thu Dec 05 16:37:29 2013 +0400 @@ -1051,6 +1051,18 @@ return false; } +bool InstanceKlass::is_same_or_direct_interface(Klass *k) const { + // Verify direct super interface + if (this == k) return true; + assert(k->is_interface(), "should be an interface class"); + for (int i = 0; i < local_interfaces()->length(); i++) { + if (local_interfaces()->at(i) == k) { + return true; + } + } + return false; +} + objArrayOop InstanceKlass::allocate_objArray(int n, int length, TRAPS) { if (length < 0) THROW_0(vmSymbols::java_lang_NegativeArraySizeException()); if (length > arrayOopDesc::max_array_length(T_OBJECT)) { diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/oops/instanceKlass.hpp --- a/src/share/vm/oops/instanceKlass.hpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/oops/instanceKlass.hpp Thu Dec 05 16:37:29 2013 +0400 @@ -777,6 +777,7 @@ // subclass/subinterface checks bool implements_interface(Klass* k) const; + bool is_same_or_direct_interface(Klass* k) const; // Access to the implementor of an interface. Klass* implementor() const diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/oops/klassVtable.cpp --- a/src/share/vm/oops/klassVtable.cpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/oops/klassVtable.cpp Thu Dec 05 16:37:29 2013 +0400 @@ -1076,7 +1076,12 @@ LinkResolver::lookup_instance_method_in_klasses(target, _klass, m->name(), m->signature(), CHECK); } if (target == NULL || !target->is_public() || target->is_abstract()) { - // Entry do not resolve. Leave it empty + // Entry does not resolve. Leave it empty for AbstractMethodError. + if (!(target == NULL) && !target->is_public()) { + // Stuff an IllegalAccessError throwing method in there instead. + itableOffsetEntry::method_entry(_klass(), method_table_offset)[m->itable_index()]. + initialize(Universe::throw_illegal_access_error()); + } } else { // Entry did resolve, check loader constraints before initializing // if checkconstraints requested diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/opto/compile.hpp --- a/src/share/vm/opto/compile.hpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/opto/compile.hpp Thu Dec 05 16:37:29 2013 +0400 @@ -42,6 +42,7 @@ #include "runtime/deoptimization.hpp" #include "runtime/vmThread.hpp" #include "trace/tracing.hpp" +#include "utilities/ticks.hpp" class Block; class Bundle; @@ -597,20 +598,19 @@ bool has_method_handle_invokes() const { return _has_method_handle_invokes; } void set_has_method_handle_invokes(bool z) { _has_method_handle_invokes = z; } - jlong _latest_stage_start_counter; + Ticks _latest_stage_start_counter; void begin_method() { #ifndef PRODUCT if (_printer) _printer->begin_method(this); #endif - C->_latest_stage_start_counter = os::elapsed_counter(); + C->_latest_stage_start_counter.stamp(); } void print_method(CompilerPhaseType cpt, int level = 1) { - EventCompilerPhase event(UNTIMED); + EventCompilerPhase event; if (event.should_commit()) { event.set_starttime(C->_latest_stage_start_counter); - event.set_endtime(os::elapsed_counter()); event.set_phase((u1) cpt); event.set_compileID(C->_compile_id); event.set_phaseLevel(level); @@ -621,14 +621,13 @@ #ifndef PRODUCT if (_printer) _printer->print_method(this, CompilerPhaseTypeHelper::to_string(cpt), level); #endif - C->_latest_stage_start_counter = os::elapsed_counter(); + C->_latest_stage_start_counter.stamp(); } void end_method(int level = 1) { - EventCompilerPhase event(UNTIMED); + EventCompilerPhase event; if (event.should_commit()) { event.set_starttime(C->_latest_stage_start_counter); - event.set_endtime(os::elapsed_counter()); event.set_phase((u1) PHASE_END); event.set_compileID(C->_compile_id); event.set_phaseLevel(level); diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/runtime/sweeper.cpp --- a/src/share/vm/runtime/sweeper.cpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/runtime/sweeper.cpp Thu Dec 05 16:37:29 2013 +0400 @@ -38,6 +38,7 @@ #include "runtime/vm_operations.hpp" #include "trace/tracing.hpp" #include "utilities/events.hpp" +#include "utilities/ticks.inline.hpp" #include "utilities/xmlstream.hpp" #ifdef ASSERT @@ -144,10 +145,10 @@ // 3) zombie -> marked_for_reclamation int NMethodSweeper::_total_nof_methods_reclaimed = 0; // Accumulated nof methods flushed -jlong NMethodSweeper::_total_time_sweeping = 0; // Accumulated time sweeping -jlong NMethodSweeper::_total_time_this_sweep = 0; // Total time this sweep -jlong NMethodSweeper::_peak_sweep_time = 0; // Peak time for a full sweep -jlong NMethodSweeper::_peak_sweep_fraction_time = 0; // Peak time sweeping one fraction +Tickspan NMethodSweeper::_total_time_sweeping; // Accumulated time sweeping +Tickspan NMethodSweeper::_total_time_this_sweep; // Total time this sweep +Tickspan NMethodSweeper::_peak_sweep_time; // Peak time for a full sweep +Tickspan NMethodSweeper::_peak_sweep_fraction_time; // Peak time sweeping one fraction int NMethodSweeper::_hotness_counter_reset_val = 0; @@ -209,7 +210,7 @@ _sweep_fractions_left = NmethodSweepFraction; _current = CodeCache::first_nmethod(); _traversals += 1; - _total_time_this_sweep = 0; + _total_time_this_sweep = Tickspan(); if (PrintMethodFlushing) { tty->print_cr("### Sweep: stack traversal %d", _traversals); @@ -303,7 +304,7 @@ } void NMethodSweeper::sweep_code_cache() { - jlong sweep_start_counter = os::elapsed_counter(); + Ticks sweep_start_counter = Ticks::now(); _flushed_count = 0; _zombified_count = 0; @@ -367,8 +368,8 @@ assert(_sweep_fractions_left > 1 || _current == NULL, "must have scanned the whole cache"); - jlong sweep_end_counter = os::elapsed_counter(); - jlong sweep_time = sweep_end_counter - sweep_start_counter; + const Ticks sweep_end_counter = Ticks::now(); + const Tickspan sweep_time = sweep_end_counter - sweep_start_counter; _total_time_sweeping += sweep_time; _total_time_this_sweep += sweep_time; _peak_sweep_fraction_time = MAX2(sweep_time, _peak_sweep_fraction_time); @@ -389,7 +390,8 @@ #ifdef ASSERT if(PrintMethodFlushing) { - tty->print_cr("### sweeper: sweep time(%d): " INT64_FORMAT, _sweep_fractions_left, (jlong)sweep_time); + tty->print_cr("### sweeper: sweep time(%d): " + INT64_FORMAT, _sweep_fractions_left, (jlong)sweep_time.value()); } #endif diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/runtime/sweeper.hpp --- a/src/share/vm/runtime/sweeper.hpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/runtime/sweeper.hpp Thu Dec 05 16:37:29 2013 +0400 @@ -25,6 +25,7 @@ #ifndef SHARE_VM_RUNTIME_SWEEPER_HPP #define SHARE_VM_RUNTIME_SWEEPER_HPP +#include "utilities/ticks.hpp" // An NmethodSweeper is an incremental cleaner for: // - cleanup inline caches // - reclamation of nmethods @@ -71,10 +72,10 @@ // 3) zombie -> marked_for_reclamation // Stat counters static int _total_nof_methods_reclaimed; // Accumulated nof methods flushed - static jlong _total_time_sweeping; // Accumulated time sweeping - static jlong _total_time_this_sweep; // Total time this sweep - static jlong _peak_sweep_time; // Peak time for a full sweep - static jlong _peak_sweep_fraction_time; // Peak time sweeping one fraction + static Tickspan _total_time_sweeping; // Accumulated time sweeping + static Tickspan _total_time_this_sweep; // Total time this sweep + static Tickspan _peak_sweep_time; // Peak time for a full sweep + static Tickspan _peak_sweep_fraction_time; // Peak time sweeping one fraction static int process_nmethod(nmethod *nm); static void release_nmethod(nmethod* nm); @@ -87,9 +88,9 @@ public: static long traversal_count() { return _traversals; } static int total_nof_methods_reclaimed() { return _total_nof_methods_reclaimed; } - static jlong total_time_sweeping() { return _total_time_sweeping; } - static jlong peak_sweep_time() { return _peak_sweep_time; } - static jlong peak_sweep_fraction_time() { return _peak_sweep_fraction_time; } + static const Tickspan total_time_sweeping() { return _total_time_sweeping; } + static const Tickspan peak_sweep_time() { return _peak_sweep_time; } + static const Tickspan peak_sweep_fraction_time() { return _peak_sweep_fraction_time; } static void log_sweep(const char* msg, const char* format = NULL, ...); diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/trace/noTraceBackend.hpp --- a/src/share/vm/trace/noTraceBackend.hpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/trace/noTraceBackend.hpp Thu Dec 05 16:37:29 2013 +0400 @@ -25,9 +25,7 @@ #define SHARE_VM_TRACE_NOTRACEBACKEND_HPP #include "prims/jni.h" - -typedef jlong TracingTime; -typedef jlong RelativeTracingTime; +#include "trace/traceTime.hpp" class NoTraceBackend { public: @@ -44,5 +42,3 @@ typedef NoTraceBackend Tracing; #endif - - diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/trace/trace.xml --- a/src/share/vm/trace/trace.xml Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/trace/trace.xml Thu Dec 05 16:37:29 2013 +0400 @@ -176,8 +176,8 @@ - - + + class TraceEvent : public StackObj { - protected: - jlong _startTime; - jlong _endTime; - private: bool _started; #ifdef ASSERT @@ -54,6 +51,18 @@ bool _ignore_check; #endif + protected: + jlong _startTime; + jlong _endTime; + + void set_starttime(const TracingTime& time) { + _startTime = time; + } + + void set_endtime(const TracingTime& time) { + _endTime = time; + } + public: TraceEvent(EventStartTime timing=TIMED) : _startTime(0), @@ -100,12 +109,12 @@ set_commited(); } - void set_starttime(jlong time) { - _startTime = time; + void set_starttime(const Ticks& time) { + _startTime = time.value(); } - void set_endtime(jlong time) { - _endTime = time; + void set_endtime(const Ticks& time) { + _endTime = time.value(); } TraceEventId id() const { diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/trace/traceEventClasses.xsl --- a/src/share/vm/trace/traceEventClasses.xsl Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/trace/traceEventClasses.xsl Thu Dec 05 16:37:29 2013 +0400 @@ -40,6 +40,7 @@ #include "tracefiles/traceTypes.hpp" #include "trace/traceEvent.hpp" #include "utilities/macros.hpp" +#include "utilities/ticks.hpp" #if INCLUDE_TRACE @@ -55,8 +56,8 @@ class TraceEvent { public: TraceEvent() {} - void set_starttime(jlong time) const {} - void set_endtime(jlong time) const {} + void set_starttime(const Ticks& time) {} + void set_endtime(const Ticks& time) {} bool should_commit() const { return false; } void commit() const {} }; @@ -170,23 +171,23 @@ - #if INCLUDE_TRACE - + #else - + #endif - + #if INCLUDE_TRACE - + #else - + #endif + @@ -226,7 +227,17 @@ - + + + + + + + + + + + ts.print(", "); diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/trace/traceTime.hpp --- a/src/share/vm/trace/traceTime.hpp Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/trace/traceTime.hpp Thu Dec 05 16:37:29 2013 +0400 @@ -28,6 +28,5 @@ #include "prims/jni.h" typedef jlong TracingTime; -typedef jlong RelativeTracingTime; -#endif +#endif // SHARE_VM_TRACE_TRACETIME_HPP diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/trace/traceTypes.xsl --- a/src/share/vm/trace/traceTypes.xsl Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/trace/traceTypes.xsl Thu Dec 05 16:37:29 2013 +0400 @@ -32,9 +32,11 @@ #ifndef TRACEFILES_JFRTYPES_HPP #define TRACEFILES_JFRTYPES_HPP +#include "oops/symbol.hpp" #include "trace/traceDataTypes.hpp" #include "utilities/globalDefinitions.hpp" -#include "oops/symbol.hpp" +#include "utilities/ticks.hpp" + enum JVMContentType { _not_a_content_type = (JVM_CONTENT_TYPES_START - 1), diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/trace/tracetypes.xml --- a/src/share/vm/trace/tracetypes.xml Tue Dec 03 14:13:06 2013 +0400 +++ b/src/share/vm/trace/tracetypes.xml Thu Dec 05 16:37:29 2013 +0400 @@ -249,13 +249,13 @@ - + + type="Ticks" sizeop="sizeof(s8)"/> - - + + = start, "negative time!"); + + _span_ticks = end.value() - start.value(); +} + +template +static ReturnType time_conversion(const Tickspan& span, TicksToTimeHelper::Unit unit) { + assert(TicksToTimeHelper::SECONDS == unit || + TicksToTimeHelper::MILLISECONDS == unit, "invalid unit!"); + + ReturnType frequency_per_unit = (ReturnType)os::elapsed_frequency() / (ReturnType)unit; + + return (ReturnType) ((ReturnType)span.value() / frequency_per_unit); +} + +double TicksToTimeHelper::seconds(const Tickspan& span) { + return time_conversion(span, SECONDS); +} + +jlong TicksToTimeHelper::milliseconds(const Tickspan& span) { + return time_conversion(span, MILLISECONDS); +} diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/utilities/ticks.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/utilities/ticks.hpp Thu Dec 05 16:37:29 2013 +0400 @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2013, 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. + * + */ + +#ifndef SHARE_VM_UTILITIES_TICKS_HPP +#define SHARE_VM_UTILITIES_TICKS_HPP + +#include "memory/allocation.hpp" +#include "utilities/globalDefinitions.hpp" + +class Ticks; + +class Tickspan VALUE_OBJ_CLASS_SPEC { + friend class Ticks; + friend Tickspan operator-(const Ticks& end, const Ticks& start); + + private: + jlong _span_ticks; + + Tickspan(const Ticks& end, const Ticks& start); + + public: + Tickspan() : _span_ticks(0) {} + + Tickspan& operator+=(const Tickspan& rhs) { + _span_ticks += rhs._span_ticks; + return *this; + } + + jlong value() const { + return _span_ticks; + } + +}; + +class Ticks VALUE_OBJ_CLASS_SPEC { + private: + jlong _stamp_ticks; + + public: + Ticks() : _stamp_ticks(0) { + assert((_stamp_ticks = invalid_time_stamp) == invalid_time_stamp, + "initial unstamped time value assignment"); + } + + Ticks& operator+=(const Tickspan& span) { + _stamp_ticks += span.value(); + return *this; + } + + Ticks& operator-=(const Tickspan& span) { + _stamp_ticks -= span.value(); + return *this; + } + + void stamp(); + + jlong value() const { + return _stamp_ticks; + } + + static const Ticks now(); + +#ifdef ASSERT + static const jlong invalid_time_stamp; +#endif + +#ifndef PRODUCT + // only for internal use by GC VM tests + friend class TimePartitionPhasesIteratorTest; + friend class GCTimerTest; + + private: + // implicit type conversion + Ticks(int ticks) : _stamp_ticks(ticks) {} + +#endif // !PRODUCT + +}; + +class TicksToTimeHelper : public AllStatic { + public: + enum Unit { + SECONDS = 1, + MILLISECONDS = 1000 + }; + static double seconds(const Tickspan& span); + static jlong milliseconds(const Tickspan& span); +}; + +#endif // SHARE_VM_UTILITIES_TICKS_HPP diff -r 0611ce949aaa -r e254e5940c19 src/share/vm/utilities/ticks.inline.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/utilities/ticks.inline.hpp Thu Dec 05 16:37:29 2013 +0400 @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013, 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. + * + */ + +#ifndef SHARE_VM_UTILITIES_TICKS_INLINE_HPP +#define SHARE_VM_UTILITIES_TICKS_INLINE_HPP + +#include "utilities/ticks.hpp" + +inline Tickspan operator+(Tickspan lhs, const Tickspan& rhs) { + lhs += rhs; + return lhs; +} + +inline bool operator==(const Tickspan& lhs, const Tickspan& rhs) { + return lhs.value() == rhs.value(); +} + +inline bool operator!=(const Tickspan& lhs, const Tickspan& rhs) { + return !operator==(lhs,rhs); +} + +inline bool operator<(const Tickspan& lhs, const Tickspan& rhs) { + return lhs.value() < rhs.value(); +} + +inline bool operator>(const Tickspan& lhs, const Tickspan& rhs) { + return operator<(rhs,lhs); +} + +inline bool operator<=(const Tickspan& lhs, const Tickspan& rhs) { + return !operator>(lhs,rhs); +} + +inline bool operator>=(const Tickspan& lhs, const Tickspan& rhs) { + return !operator<(lhs,rhs); +} + +inline Ticks operator+(Ticks lhs, const Tickspan& span) { + lhs += span; + return lhs; +} + +inline Ticks operator-(Ticks lhs, const Tickspan& span) { + lhs -= span; + return lhs; +} + +inline Tickspan operator-(const Ticks& end, const Ticks& start) { + return Tickspan(end, start); +} + +inline bool operator==(const Ticks& lhs, const Ticks& rhs) { + return lhs.value() == rhs.value(); +} + +inline bool operator!=(const Ticks& lhs, const Ticks& rhs) { + return !operator==(lhs,rhs); +} + +inline bool operator<(const Ticks& lhs, const Ticks& rhs) { + return lhs.value() < rhs.value(); +} + +inline bool operator>(const Ticks& lhs, const Ticks& rhs) { + return operator<(rhs,lhs); +} + +inline bool operator<=(const Ticks& lhs, const Ticks& rhs) { + return !operator>(lhs,rhs); +} + +inline bool operator>=(const Ticks& lhs, const Ticks& rhs) { + return !operator<(lhs,rhs); +} + +#endif // SHARE_VM_UTILITIES_TICKS_INLINE_HPP diff -r 0611ce949aaa -r e254e5940c19 test/compiler/jsr292/methodHandleExceptions/ByteClassLoader.java --- a/test/compiler/jsr292/methodHandleExceptions/ByteClassLoader.java Tue Dec 03 14:13:06 2013 +0400 +++ b/test/compiler/jsr292/methodHandleExceptions/ByteClassLoader.java Thu Dec 05 16:37:29 2013 +0400 @@ -1,3 +1,12 @@ +import java.io.BufferedOutputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.jar.JarEntry; +import java.util.jar.JarOutputStream; + /* * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -23,12 +32,63 @@ */ /** - * A minimal classloader for loading bytecodes that could not result from - * properly compiled Java. + * A ByteClassLoader is used to define classes from collections of bytes, as + * well as loading classes in the usual way. It includes options to write the + * classes to files in a jar, or to read the classes from jars in a later or + * debugging run. + * + * If Boolean property byteclassloader.verbose is true, be chatty about jar + * file operations. * - * @author dr2chase */ -public class ByteClassLoader extends ClassLoader { +public class ByteClassLoader extends URLClassLoader { + + final static boolean verbose + = Boolean.getBoolean("byteclassloader.verbose"); + + final boolean read; + final JarOutputStream jos; + final String jar_name; + + /** + * Make a new ByteClassLoader. + * + * @param jar_name Basename of jar file to be read/written by this classloader. + * @param read If true, read classes from jar file instead of from parameter. + * @param write If true, write classes to jar files for offline study/use. + * + * @throws FileNotFoundException + * @throws IOException + */ + public ByteClassLoader(String jar_name, boolean read, boolean write) + throws FileNotFoundException, IOException { + super(read + ? new URL[]{new URL("file:" + jar_name + ".jar")} + : new URL[0]); + this.read = read; + this.jar_name = jar_name; + this.jos = write + ? new JarOutputStream( + new BufferedOutputStream( + new FileOutputStream(jar_name + ".jar"))) : null; + if (read && write) { + throw new Error("At most one of read and write may be true."); + } + } + + private static void writeJarredFile(JarOutputStream jos, String file, String suffix, byte[] bytes) { + String fileName = file.replace(".", "/") + "." + suffix; + JarEntry ze = new JarEntry(fileName); + try { + ze.setSize(bytes.length); + jos.putNextEntry(ze); + jos.write(bytes); + jos.closeEntry(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + /** * (pre)load class name using classData for the definition. * @@ -36,9 +96,36 @@ * @param classData * @return */ - public Class loadBytes(String name, byte[] classData) { - Class clazz = defineClass(name, classData, 0, classData.length); - resolveClass(clazz); - return clazz; + public Class loadBytes(String name, byte[] classData) throws ClassNotFoundException { + if (jos != null) { + if (verbose) { + System.out.println("ByteClassLoader: writing " + name); + } + writeJarredFile(jos, name, "class", classData); + } + + Class clazz = null; + if (read) { + if (verbose) { + System.out.println("ByteClassLoader: reading " + name + " from " + jar_name); + } + clazz = loadClass(name); + } else { + clazz = defineClass(name, classData, 0, classData.length); + resolveClass(clazz); + } + return clazz; + } + + public void close() { + if (jos != null) { + try { + if (verbose) { + System.out.println("ByteClassLoader: closing " + jar_name); + } + jos.close(); + } catch (IOException ex) { + } + } } } diff -r 0611ce949aaa -r e254e5940c19 test/compiler/jsr292/methodHandleExceptions/C.java --- a/test/compiler/jsr292/methodHandleExceptions/C.java Tue Dec 03 14:13:06 2013 +0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2013, 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 class -- implements I, which provides default for m, but this class - * declares it abstract which (should) hide the interface default, and throw - * an abstract method error if it is called (calling it requires bytecode hacking - * or inconsistent compilation). - */ -public abstract class C implements I { - public abstract int m(); -} diff -r 0611ce949aaa -r e254e5940c19 test/compiler/jsr292/methodHandleExceptions/I.java --- a/test/compiler/jsr292/methodHandleExceptions/I.java Tue Dec 03 14:13:06 2013 +0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2013, 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. - * - */ - -public interface I { - default public int m() { return 1; } -} diff -r 0611ce949aaa -r e254e5940c19 test/compiler/jsr292/methodHandleExceptions/TestAMEnotNPE.java --- a/test/compiler/jsr292/methodHandleExceptions/TestAMEnotNPE.java Tue Dec 03 14:13:06 2013 +0400 +++ b/test/compiler/jsr292/methodHandleExceptions/TestAMEnotNPE.java Thu Dec 05 16:37:29 2013 +0400 @@ -21,50 +21,127 @@ * questions. * */ - import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; import jdk.internal.org.objectweb.asm.ClassWriter; import jdk.internal.org.objectweb.asm.Handle; import jdk.internal.org.objectweb.asm.MethodVisitor; import jdk.internal.org.objectweb.asm.Opcodes; +import p.Dok; /** - * @test - * @bug 8025260 - * @summary Ensure that AbstractMethodError is thrown, not NullPointerException, through MethodHandles::jump_from_method_handle code path + * @test @bug 8025260 8016839 + * @summary Ensure that AbstractMethodError and IllegalAccessError are thrown appropriately, not NullPointerException + * + * @compile -XDignore.symbol.file TestAMEnotNPE.java ByteClassLoader.java p/C.java p/Dok.java p/E.java p/F.java p/I.java p/Tdirect.java p/Treflect.java * - * @compile -XDignore.symbol.file ByteClassLoader.java I.java C.java TestAMEnotNPE.java * @run main/othervm TestAMEnotNPE + * @run main/othervm -Xint TestAMEnotNPE + * @run main/othervm -Xcomp TestAMEnotNPE */ - public class TestAMEnotNPE implements Opcodes { + static boolean writeJarFiles = false; + static boolean readJarFiles = false; + /** - * The bytes for D, a NOT abstract class extending abstract class C - * without supplying an implementation for abstract method m. - * There is a default method in the interface I, but it should lose to - * the abstract class. + * Optional command line parameter (any case-insensitive prefix of) + * "writejarfiles" or "readjarfiles". + * + * "Writejarfiles" creates a jar file for each different set of tested classes. + * "Readjarfiles" causes the classloader to use the copies of the classes + * found in the corresponding jar files. + * + * Jarfilenames look something like pD_ext_pF (p.D extends p.F) + * and qD_m_pp_imp_pI (q.D with package-private m implements p.I) + * + */ + public static void main(String args[]) throws Throwable { + ArrayList lt = new ArrayList(); + + if (args.length > 0) { + String a0 = args[0].toLowerCase(); + if (a0.length() > 0) { + writeJarFiles = ("writejarfiles").startsWith(a0); + readJarFiles = ("readjarfiles").startsWith(a0); + } + if (!(writeJarFiles || readJarFiles)) { + throw new Error("Command line parameter (if any) should be prefix of writeJarFiles or readJarFiles"); + } + } + + try { + System.out.println("TRYING p.D.m PRIVATE interface-invoked as p.I.m, p.D extends p.F, p.F.m FINAL"); + tryAndCheckThrown(lt, bytesForDprivateSubWhat("p/F"), + "p.D extends p.F (p.F implements p.I, FINAL public m), private m", + IllegalAccessError.class, "pD_ext_pF"); + // We'll take either a VerifyError (pre 2013-11-30) + // or an IllegalAccessError (post 2013-11-22) + } catch (VerifyError ve) { + System.out.println("Saw expected VerifyError " + ve); + } + System.out.println(); - class D extends C { - D() { super(); } - // does not define m - } + System.out.println("TRYING p.D.m PRIVATE interface-invoked as p.I.m, p.D extends p.E"); + tryAndCheckThrown(lt, bytesForDprivateSubWhat("p/E"), + "p.D extends p.E (p.E implements p.I, public m), private m", + IllegalAccessError.class, "pD_ext_pE"); + + System.out.println("TRYING p.D.m ABSTRACT interface-invoked as p.I.m"); + tryAndCheckThrown(lt, bytesForD(), + "D extends abstract C, no m", + AbstractMethodError.class, "pD_ext_pC"); + + System.out.println("TRYING q.D.m PACKAGE interface-invoked as p.I.m"); + tryAndCheckThrown(lt, "q.D", bytesForDsomeAccess("q/D", 0), + "q.D implements p.I, protected m", IllegalAccessError.class, + "qD_m_pp_imp_pI"); + + // Note jar file name is used in the plural-arg case. + System.out.println("TRYING p.D.m PRIVATE interface-invoked as p.I.m"); + tryAndCheckThrown(lt, bytesForDsomeAccess("p/D", ACC_PRIVATE), + "p.D implements p.I, private m", + IllegalAccessError.class, "pD_m_pri_imp_pI"); + // Plural-arg test. + System.out.println("TRYING p.D.m PRIVATE MANY ARG interface-invoked as p.I.m"); + tryAndCheckThrownMany(lt, bytesForDsomeAccess("p/D", ACC_PRIVATE), + "p.D implements p.I, private m", IllegalAccessError.class); + + if (lt.size() > 0) { + System.out.flush(); + Thread.sleep(250); // This de-interleaves output and error in Netbeans, sigh. + for (Throwable th : lt) + System.err.println(th); + throw new Error("Test failed, there were " + lt.size() + " failures listed above"); + } else { + System.out.println("ALL PASS, HOORAY!"); + } + } + + /** + * The bytes for D, a NOT abstract class extending abstract class C without + * supplying an implementation for abstract method m. There is a default + * method in the interface I, but it should lose to the abstract class. + * * @return * @throws Exception */ public static byte[] bytesForD() throws Exception { - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS); + ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES + | ClassWriter.COMPUTE_MAXS); MethodVisitor mv; - cw.visit(V1_8, ACC_PUBLIC + ACC_SUPER, "D", null, "C", null); + cw.visit(V1_8, ACC_PUBLIC + ACC_SUPER, "p/D", null, "p/C", null); { mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "C", "", "()V"); + mv.visitMethodInsn(INVOKESPECIAL, "p/C", "", "()V"); mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); @@ -74,70 +151,346 @@ return cw.toByteArray(); } + /** + * The bytes for D, implements I, does not extend C, declares m()I with + * access method_acc. + * + * @param d_name Name of class defined + * @param method_acc Accessibility of that class's method m. + * @return + * @throws Exception + */ + public static byte[] bytesForDsomeAccess(String d_name, int method_acc) throws Exception { + return bytesForSomeDsubSomethingSomeAccess(d_name, "java/lang/Object", method_acc); + } + + /** + * The bytes for D implements I, extends some class, declares m()I as + * private. + * + * Invokeinterface of I.m applied to this D should throw IllegalAccessError + * + * @param sub_what The name of the class that D will extend. + * @return + * @throws Exception + */ + public static byte[] bytesForDprivateSubWhat(String sub_what) throws Exception { + return bytesForSomeDsubSomethingSomeAccess("p/D", sub_what, ACC_PRIVATE); + } /** - * The bytecodes for an invokeExact of a particular methodHandle, I.m, invoked on a D + * Returns the bytes for a class with name d_name (presumably "D" in some + * package), extending some class with name sub_what, implementing p.I, + * and defining two methods m() and m(11args) with access method_acc. + * + * @param d_name Name of class that is defined + * @param sub_what Name of class that it extends + * @param method_acc Accessibility of method(s) m in defined class. + * @return + * @throws Exception + */ + public static byte[] bytesForSomeDsubSomethingSomeAccess + (String d_name, String sub_what, int method_acc) + throws Exception { + + ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES + | ClassWriter.COMPUTE_MAXS); + MethodVisitor mv; + String[] interfaces = {"p/I"}; - class T { - T() { super(); } // boring constructor - int test() { - MethodHandle mh = `I.m():int`; - D d = new D(); - return mh.invokeExact(d); // Should explode here, AbstractMethodError - } + cw.visit(V1_8, ACC_PUBLIC + ACC_SUPER, d_name, null, sub_what, interfaces); + { + mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); + mv.visitCode(); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESPECIAL, sub_what, "", "()V"); + mv.visitInsn(RETURN); + mv.visitMaxs(0, 0); + mv.visitEnd(); + } + // int m() {return 3;} + { + mv = cw.visitMethod(method_acc, "m", "()I", null, null); + mv.visitCode(); + mv.visitLdcInsn(new Integer(3)); + mv.visitInsn(IRETURN); + mv.visitMaxs(0, 0); + mv.visitEnd(); } + // int m(11args) {return 3;} + { + mv = cw.visitMethod(method_acc, "m", "(BCSIJ" + + "Ljava/lang/Object;" + + "Ljava/lang/Object;" + + "Ljava/lang/Object;" + + "Ljava/lang/Object;" + + "Ljava/lang/Object;" + + "Ljava/lang/Object;" + + ")I", null, null); + mv.visitCode(); + mv.visitLdcInsn(new Integer(3)); + mv.visitInsn(IRETURN); + mv.visitMaxs(0, 0); + mv.visitEnd(); + } + cw.visitEnd(); + return cw.toByteArray(); + } + /** + * The bytecodes for a class p/T defining a methods test() and test(11args) + * that contain an invokeExact of a particular methodHandle, I.m. + * + * Test will be passed values that may imperfectly implement I, + * and thus may in turn throw exceptions. + * * @return * @throws Exception */ public static byte[] bytesForT() throws Exception { - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS); + ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES + | ClassWriter.COMPUTE_MAXS); MethodVisitor mv; - cw.visit(V1_8, ACC_PUBLIC + ACC_SUPER, "T", null, "java/lang/Object", null); + cw.visit(V1_8, ACC_PUBLIC + ACC_SUPER, "p/T", null, "java/lang/Object", null); { mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V"); mv.visitInsn(RETURN); - mv.visitMaxs(0,0); + mv.visitMaxs(0, 0); + mv.visitEnd(); + } + // static int test(I) + { + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "test", "(Lp/I;)I", null, null); + mv.visitCode(); + mv.visitLdcInsn(new Handle(Opcodes.H_INVOKEINTERFACE, "p/I", "m", "()I")); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle", + "invokeExact", "(Lp/I;)I"); + mv.visitInsn(IRETURN); + mv.visitMaxs(0, 0); mv.visitEnd(); } + // static int test(I,11args) { - mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "test", "()I", null, null); + mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "test", "(Lp/I;BCSIJLjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)I", null, null); mv.visitCode(); - mv.visitLdcInsn(new Handle(Opcodes.H_INVOKEINTERFACE, "I", "m", "()I")); - mv.visitTypeInsn(NEW, "D"); - mv.visitInsn(DUP); - mv.visitMethodInsn(INVOKESPECIAL, "D", "", "()V"); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle", "invokeExact", "(LI;)I"); + mv.visitLdcInsn(new Handle(Opcodes.H_INVOKEINTERFACE, "p/I", "m", "(BCSIJLjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)I")); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ILOAD, 1); + mv.visitVarInsn(ILOAD, 2); + mv.visitVarInsn(ILOAD, 3); + mv.visitVarInsn(ILOAD, 4); + mv.visitVarInsn(LLOAD, 5); + mv.visitVarInsn(ALOAD, 7); + mv.visitVarInsn(ALOAD, 8); + mv.visitVarInsn(ALOAD, 9); + mv.visitVarInsn(ALOAD, 10); + mv.visitVarInsn(ALOAD, 11); + mv.visitVarInsn(ALOAD, 12); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle", + "invokeExact", "(Lp/I;BCSIJLjava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)I"); mv.visitInsn(IRETURN); - mv.visitMaxs(0,0); + mv.visitMaxs(0, 0); mv.visitEnd(); } cw.visitEnd(); return cw.toByteArray(); } - public static void main(String args[] ) throws Throwable { - ByteClassLoader bcl = new ByteClassLoader(); - Class d = bcl.loadBytes("D", bytesForD()); - Class t = bcl.loadBytes("T", bytesForT()); + private static void tryAndCheckThrown( + List lt, byte[] dBytes, String what, Class expected, String jar_name) + throws Throwable { + tryAndCheckThrown(lt, "p.D", dBytes, what, expected, jar_name); + } + + private static void tryAndCheckThrown(List lt, String d_name, byte[] dBytes, String what, Class expected, String jar_name) + throws Throwable { + + System.out.println("Methodhandle invokeExact I.m() for instance of " + what); + ByteClassLoader bcl1 = new ByteClassLoader(jar_name, readJarFiles, writeJarFiles); try { - Object result = t.getMethod("test").invoke(null); - System.out.println("Expected AbstractMethodError wrapped in InvocationTargetException, saw no exception"); - throw new Error("Missing expected exception"); + Class d1 = bcl1.loadBytes(d_name, dBytes); + Class t1 = bcl1.loadBytes("p.T", bytesForT()); + invokeTest(t1, d1, expected, lt); + } finally { + // Not necessary for others -- all class files are written in this call. + // (unless the VM crashes first). + bcl1.close(); + } + + System.out.println("Reflection invoke I.m() for instance of " + what); + ByteClassLoader bcl3 = new ByteClassLoader(jar_name, readJarFiles, false); + Class d3 = bcl3.loadBytes(d_name, dBytes); + Class t3 = bcl3.loadClass("p.Treflect"); + invokeTest(t3, d3, expected, lt); + + System.out.println("Bytecode invokeInterface I.m() for instance of " + what); + ByteClassLoader bcl2 = new ByteClassLoader(jar_name, readJarFiles, false); + Class d2 = bcl2.loadBytes(d_name, dBytes); + Class t2 = bcl2.loadClass("p.Tdirect"); + badGoodBadGood(t2, d2, expected, lt); + } + + private static void invokeTest(Class t, Class d, Class expected, List lt) + throws Throwable { + try { + Method m = t.getMethod("test", p.I.class); + Object o = d.newInstance(); + Object result = m.invoke(null, o); + if (expected != null) { + System.out.println("FAIL, Expected " + expected.getName() + + " wrapped in InvocationTargetException, but nothing was thrown"); + lt.add(new Error("Exception " + expected.getName() + " was not thrown")); + } else { + System.out.println("PASS, saw expected return."); + } } catch (InvocationTargetException e) { Throwable th = e.getCause(); - if (th instanceof AbstractMethodError) { - th.printStackTrace(System.out); - System.out.println("PASS, saw expected exception (AbstractMethodError, wrapped in InvocationTargetException)."); + th.printStackTrace(System.out); + if (expected != null) { + if (expected.isInstance(th)) { + System.out.println("PASS, saw expected exception (" + expected.getName() + ")."); + } else { + System.out.println("FAIL, Expected " + expected.getName() + + " wrapped in InvocationTargetException, saw " + th); + lt.add(th); + } } else { - System.out.println("Expected AbstractMethodError wrapped in InvocationTargetException, saw " + th); - throw th; + System.out.println("FAIL, expected no exception, saw " + th); + lt.add(th); } } + System.out.println(); + } + + /* Many-arg versions of above */ + private static void tryAndCheckThrownMany(List lt, byte[] dBytes, String what, Class expected) + throws Throwable { + + System.out.println("Methodhandle invokeExact I.m(11params) for instance of " + what); + ByteClassLoader bcl1 = new ByteClassLoader("p.D", readJarFiles, false); + try { + Class d1 = bcl1.loadBytes("p.D", dBytes); + Class t1 = bcl1.loadBytes("p.T", bytesForT()); + invokeTestMany(t1, d1, expected, lt); + } finally { + bcl1.close(); // Not necessary for others -- all class files are written in this call. + } + + { + System.out.println("Bytecode invokeInterface I.m(11params) for instance of " + what); + ByteClassLoader bcl2 = new ByteClassLoader("pD_m_pri_imp_pI", readJarFiles, false); + Class d2 = bcl2.loadBytes("p.D", dBytes); + Class t2 = bcl2.loadClass("p.Tdirect"); + badGoodBadGoodMany(t2, d2, expected, lt); + + } + { + System.out.println("Reflection invokeInterface I.m(11params) for instance of " + what); + ByteClassLoader bcl2 = new ByteClassLoader("pD_m_pri_imp_pI", readJarFiles, false); + Class d2 = bcl2.loadBytes("p.D", dBytes); + Class t2 = bcl2.loadClass("p.Treflect"); + invokeTestMany(t2, d2, expected, lt); + } + } + + private static void invokeTestMany(Class t, Class d, Class expected, List lt) + throws Throwable { + try { + Method m = t.getMethod("test", p.I.class, + Byte.TYPE, Character.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE, + Object.class, Object.class, Object.class, + Object.class, Object.class, Object.class); + Object o = d.newInstance(); + Byte b = 1; + Character c = 2; + Short s = 3; + Integer i = 4; + Long j = 5L; + Object o1 = b; + Object o2 = c; + Object o3 = s; + Object o4 = i; + Object o5 = j; + Object o6 = "6"; + + Object result = m.invoke(null, o, b, c, s, i, j, + o1, o2, o3, o4, o5, o6); + if (expected != null) { + System.out.println("FAIL, Expected " + expected.getName() + + " wrapped in InvocationTargetException, but nothing was thrown"); + lt.add(new Error("Exception " + expected.getName() + + " was not thrown")); + } else { + System.out.println("PASS, saw expected return."); + } + } catch (InvocationTargetException e) { + Throwable th = e.getCause(); + th.printStackTrace(System.out); + if (expected != null) { + if (expected.isInstance(th)) { + System.out.println("PASS, saw expected exception (" + + expected.getName() + ")."); + } else { + System.out.println("FAIL, Expected " + expected.getName() + + " wrapped in InvocationTargetException, saw " + th); + lt.add(th); + } + } else { + System.out.println("FAIL, expected no exception, saw " + th); + lt.add(th); + } + } + System.out.println(); + } + + /** + * This tests a peculiar idiom for tickling the bug on older VMs that lack + * methodhandles. The bug (if not fixed) acts in the following way: + * + * When a broken receiver is passed to the first execution of an invokeinterface + * bytecode, the illegal access is detected before the effects of resolution are + * cached for later use, and so repeated calls with a broken receiver will always + * throw the correct error. + * + * If, however, a good receiver is passed to the invokeinterface, the effects of + * resolution will be successfully cached. A subsequent execution with a broken + * receiver will reuse the cached information, skip the detailed resolution work, + * and instead encounter a null pointer. By convention, that is the encoding for a + * missing abstract method, and an AbstractMethodError is thrown -- not the expected + * IllegalAccessError. + * + * @param t2 Test invocation class + * @param d2 Test receiver class + * @param expected expected exception type + * @param lt list of unexpected throwables seen + */ + private static void badGoodBadGood(Class t2, Class d2, Class expected, List lt) + throws Throwable { + System.out.println(" Error input 1st time"); + invokeTest(t2, d2, expected, lt); + System.out.println(" Good input (instance of Dok)"); + invokeTest(t2, Dok.class, null, lt); + System.out.println(" Error input 2nd time"); + invokeTest(t2, d2, expected, lt); + System.out.println(" Good input (instance of Dok)"); + invokeTest(t2, Dok.class, null, lt); + } + + private static void badGoodBadGoodMany(Class t2, Class d2, Class expected, List lt) + throws Throwable { + System.out.println(" Error input 1st time"); + invokeTestMany(t2, d2, expected, lt); + System.out.println(" Good input (instance of Dok)"); + invokeTestMany(t2, Dok.class, null, lt); + System.out.println(" Error input 2nd time"); + invokeTestMany(t2, d2, expected, lt); + System.out.println(" Good input (instance of Dok)"); + invokeTestMany(t2, Dok.class, null, lt); } } diff -r 0611ce949aaa -r e254e5940c19 test/compiler/jsr292/methodHandleExceptions/p/C.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/jsr292/methodHandleExceptions/p/C.java Thu Dec 05 16:37:29 2013 +0400 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2013, 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. + * + */ + +package p; + +/** + * Test class -- implements I, which provides default for m, but this class + * declares it abstract which (should) hide the interface default, and throw + * an abstract method error if called. + * + */ +public abstract class C implements p.I { + public abstract int m(); +} diff -r 0611ce949aaa -r e254e5940c19 test/compiler/jsr292/methodHandleExceptions/p/Dok.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/jsr292/methodHandleExceptions/p/Dok.java Thu Dec 05 16:37:29 2013 +0400 @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2013, 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. + * + */ +package p; + +/** + * Test class -- implements I, extends E, both define m, so all should be well. + */ +public class Dok extends p.E { + +} diff -r 0611ce949aaa -r e254e5940c19 test/compiler/jsr292/methodHandleExceptions/p/E.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/jsr292/methodHandleExceptions/p/E.java Thu Dec 05 16:37:29 2013 +0400 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2013, 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. + * + */ + +package p; + +/** + * Test class -- implements I, which provides default for m, but this class + * redeclares it so that all its non-overriding descendants should call its + * method instead (with no error, assuming no descendant monkey business, which + * of course is NOT usually the case in this test). + * + */ +public abstract class E implements p.I { + public int m() { + return 2; + } +} diff -r 0611ce949aaa -r e254e5940c19 test/compiler/jsr292/methodHandleExceptions/p/F.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/jsr292/methodHandleExceptions/p/F.java Thu Dec 05 16:37:29 2013 +0400 @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2013, 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. + * + */ + +package p; + +/** + * Test class -- implements I, which provides default for m, but this class + * redeclares it so that all its non-overriding descendants should call its + * method instead (with no error, assuming no descendant monkey business, which + * of course is NOT usually the case in this test). + * + * Note that m is final -- one form of monkey business is attempting to redefine + * m. + * + */ +public abstract class F implements p.I { + final public int m() { + return 2; + } +} diff -r 0611ce949aaa -r e254e5940c19 test/compiler/jsr292/methodHandleExceptions/p/I.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/jsr292/methodHandleExceptions/p/I.java Thu Dec 05 16:37:29 2013 +0400 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2013, 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. + * + */ + +package p; + +/** + * Test interface I, provides default implementations for m() and m(11args). + */ + +public interface I { + default public int m() { return 1; } + default public int m(byte b, char c, short s, int i, long l, + Object o1, Object o2, Object o3, Object o4, Object o5, Object o6) { + return 2; + } +} diff -r 0611ce949aaa -r e254e5940c19 test/compiler/jsr292/methodHandleExceptions/p/Tdirect.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/jsr292/methodHandleExceptions/p/Tdirect.java Thu Dec 05 16:37:29 2013 +0400 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013, 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. + * + */ + +package p; + +/** + * Invokes I.m directly using invokeInterface bytecodes. + */ +public class Tdirect { + public static int test(p.I i) { + int accum = 0; + for (int j = 0; j < 100000; j++) { + accum += i.m(); + } + return accum; + } + + public static int test(p.I ii, byte b, char c, short s, int i, long l, + Object o1, Object o2, Object o3, Object o4, Object o5, Object o6) { + int accum = 0; + for (int j = 0; j < 100000; j++) { + accum += ii.m(b,c,s,i,l,o1,o2,o3,o4,o5,o6); + } + return accum; + } +} diff -r 0611ce949aaa -r e254e5940c19 test/compiler/jsr292/methodHandleExceptions/p/Treflect.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/jsr292/methodHandleExceptions/p/Treflect.java Thu Dec 05 16:37:29 2013 +0400 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013, 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. + * + */ +package p; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * Invokes I.m using reflection. + */ +public class Treflect { + + public static int test(p.I ii) throws Throwable { + int accum = 0; + Method m = p.I.class.getMethod("m"); + try { + for (int j = 0; j < 100000; j++) { + Object o = m.invoke(ii); + accum += ((Integer) o).intValue(); + } + } catch (InvocationTargetException ite) { + throw ite.getCause(); + } + return accum; + } + + public static int test(p.I ii, byte b, char c, short s, int i, long l, + Object o1, Object o2, Object o3, Object o4, Object o5, Object o6) + throws Throwable { + Method m = p.I.class.getMethod("m", Byte.TYPE, Character.TYPE, + Short.TYPE, Integer.TYPE, Long.TYPE, + Object.class, Object.class, Object.class, + Object.class, Object.class, Object.class); + int accum = 0; + try { + for (int j = 0; j < 100000; j++) { + Object o = m.invoke(ii, b, c, s, i, l, o1, o2, o3, o4, o5, o6); + accum += ((Integer) o).intValue(); + } + } catch (InvocationTargetException ite) { + throw ite.getCause(); + } + return accum; + } +} diff -r 0611ce949aaa -r e254e5940c19 test/runtime/6626217/Test6626217.sh --- a/test/runtime/6626217/Test6626217.sh Tue Dec 03 14:13:06 2013 +0400 +++ b/test/runtime/6626217/Test6626217.sh Thu Dec 05 16:37:29 2013 +0400 @@ -21,7 +21,8 @@ # questions. # - + +# @ignore 8028733 # @test @(#)Test6626217.sh # @bug 6626217 # @summary Loader-constraint table allows arrays instead of only the base-classes diff -r 0611ce949aaa -r e254e5940c19 test/runtime/6929067/Test6929067.sh --- a/test/runtime/6929067/Test6929067.sh Tue Dec 03 14:13:06 2013 +0400 +++ b/test/runtime/6929067/Test6929067.sh Thu Dec 05 16:37:29 2013 +0400 @@ -1,6 +1,7 @@ #!/bin/sh ## +## @ignore 8028740 ## @test Test6929067.sh ## @bug 6929067 ## @bug 8021296 diff -r 0611ce949aaa -r e254e5940c19 test/runtime/CDSCompressedKPtrs/XShareAuto.java --- a/test/runtime/CDSCompressedKPtrs/XShareAuto.java Tue Dec 03 14:13:06 2013 +0400 +++ b/test/runtime/CDSCompressedKPtrs/XShareAuto.java Thu Dec 05 16:37:29 2013 +0400 @@ -22,6 +22,7 @@ */ /* + * @ignore 8026154 * @test * @bug 8005933 * @summary Test that -Xshare:auto uses CDS when explicitly specified with -server. diff -r 0611ce949aaa -r e254e5940c19 test/runtime/InitialThreadOverflow/testme.sh --- a/test/runtime/InitialThreadOverflow/testme.sh Tue Dec 03 14:13:06 2013 +0400 +++ b/test/runtime/InitialThreadOverflow/testme.sh Thu Dec 05 16:37:29 2013 +0400 @@ -21,6 +21,7 @@ # or visit www.oracle.com if you need additional information or have any # questions. +# @ignore 8029139 # @test testme.sh # @bug 8009062 # @summary Poor performance of JNI AttachCurrentThread after fix for 7017193 diff -r 0611ce949aaa -r e254e5940c19 test/runtime/LoadClass/LoadClassNegative.java --- a/test/runtime/LoadClass/LoadClassNegative.java Tue Dec 03 14:13:06 2013 +0400 +++ b/test/runtime/LoadClass/LoadClassNegative.java Thu Dec 05 16:37:29 2013 +0400 @@ -22,6 +22,7 @@ */ /* + * @ignore 8028095 * @test * @key regression * @bug 8020675 diff -r 0611ce949aaa -r e254e5940c19 test/runtime/XCheckJniJsig/XCheckJSig.java --- a/test/runtime/XCheckJniJsig/XCheckJSig.java Tue Dec 03 14:13:06 2013 +0400 +++ b/test/runtime/XCheckJniJsig/XCheckJSig.java Thu Dec 05 16:37:29 2013 +0400 @@ -22,6 +22,7 @@ */ /* + * @ignore 8023735 * @test * @bug 7051189 8023393 * @summary Need to suppress info message if -Xcheck:jni is used with libjsig.so diff -r 0611ce949aaa -r e254e5940c19 test/runtime/jsig/Test8017498.sh --- a/test/runtime/jsig/Test8017498.sh Tue Dec 03 14:13:06 2013 +0400 +++ b/test/runtime/jsig/Test8017498.sh Thu Dec 05 16:37:29 2013 +0400 @@ -24,6 +24,7 @@ # ## +## @ignore 8028806 ## @test Test8017498.sh ## @bug 8017498 ## @bug 8020791 diff -r 0611ce949aaa -r e254e5940c19 test/runtime/memory/ReadFromNoaccessArea.java --- a/test/runtime/memory/ReadFromNoaccessArea.java Tue Dec 03 14:13:06 2013 +0400 +++ b/test/runtime/memory/ReadFromNoaccessArea.java Thu Dec 05 16:37:29 2013 +0400 @@ -22,6 +22,7 @@ */ /* + * @ignore 8028398 * @test * @summary Test that touching noaccess area in class ReservedHeapSpace results in SIGSEGV/ACCESS_VIOLATION * @library /testlibrary /testlibrary/whitebox