From 0b2d972fd3d10307bb613cb23d4f09385eb76287 Mon Sep 17 00:00:00 2001 From: Christian Thalinger Date: Mon, 18 Apr 2011 01:33:28 -0700 Subject: [PATCH 01/80] 7018355: JSR 292: VM crash in DefNewGeneration::copy_to_survivor_space Reviewed-by: kvn, jrose --- hotspot/src/share/vm/ci/ciMethod.hpp | 6 +- .../src/share/vm/memory/genOopClosures.hpp | 4 +- .../src/share/vm/prims/methodHandleWalk.cpp | 6 +- hotspot/src/share/vm/prims/methodHandles.cpp | 213 +++++++++--------- hotspot/src/share/vm/prims/methodHandles.hpp | 16 +- .../src/share/vm/runtime/sharedRuntime.cpp | 8 +- 6 files changed, 121 insertions(+), 132 deletions(-) diff --git a/hotspot/src/share/vm/ci/ciMethod.hpp b/hotspot/src/share/vm/ci/ciMethod.hpp index 745806c0c06..840fb5da020 100644 --- a/hotspot/src/share/vm/ci/ciMethod.hpp +++ b/hotspot/src/share/vm/ci/ciMethod.hpp @@ -276,9 +276,9 @@ class ciMethod : public ciObject { void print_short_name(outputStream* st = tty); methodOop get_method_handle_target() { - klassOop receiver_limit_oop = NULL; - int flags = 0; - return MethodHandles::decode_method(get_oop(), receiver_limit_oop, flags); + KlassHandle receiver_limit; int flags = 0; + methodHandle m = MethodHandles::decode_method(get_oop(), receiver_limit, flags); + return m(); } }; diff --git a/hotspot/src/share/vm/memory/genOopClosures.hpp b/hotspot/src/share/vm/memory/genOopClosures.hpp index 77ae7efba6d..6d5257c4f36 100644 --- a/hotspot/src/share/vm/memory/genOopClosures.hpp +++ b/hotspot/src/share/vm/memory/genOopClosures.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2011, 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 @@ -175,7 +175,7 @@ class VerifyOopClosure: public OopClosure { protected: template inline void do_oop_work(T* p) { oop obj = oopDesc::load_decode_heap_oop(p); - guarantee(obj->is_oop_or_null(), "invalid oop"); + guarantee(obj->is_oop_or_null(), err_msg("invalid oop: " INTPTR_FORMAT, obj)); } public: virtual void do_oop(oop* p); diff --git a/hotspot/src/share/vm/prims/methodHandleWalk.cpp b/hotspot/src/share/vm/prims/methodHandleWalk.cpp index 3570d2db403..936d1e73952 100644 --- a/hotspot/src/share/vm/prims/methodHandleWalk.cpp +++ b/hotspot/src/share/vm/prims/methodHandleWalk.cpp @@ -82,10 +82,8 @@ void MethodHandleChain::set_method_handle(Handle mh, TRAPS) { void MethodHandleChain::set_last_method(oop target, TRAPS) { _is_last = true; - klassOop receiver_limit_oop = NULL; - int flags = 0; - methodOop m = MethodHandles::decode_method(target, receiver_limit_oop, flags); - _last_method = methodHandle(THREAD, m); + KlassHandle receiver_limit; int flags = 0; + _last_method = MethodHandles::decode_method(target, receiver_limit, flags); if ((flags & MethodHandles::_dmf_has_receiver) == 0) _last_invoke = Bytecodes::_invokestatic; else if ((flags & MethodHandles::_dmf_does_dispatch) == 0) diff --git a/hotspot/src/share/vm/prims/methodHandles.cpp b/hotspot/src/share/vm/prims/methodHandles.cpp index eb0ba3df1f0..12a483f23b5 100644 --- a/hotspot/src/share/vm/prims/methodHandles.cpp +++ b/hotspot/src/share/vm/prims/methodHandles.cpp @@ -153,9 +153,9 @@ void MethodHandles::set_enabled(bool z) { // and local, like parse a data structure. For speed, such methods work on plain // oops, not handles. Trapping methods uniformly operate on handles. -methodOop MethodHandles::decode_vmtarget(oop vmtarget, int vmindex, oop mtype, - klassOop& receiver_limit_result, int& decode_flags_result) { - if (vmtarget == NULL) return NULL; +methodHandle MethodHandles::decode_vmtarget(oop vmtarget, int vmindex, oop mtype, + KlassHandle& receiver_limit_result, int& decode_flags_result) { + if (vmtarget == NULL) return methodHandle(); assert(methodOopDesc::nonvirtual_vtable_index < 0, "encoding"); if (vmindex < 0) { // this DMH performs no dispatch; it is directly bound to a methodOop @@ -198,20 +198,20 @@ methodOop MethodHandles::decode_vmtarget(oop vmtarget, int vmindex, oop mtype, // MemberName and DirectMethodHandle have the same linkage to the JVM internals. // (MemberName is the non-operational name used for queries and setup.) -methodOop MethodHandles::decode_DirectMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) { +methodHandle MethodHandles::decode_DirectMethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result) { oop vmtarget = java_lang_invoke_DirectMethodHandle::vmtarget(mh); int vmindex = java_lang_invoke_DirectMethodHandle::vmindex(mh); oop mtype = java_lang_invoke_DirectMethodHandle::type(mh); return decode_vmtarget(vmtarget, vmindex, mtype, receiver_limit_result, decode_flags_result); } -methodOop MethodHandles::decode_BoundMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) { +methodHandle MethodHandles::decode_BoundMethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result) { assert(java_lang_invoke_BoundMethodHandle::is_instance(mh), ""); assert(mh->klass() != SystemDictionary::AdapterMethodHandle_klass(), ""); for (oop bmh = mh;;) { // Bound MHs can be stacked to bind several arguments. oop target = java_lang_invoke_MethodHandle::vmtarget(bmh); - if (target == NULL) return NULL; + if (target == NULL) return methodHandle(); decode_flags_result |= MethodHandles::_dmf_binds_argument; klassOop tk = target->klass(); if (tk == SystemDictionary::BoundMethodHandle_klass()) { @@ -236,14 +236,14 @@ methodOop MethodHandles::decode_BoundMethodHandle(oop mh, klassOop& receiver_lim } } -methodOop MethodHandles::decode_AdapterMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) { +methodHandle MethodHandles::decode_AdapterMethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result) { assert(mh->klass() == SystemDictionary::AdapterMethodHandle_klass(), ""); for (oop amh = mh;;) { // Adapter MHs can be stacked to convert several arguments. int conv_op = adapter_conversion_op(java_lang_invoke_AdapterMethodHandle::conversion(amh)); decode_flags_result |= (_dmf_adapter_lsb << conv_op) & _DMF_ADAPTER_MASK; oop target = java_lang_invoke_MethodHandle::vmtarget(amh); - if (target == NULL) return NULL; + if (target == NULL) return methodHandle(); klassOop tk = target->klass(); if (tk == SystemDictionary::AdapterMethodHandle_klass()) { amh = target; @@ -255,8 +255,8 @@ methodOop MethodHandles::decode_AdapterMethodHandle(oop mh, klassOop& receiver_l } } -methodOop MethodHandles::decode_MethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result) { - if (mh == NULL) return NULL; +methodHandle MethodHandles::decode_MethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result) { + if (mh == NULL) return methodHandle(); klassOop mhk = mh->klass(); assert(java_lang_invoke_MethodHandle::is_subclass(mhk), "must be a MethodHandle"); if (mhk == SystemDictionary::DirectMethodHandle_klass()) { @@ -270,7 +270,7 @@ methodOop MethodHandles::decode_MethodHandle(oop mh, klassOop& receiver_limit_re return decode_BoundMethodHandle(mh, receiver_limit_result, decode_flags_result); } else { assert(false, "cannot parse this MH"); - return NULL; // random MH? + return methodHandle(); // random MH? } } @@ -299,9 +299,9 @@ methodOop MethodHandles::decode_methodOop(methodOop m, int& decode_flags_result) // A trusted party is handing us a cookie to determine a method. // Let's boil it down to the method oop they really want. -methodOop MethodHandles::decode_method(oop x, klassOop& receiver_limit_result, int& decode_flags_result) { +methodHandle MethodHandles::decode_method(oop x, KlassHandle& receiver_limit_result, int& decode_flags_result) { decode_flags_result = 0; - receiver_limit_result = NULL; + receiver_limit_result = KlassHandle(); klassOop xk = x->klass(); if (xk == Universe::methodKlassObj()) { return decode_methodOop((methodOop) x, decode_flags_result); @@ -329,7 +329,7 @@ methodOop MethodHandles::decode_method(oop x, klassOop& receiver_limit_result, i assert(!x->is_method(), "already checked"); assert(!java_lang_invoke_MemberName::is_instance(x), "already checked"); } - return NULL; + return methodHandle(); } @@ -389,11 +389,10 @@ void MethodHandles::init_MemberName(oop mname_oop, oop target_oop) { int offset = instanceKlass::cast(k)->offset_from_fields(slot); init_MemberName(mname_oop, k, accessFlags_from(mods), offset); } else { - int decode_flags = 0; klassOop receiver_limit = NULL; - methodOop m = MethodHandles::decode_method(target_oop, - receiver_limit, decode_flags); + KlassHandle receiver_limit; int decode_flags = 0; + methodHandle m = MethodHandles::decode_method(target_oop, receiver_limit, decode_flags); bool do_dispatch = ((decode_flags & MethodHandles::_dmf_does_dispatch) != 0); - init_MemberName(mname_oop, m, do_dispatch); + init_MemberName(mname_oop, m(), do_dispatch); } } @@ -423,13 +422,14 @@ void MethodHandles::init_MemberName(oop mname_oop, klassOop field_holder, Access } -methodOop MethodHandles::decode_MemberName(oop mname, klassOop& receiver_limit_result, int& decode_flags_result) { +methodHandle MethodHandles::decode_MemberName(oop mname, KlassHandle& receiver_limit_result, int& decode_flags_result) { + methodHandle empty; int flags = java_lang_invoke_MemberName::flags(mname); - if ((flags & (IS_METHOD | IS_CONSTRUCTOR)) == 0) return NULL; // not invocable + if ((flags & (IS_METHOD | IS_CONSTRUCTOR)) == 0) return empty; // not invocable oop vmtarget = java_lang_invoke_MemberName::vmtarget(mname); int vmindex = java_lang_invoke_MemberName::vmindex(mname); - if (vmindex == VM_INDEX_UNINITIALIZED) return NULL; // not resolved - methodOop m = decode_vmtarget(vmtarget, vmindex, NULL, receiver_limit_result, decode_flags_result); + if (vmindex == VM_INDEX_UNINITIALIZED) return empty; // not resolved + methodHandle m = decode_vmtarget(vmtarget, vmindex, NULL, receiver_limit_result, decode_flags_result); oop clazz = java_lang_invoke_MemberName::clazz(mname); if (clazz != NULL && java_lang_Class::is_instance(clazz)) { klassOop klass = java_lang_Class::as_klassOop(clazz); @@ -439,9 +439,7 @@ methodOop MethodHandles::decode_MemberName(oop mname, klassOop& receiver_limit_r } // convert the external string or reflective type to an internal signature -Symbol* MethodHandles::convert_to_signature(oop type_str, - bool polymorphic, - TRAPS) { +Symbol* MethodHandles::convert_to_signature(oop type_str, bool polymorphic, TRAPS) { if (java_lang_invoke_MethodType::is_instance(type_str)) { return java_lang_invoke_MethodType::as_signature(type_str, polymorphic, CHECK_NULL); } else if (java_lang_Class::is_instance(type_str)) { @@ -474,48 +472,48 @@ void MethodHandles::resolve_MemberName(Handle mname, TRAPS) { #endif if (java_lang_invoke_MemberName::vmindex(mname()) != VM_INDEX_UNINITIALIZED) return; // already resolved - oop defc_oop = java_lang_invoke_MemberName::clazz(mname()); - oop name_str = java_lang_invoke_MemberName::name(mname()); - oop type_str = java_lang_invoke_MemberName::type(mname()); - int flags = java_lang_invoke_MemberName::flags(mname()); + Handle defc_oop(THREAD, java_lang_invoke_MemberName::clazz(mname())); + Handle name_str(THREAD, java_lang_invoke_MemberName::name( mname())); + Handle type_str(THREAD, java_lang_invoke_MemberName::type( mname())); + int flags = java_lang_invoke_MemberName::flags(mname()); - if (defc_oop == NULL || name_str == NULL || type_str == NULL) { + if (defc_oop.is_null() || name_str.is_null() || type_str.is_null()) { THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to resolve"); } - klassOop defc_klassOop = java_lang_Class::as_klassOop(defc_oop); - defc_oop = NULL; // safety - if (defc_klassOop == NULL) return; // a primitive; no resolution possible - if (!Klass::cast(defc_klassOop)->oop_is_instance()) { - if (!Klass::cast(defc_klassOop)->oop_is_array()) return; - defc_klassOop = SystemDictionary::Object_klass(); + + instanceKlassHandle defc; + { + klassOop defc_klassOop = java_lang_Class::as_klassOop(defc_oop()); + if (defc_klassOop == NULL) return; // a primitive; no resolution possible + if (!Klass::cast(defc_klassOop)->oop_is_instance()) { + if (!Klass::cast(defc_klassOop)->oop_is_array()) return; + defc_klassOop = SystemDictionary::Object_klass(); + } + defc = instanceKlassHandle(THREAD, defc_klassOop); } - instanceKlassHandle defc(THREAD, defc_klassOop); - defc_klassOop = NULL; // safety if (defc.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "primitive class"); } - defc->link_class(CHECK); + defc->link_class(CHECK); // possible safepoint // convert the external string name to an internal symbol - TempNewSymbol name = java_lang_String::as_symbol_or_null(name_str); + TempNewSymbol name = java_lang_String::as_symbol_or_null(name_str()); if (name == NULL) return; // no such name - name_str = NULL; // safety Handle polymorphic_method_type; bool polymorphic_signature = false; if ((flags & ALL_KINDS) == IS_METHOD && (defc() == SystemDictionary::MethodHandle_klass() && - methodOopDesc::is_method_handle_invoke_name(name))) + methodOopDesc::is_method_handle_invoke_name(name))) { polymorphic_signature = true; - - // convert the external string or reflective type to an internal signature - TempNewSymbol type = convert_to_signature(type_str, polymorphic_signature, CHECK); - if (java_lang_invoke_MethodType::is_instance(type_str) && polymorphic_signature) { - polymorphic_method_type = Handle(THREAD, type_str); //preserve exactly } + // convert the external string or reflective type to an internal signature + TempNewSymbol type = convert_to_signature(type_str(), polymorphic_signature, CHECK); + if (java_lang_invoke_MethodType::is_instance(type_str()) && polymorphic_signature) { + polymorphic_method_type = type_str; // preserve exactly + } if (type == NULL) return; // no such signature exists in the VM - type_str = NULL; // safety // Time to do the lookup. switch (flags & ALL_KINDS) { @@ -560,8 +558,8 @@ void MethodHandles::resolve_MemberName(Handle mname, TRAPS) { java_lang_invoke_MemberName::set_vmtarget(mname(), vmtarget); java_lang_invoke_MemberName::set_vmindex(mname(), vmindex); java_lang_invoke_MemberName::set_modifiers(mname(), mods); - DEBUG_ONLY(int junk; klassOop junk2); - assert(decode_MemberName(mname(), junk2, junk) == result.resolved_method()(), + DEBUG_ONLY(KlassHandle junk1; int junk2); + assert(decode_MemberName(mname(), junk1, junk2) == result.resolved_method(), "properly stored for later decoding"); return; } @@ -589,8 +587,8 @@ void MethodHandles::resolve_MemberName(Handle mname, TRAPS) { java_lang_invoke_MemberName::set_vmtarget(mname(), vmtarget); java_lang_invoke_MemberName::set_vmindex(mname(), vmindex); java_lang_invoke_MemberName::set_modifiers(mname(), mods); - DEBUG_ONLY(int junk; klassOop junk2); - assert(decode_MemberName(mname(), junk2, junk) == result.resolved_method()(), + DEBUG_ONLY(KlassHandle junk1; int junk2); + assert(decode_MemberName(mname(), junk1, junk2) == result.resolved_method(), "properly stored for later decoding"); return; } @@ -677,16 +675,14 @@ void MethodHandles::expand_MemberName(Handle mname, int suppress, TRAPS) { case IS_METHOD: case IS_CONSTRUCTOR: { - klassOop receiver_limit = NULL; - int decode_flags = 0; - methodHandle m(THREAD, decode_vmtarget(vmtarget, vmindex, NULL, - receiver_limit, decode_flags)); + KlassHandle receiver_limit; int decode_flags = 0; + methodHandle m = decode_vmtarget(vmtarget, vmindex, NULL, receiver_limit, decode_flags); if (m.is_null()) break; if (!have_defc) { klassOop defc = m->method_holder(); - if (receiver_limit != NULL && receiver_limit != defc - && Klass::cast(receiver_limit)->is_subtype_of(defc)) - defc = receiver_limit; + if (receiver_limit.not_null() && receiver_limit() != defc + && Klass::cast(receiver_limit())->is_subtype_of(defc)) + defc = receiver_limit(); java_lang_invoke_MemberName::set_clazz(mname(), Klass::cast(defc)->java_mirror()); } if (!have_name) { @@ -884,10 +880,9 @@ oop MethodHandles::encode_target(Handle mh, int format, TRAPS) { // - AMH can have methodOop for static invoke with bound receiver // - DMH can have methodOop for static invoke (on variable receiver) // - DMH can have klassOop for dispatched (non-static) invoke - klassOop receiver_limit = NULL; - int decode_flags = 0; - methodOop m = decode_MethodHandle(mh(), receiver_limit, decode_flags); - if (m == NULL) return NULL; + KlassHandle receiver_limit; int decode_flags = 0; + methodHandle m = decode_MethodHandle(mh(), receiver_limit, decode_flags); + if (m.is_null()) return NULL; switch (format) { case ETF_REFLECT_METHOD: // same as jni_ToReflectedMethod: @@ -903,10 +898,10 @@ oop MethodHandles::encode_target(Handle mh, int format, TRAPS) { if (SystemDictionary::MemberName_klass() == NULL) break; instanceKlassHandle mname_klass(THREAD, SystemDictionary::MemberName_klass()); mname_klass->initialize(CHECK_NULL); - Handle mname = mname_klass->allocate_instance_handle(CHECK_NULL); + Handle mname = mname_klass->allocate_instance_handle(CHECK_NULL); // possible safepoint java_lang_invoke_MemberName::set_vmindex(mname(), VM_INDEX_UNINITIALIZED); bool do_dispatch = ((decode_flags & MethodHandles::_dmf_does_dispatch) != 0); - init_MemberName(mname(), m, do_dispatch); + init_MemberName(mname(), m(), do_dispatch); expand_MemberName(mname, 0, CHECK_NULL); return mname(); } @@ -1459,8 +1454,8 @@ void MethodHandles::init_DirectMethodHandle(Handle mh, methodHandle m, bool do_d // that links the interpreter calls to the method. We need the same // bits, and will use the same calling sequence code. - int vmindex = methodOopDesc::garbage_vtable_index; - oop vmtarget = NULL; + int vmindex = methodOopDesc::garbage_vtable_index; + Handle vmtarget; instanceKlass::cast(m->method_holder())->link_class(CHECK); @@ -1478,7 +1473,7 @@ void MethodHandles::init_DirectMethodHandle(Handle mh, methodHandle m, bool do_d } else if (!do_dispatch || m->can_be_statically_bound()) { // We are simulating an invokestatic or invokespecial instruction. // Set up the method pointer, just like ConstantPoolCacheEntry::set_method(). - vmtarget = m(); + vmtarget = m; // this does not help dispatch, but it will make it possible to parse this MH: vmindex = methodOopDesc::nonvirtual_vtable_index; assert(vmindex < 0, "(>=0) == do_dispatch"); @@ -1490,7 +1485,7 @@ void MethodHandles::init_DirectMethodHandle(Handle mh, methodHandle m, bool do_d // For a DMH, it is done now, when the handle is created. Klass* k = Klass::cast(m->method_holder()); if (k->should_be_initialized()) { - k->initialize(CHECK); + k->initialize(CHECK); // possible safepoint } } } else { @@ -1504,10 +1499,10 @@ void MethodHandles::init_DirectMethodHandle(Handle mh, methodHandle m, bool do_d if (me == NULL) { THROW(vmSymbols::java_lang_InternalError()); } - java_lang_invoke_DirectMethodHandle::set_vmtarget(mh(), vmtarget); - java_lang_invoke_DirectMethodHandle::set_vmindex(mh(), vmindex); - DEBUG_ONLY(int flags; klassOop rlimit); - assert(MethodHandles::decode_method(mh(), rlimit, flags) == m(), + java_lang_invoke_DirectMethodHandle::set_vmtarget(mh(), vmtarget()); + java_lang_invoke_DirectMethodHandle::set_vmindex( mh(), vmindex); + DEBUG_ONLY(KlassHandle rlimit; int flags); + assert(MethodHandles::decode_method(mh(), rlimit, flags) == m, "properly stored for later decoding"); DEBUG_ONLY(bool actual_do_dispatch = ((flags & _dmf_does_dispatch) != 0)); assert(!(actual_do_dispatch && !do_dispatch), @@ -1523,10 +1518,13 @@ void MethodHandles::verify_BoundMethodHandle_with_receiver(Handle mh, methodHandle m, TRAPS) { // Verify type. - oop receiver = java_lang_invoke_BoundMethodHandle::argument(mh()); - Handle mtype(THREAD, java_lang_invoke_MethodHandle::type(mh())); KlassHandle bound_recv_type; - if (receiver != NULL) bound_recv_type = KlassHandle(THREAD, receiver->klass()); + { + oop receiver = java_lang_invoke_BoundMethodHandle::argument(mh()); + if (receiver != NULL) + bound_recv_type = KlassHandle(THREAD, receiver->klass()); + } + Handle mtype(THREAD, java_lang_invoke_MethodHandle::type(mh())); verify_method_type(m, mtype, true, bound_recv_type, CHECK); int receiver_pos = m->size_of_parameters() - 1; @@ -1573,8 +1571,8 @@ void MethodHandles::init_BoundMethodHandle_with_receiver(Handle mh, java_lang_invoke_BoundMethodHandle::set_vmtarget(mh(), m()); - DEBUG_ONLY(int junk; klassOop junk2); - assert(MethodHandles::decode_method(mh(), junk2, junk) == m(), "properly stored for later decoding"); + DEBUG_ONLY(KlassHandle junk1; int junk2); + assert(MethodHandles::decode_method(mh(), junk1, junk2) == m, "properly stored for later decoding"); assert(decode_MethodHandle_stack_pushes(mh()) == 1, "BMH pushes one stack slot"); // Done! @@ -1682,8 +1680,11 @@ void MethodHandles::init_BoundMethodHandle(Handle mh, Handle target, int argnum, } // Get bound type and required slots. - oop ptype_oop = java_lang_invoke_MethodType::ptype(java_lang_invoke_MethodHandle::type(target()), argnum); - BasicType ptype = java_lang_Class::as_BasicType(ptype_oop); + BasicType ptype; + { + oop ptype_oop = java_lang_invoke_MethodType::ptype(java_lang_invoke_MethodHandle::type(target()), argnum); + ptype = java_lang_Class::as_BasicType(ptype_oop); + } int slots_pushed = type2size[ptype]; // If (a) the target is a direct non-dispatched method handle, @@ -1694,13 +1695,12 @@ void MethodHandles::init_BoundMethodHandle(Handle mh, Handle target, int argnum, if (OptimizeMethodHandles && target->klass() == SystemDictionary::DirectMethodHandle_klass() && (argnum == 0 || java_lang_invoke_DirectMethodHandle::vmindex(target()) < 0)) { - int decode_flags = 0; klassOop receiver_limit_oop = NULL; - methodHandle m(THREAD, decode_method(target(), receiver_limit_oop, decode_flags)); + KlassHandle receiver_limit; int decode_flags = 0; + methodHandle m = decode_method(target(), receiver_limit, decode_flags); if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "DMH failed to decode"); } DEBUG_ONLY(int m_vmslots = m->size_of_parameters() - slots_pushed); // pos. of 1st arg. assert(java_lang_invoke_BoundMethodHandle::vmslots(mh()) == m_vmslots, "type w/ m sig"); if (argnum == 0 && (decode_flags & _dmf_has_receiver) != 0) { - KlassHandle receiver_limit(THREAD, receiver_limit_oop); init_BoundMethodHandle_with_receiver(mh, m, receiver_limit, decode_flags, CHECK); @@ -2019,7 +2019,6 @@ void MethodHandles::verify_AdapterMethodHandle(Handle mh, int argnum, TRAPS) { } void MethodHandles::init_AdapterMethodHandle(Handle mh, Handle target, int argnum, TRAPS) { - oop argument = java_lang_invoke_AdapterMethodHandle::argument(mh()); int argslot = java_lang_invoke_AdapterMethodHandle::vmargslot(mh()); jint conversion = java_lang_invoke_AdapterMethodHandle::conversion(mh()); jint conv_op = adapter_conversion_op(conversion); @@ -2215,18 +2214,14 @@ JVM_ENTRY(void, MHN_init_DMH(JNIEnv *env, jobject igcls, jobject mh_jh, // which method are we really talking about? if (target_jh == NULL) { THROW(vmSymbols::java_lang_InternalError()); } - oop target_oop = JNIHandles::resolve_non_null(target_jh); - if (java_lang_invoke_MemberName::is_instance(target_oop) && - java_lang_invoke_MemberName::vmindex(target_oop) == VM_INDEX_UNINITIALIZED) { - Handle mname(THREAD, target_oop); - MethodHandles::resolve_MemberName(mname, CHECK); - target_oop = mname(); // in case of GC + Handle target(THREAD, JNIHandles::resolve_non_null(target_jh)); + if (java_lang_invoke_MemberName::is_instance(target()) && + java_lang_invoke_MemberName::vmindex(target()) == VM_INDEX_UNINITIALIZED) { + MethodHandles::resolve_MemberName(target, CHECK); } - int decode_flags = 0; klassOop receiver_limit = NULL; - methodHandle m(THREAD, - MethodHandles::decode_method(target_oop, - receiver_limit, decode_flags)); + KlassHandle receiver_limit; int decode_flags = 0; + methodHandle m = MethodHandles::decode_method(target(), receiver_limit, decode_flags); if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "no such method"); } // The trusted Java code that calls this method should already have performed @@ -2284,12 +2279,8 @@ JVM_ENTRY(void, MHN_init_BMH(JNIEnv *env, jobject igcls, jobject mh_jh, // Target object is a reflective method. (%%% Do we need this alternate path?) Untested("init_BMH of non-MH"); if (argnum != 0) { THROW(vmSymbols::java_lang_InternalError()); } - int decode_flags = 0; klassOop receiver_limit_oop = NULL; - methodHandle m(THREAD, - MethodHandles::decode_method(target(), - receiver_limit_oop, - decode_flags)); - KlassHandle receiver_limit(THREAD, receiver_limit_oop); + KlassHandle receiver_limit; int decode_flags = 0; + methodHandle m = MethodHandles::decode_method(target(), receiver_limit, decode_flags); MethodHandles::init_BoundMethodHandle_with_receiver(mh, m, receiver_limit, decode_flags, @@ -2424,12 +2415,12 @@ JVM_ENTRY(jint, MHN_getNamedCon(JNIEnv *env, jobject igcls, jint which, jobjectA #ifndef PRODUCT if (which >= 0 && which < con_value_count) { int con = con_values[which]; - objArrayOop box = (objArrayOop) JNIHandles::resolve(box_jh); - if (box != NULL && box->klass() == Universe::objectArrayKlassObj() && box->length() > 0) { + objArrayHandle box(THREAD, (objArrayOop) JNIHandles::resolve(box_jh)); + if (box.not_null() && box->klass() == Universe::objectArrayKlassObj() && box->length() > 0) { const char* str = &con_names[0]; for (int i = 0; i < which; i++) str += strlen(str) + 1; // skip name and null - oop name = java_lang_String::create_oop_from_str(str, CHECK_0); + oop name = java_lang_String::create_oop_from_str(str, CHECK_0); // possible safepoint box->obj_at_put(0, name); } return con; @@ -2486,10 +2477,10 @@ JVM_ENTRY(jint, MHN_getMembers(JNIEnv *env, jobject igcls, jclass clazz_jh, jstring name_jh, jstring sig_jh, int mflags, jclass caller_jh, jint skip, jobjectArray results_jh)) { if (clazz_jh == NULL || results_jh == NULL) return -1; - klassOop k_oop = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz_jh)); + KlassHandle k(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(clazz_jh))); - objArrayOop results = (objArrayOop) JNIHandles::resolve(results_jh); - if (results == NULL || !results->is_objArray()) return -1; + objArrayHandle results(THREAD, (objArrayOop) JNIHandles::resolve(results_jh)); + if (results.is_null() || !results->is_objArray()) return -1; TempNewSymbol name = NULL; TempNewSymbol sig = NULL; @@ -2502,20 +2493,20 @@ JVM_ENTRY(jint, MHN_getMembers(JNIEnv *env, jobject igcls, if (sig == NULL) return 0; // a match is not possible } - klassOop caller = NULL; + KlassHandle caller; if (caller_jh != NULL) { oop caller_oop = JNIHandles::resolve_non_null(caller_jh); if (!java_lang_Class::is_instance(caller_oop)) return -1; - caller = java_lang_Class::as_klassOop(caller_oop); + caller = KlassHandle(THREAD, java_lang_Class::as_klassOop(caller_oop)); } - if (name != NULL && sig != NULL && results != NULL) { + if (name != NULL && sig != NULL && results.not_null()) { // try a direct resolve // %%% TO DO } - int res = MethodHandles::find_MemberNames(k_oop, name, sig, mflags, - caller, skip, results); + int res = MethodHandles::find_MemberNames(k(), name, sig, mflags, + caller(), skip, results()); // TO DO: expand at least some of the MemberNames, to avoid massive callbacks return res; } diff --git a/hotspot/src/share/vm/prims/methodHandles.hpp b/hotspot/src/share/vm/prims/methodHandles.hpp index 08e0b537700..d104783d40f 100644 --- a/hotspot/src/share/vm/prims/methodHandles.hpp +++ b/hotspot/src/share/vm/prims/methodHandles.hpp @@ -265,13 +265,13 @@ class MethodHandles: AllStatic { static inline address from_interpreted_entry(EntryKind ek); // helpers for decode_method. - static methodOop decode_methodOop(methodOop m, int& decode_flags_result); - static methodOop decode_vmtarget(oop vmtarget, int vmindex, oop mtype, klassOop& receiver_limit_result, int& decode_flags_result); - static methodOop decode_MemberName(oop mname, klassOop& receiver_limit_result, int& decode_flags_result); - static methodOop decode_MethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result); - static methodOop decode_DirectMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result); - static methodOop decode_BoundMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result); - static methodOop decode_AdapterMethodHandle(oop mh, klassOop& receiver_limit_result, int& decode_flags_result); + static methodOop decode_methodOop(methodOop m, int& decode_flags_result); + static methodHandle decode_vmtarget(oop vmtarget, int vmindex, oop mtype, KlassHandle& receiver_limit_result, int& decode_flags_result); + static methodHandle decode_MemberName(oop mname, KlassHandle& receiver_limit_result, int& decode_flags_result); + static methodHandle decode_MethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result); + static methodHandle decode_DirectMethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result); + static methodHandle decode_BoundMethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result); + static methodHandle decode_AdapterMethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result); // Find out how many stack slots an mh pushes or pops. // The result is *not* reported as a multiple of stack_move_unit(); @@ -317,7 +317,7 @@ class MethodHandles: AllStatic { _dmf_adapter_lsb = 0x20, _DMF_ADAPTER_MASK = (_dmf_adapter_lsb << CONV_OP_LIMIT) - _dmf_adapter_lsb }; - static methodOop decode_method(oop x, klassOop& receiver_limit_result, int& decode_flags_result); + static methodHandle decode_method(oop x, KlassHandle& receiver_limit_result, int& decode_flags_result); enum { // format of query to getConstant: GC_JVM_PUSH_LIMIT = 0, diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.cpp b/hotspot/src/share/vm/runtime/sharedRuntime.cpp index 820678701f4..f60b2f07029 100644 --- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp +++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp @@ -1721,14 +1721,14 @@ char* SharedRuntime::generate_wrong_method_type_message(JavaThread* thread, targetArity = ArgumentCount(target->signature()).size(); } } - klassOop kignore; int dmf_flags = 0; - methodOop actual_method = MethodHandles::decode_method(actual, kignore, dmf_flags); + KlassHandle kignore; int dmf_flags = 0; + methodHandle actual_method = MethodHandles::decode_method(actual, kignore, dmf_flags); if ((dmf_flags & ~(MethodHandles::_dmf_has_receiver | MethodHandles::_dmf_does_dispatch | MethodHandles::_dmf_from_interface)) != 0) - actual_method = NULL; // MH does extra binds, drops, etc. + actual_method = methodHandle(); // MH does extra binds, drops, etc. bool has_receiver = ((dmf_flags & MethodHandles::_dmf_has_receiver) != 0); - if (actual_method != NULL) { + if (actual_method.not_null()) { mhName = actual_method->signature()->as_C_string(); mhArity = ArgumentCount(actual_method->signature()).size(); if (!actual_method->is_static()) mhArity += 1; From 7fb4bcc550613354a9b00517488414aff64cec67 Mon Sep 17 00:00:00 2001 From: Christian Thalinger Date: Mon, 18 Apr 2011 06:50:57 -0700 Subject: [PATCH 02/80] 7036960: TemplateTable::fast_aldc in templateTable_x86_64.cpp uses movptr instead of load_klass Reviewed-by: kvn, iveresov --- .../src/cpu/x86/vm/templateTable_x86_32.cpp | 24 +++++++++---------- .../src/cpu/x86/vm/templateTable_x86_64.cpp | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp index b152f698cfd..483660826ac 100644 --- a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp @@ -413,7 +413,7 @@ void TemplateTable::fast_aldc(bool wide) { Label L_done, L_throw_exception; const Register con_klass_temp = rcx; // same as Rcache - __ movptr(con_klass_temp, Address(rax, oopDesc::klass_offset_in_bytes())); + __ load_klass(con_klass_temp, rax); __ cmpptr(con_klass_temp, ExternalAddress((address)Universe::systemObjArrayKlassObj_addr())); __ jcc(Assembler::notEqual, L_done); __ cmpl(Address(rax, arrayOopDesc::length_offset_in_bytes()), 0); @@ -423,7 +423,7 @@ void TemplateTable::fast_aldc(bool wide) { // Load the exception from the system-array which wraps it: __ bind(L_throw_exception); - __ movptr(rax, Address(rax, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); + __ load_heap_oop(rax, Address(rax, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); __ jump(ExternalAddress(Interpreter::throw_exception_entry())); __ bind(L_done); @@ -937,9 +937,9 @@ void TemplateTable::aastore() { __ jcc(Assembler::zero, is_null); // Move subklass into EBX - __ movptr(rbx, Address(rax, oopDesc::klass_offset_in_bytes())); + __ load_klass(rbx, rax); // Move superklass into EAX - __ movptr(rax, Address(rdx, oopDesc::klass_offset_in_bytes())); + __ load_klass(rax, rdx); __ movptr(rax, Address(rax, sizeof(oopDesc) + objArrayKlass::element_klass_offset_in_bytes())); // Compress array+index*wordSize+12 into a single register. Frees ECX. __ lea(rdx, element_address); @@ -1992,7 +1992,7 @@ void TemplateTable::_return(TosState state) { if (_desc->bytecode() == Bytecodes::_return_register_finalizer) { assert(state == vtos, "only valid state"); __ movptr(rax, aaddress(0)); - __ movptr(rdi, Address(rax, oopDesc::klass_offset_in_bytes())); + __ load_klass(rdi, rax); __ movl(rdi, Address(rdi, Klass::access_flags_offset_in_bytes() + sizeof(oopDesc))); __ testl(rdi, JVM_ACC_HAS_FINALIZER); Label skip_register_finalizer; @@ -2939,7 +2939,7 @@ void TemplateTable::invokevirtual_helper(Register index, Register recv, // get receiver klass __ null_check(recv, oopDesc::klass_offset_in_bytes()); // Keep recv in rcx for callee expects it there - __ movptr(rax, Address(recv, oopDesc::klass_offset_in_bytes())); + __ load_klass(rax, recv); __ verify_oop(rax); // profile this call @@ -3019,7 +3019,7 @@ void TemplateTable::invokeinterface(int byte_no) { // Get receiver klass into rdx - also a null check __ restore_locals(); // restore rdi - __ movptr(rdx, Address(rcx, oopDesc::klass_offset_in_bytes())); + __ load_klass(rdx, rcx); __ verify_oop(rdx); // profile this call @@ -3103,7 +3103,7 @@ void TemplateTable::invokedynamic(int byte_no) { __ profile_call(rsi); } - __ movptr(rcx_method_handle, Address(rax_callsite, __ delayed_value(java_lang_invoke_CallSite::target_offset_in_bytes, rcx))); + __ load_heap_oop(rcx_method_handle, Address(rax_callsite, __ delayed_value(java_lang_invoke_CallSite::target_offset_in_bytes, rcx))); __ null_check(rcx_method_handle); __ prepare_to_jump_from_interpreted(); __ jump_to_method_handle_entry(rcx_method_handle, rdx); @@ -3249,7 +3249,7 @@ void TemplateTable::_new() { (int32_t)markOopDesc::prototype()); // header __ pop(rcx); // get saved klass back in the register. } - __ movptr(Address(rax, oopDesc::klass_offset_in_bytes()), rcx); // klass + __ store_klass(rax, rcx); // klass { SkipIfEqual skip_if(_masm, &DTraceAllocProbes, 0); @@ -3324,7 +3324,7 @@ void TemplateTable::checkcast() { __ movptr(rax, Address(rcx, rbx, Address::times_ptr, sizeof(constantPoolOopDesc))); __ bind(resolved); - __ movptr(rbx, Address(rdx, oopDesc::klass_offset_in_bytes())); + __ load_klass(rbx, rdx); // Generate subtype check. Blows ECX. Resets EDI. Object in EDX. // Superklass in EAX. Subklass in EBX. @@ -3367,12 +3367,12 @@ void TemplateTable::instanceof() { __ push(atos); call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc) ); __ pop_ptr(rdx); - __ movptr(rdx, Address(rdx, oopDesc::klass_offset_in_bytes())); + __ load_klass(rdx, rdx); __ jmp(resolved); // Get superklass in EAX and subklass in EDX __ bind(quicked); - __ movptr(rdx, Address(rax, oopDesc::klass_offset_in_bytes())); + __ load_klass(rdx, rax); __ movptr(rax, Address(rcx, rbx, Address::times_ptr, sizeof(constantPoolOopDesc))); __ bind(resolved); diff --git a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp index 64385a7d54c..e1ec5ad4474 100644 --- a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp @@ -427,7 +427,7 @@ void TemplateTable::fast_aldc(bool wide) { Label L_done, L_throw_exception; const Register con_klass_temp = rcx; // same as cache const Register array_klass_temp = rdx; // same as index - __ movptr(con_klass_temp, Address(rax, oopDesc::klass_offset_in_bytes())); + __ load_klass(con_klass_temp, rax); __ lea(array_klass_temp, ExternalAddress((address)Universe::systemObjArrayKlassObj_addr())); __ cmpptr(con_klass_temp, Address(array_klass_temp, 0)); __ jcc(Assembler::notEqual, L_done); @@ -438,7 +438,7 @@ void TemplateTable::fast_aldc(bool wide) { // Load the exception from the system-array which wraps it: __ bind(L_throw_exception); - __ movptr(rax, Address(rax, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); + __ load_heap_oop(rax, Address(rax, arrayOopDesc::base_offset_in_bytes(T_OBJECT))); __ jump(ExternalAddress(Interpreter::throw_exception_entry())); __ bind(L_done); From 06c379e859be3678183feec8ba4b680fe0b4172f Mon Sep 17 00:00:00 2001 From: Pavel Porvatov Date: Tue, 19 Apr 2011 10:11:58 +0400 Subject: [PATCH 03/80] 7036025: java.security.AccessControlException when creating JFileChooser in signed applet Reviewed-by: malenkov --- .../classes/sun/swing/WindowsPlacesBar.java | 9 ++- .../JFileChooser/7036025/bug7036025.java | 62 +++++++++++++++++++ .../JFileChooser/7036025/security.policy | 5 ++ 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 jdk/test/javax/swing/JFileChooser/7036025/bug7036025.java create mode 100644 jdk/test/javax/swing/JFileChooser/7036025/security.policy diff --git a/jdk/src/share/classes/sun/swing/WindowsPlacesBar.java b/jdk/src/share/classes/sun/swing/WindowsPlacesBar.java index 9972b671d75..a05259e5978 100644 --- a/jdk/src/share/classes/sun/swing/WindowsPlacesBar.java +++ b/jdk/src/share/classes/sun/swing/WindowsPlacesBar.java @@ -29,6 +29,8 @@ import java.awt.event.*; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.*; +import java.security.AccessController; +import java.security.PrivilegedAction; import javax.swing.*; import javax.swing.border.*; @@ -79,7 +81,12 @@ public class WindowsPlacesBar extends JToolBar setBackground(bgColor); FileSystemView fsv = fc.getFileSystemView(); - files = (File[])ShellFolder.get("fileChooserShortcutPanelFolders"); + files = AccessController.doPrivileged(new PrivilegedAction() { + public File[] run() { + return (File[]) ShellFolder.get("fileChooserShortcutPanelFolders"); + } + }); + buttons = new JToggleButton[files.length]; buttonGroup = new ButtonGroup(); for (int i = 0; i < files.length; i++) { diff --git a/jdk/test/javax/swing/JFileChooser/7036025/bug7036025.java b/jdk/test/javax/swing/JFileChooser/7036025/bug7036025.java new file mode 100644 index 00000000000..dd7b003a01f --- /dev/null +++ b/jdk/test/javax/swing/JFileChooser/7036025/bug7036025.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + @bug 7036025 + @summary java.security.AccessControlException when creating JFileChooser in signed applet + @author Pavel Porvatov + @run main/othervm/policy=security.policy bug7036025 +*/ + +import javax.swing.*; +import java.io.File; + +public class bug7036025 { + public static final String DIR = "c:/temp"; + + public static void main(String[] args) throws Exception { + String systemLookAndFeelClassName = UIManager.getSystemLookAndFeelClassName(); + + if (!systemLookAndFeelClassName.toLowerCase().contains("windows")) { + System.out.println("The test is only for Windows OS."); + + return; + } + + File file = new File(DIR); + + if (!file.exists()) { + if (!file.mkdir()) { + throw new RuntimeException("Cannot create " + DIR); + } + + file.deleteOnExit(); + } + + UIManager.setLookAndFeel(systemLookAndFeelClassName); + + new JFileChooser(file); + + System.out.println("Test passed for LookAndFeel " + UIManager.getLookAndFeel().getName()); + } +} diff --git a/jdk/test/javax/swing/JFileChooser/7036025/security.policy b/jdk/test/javax/swing/JFileChooser/7036025/security.policy new file mode 100644 index 00000000000..57e0bd2af52 --- /dev/null +++ b/jdk/test/javax/swing/JFileChooser/7036025/security.policy @@ -0,0 +1,5 @@ +grant { + permission java.io.FilePermission "C:\\temp\\*", "read"; + permission java.io.FilePermission "C:\\temp", "read,write,delete"; + permission java.util.PropertyPermission "*", "read"; +}; From 89d504b32f618ac6beecf8aa773fe94d09c1f5bb Mon Sep 17 00:00:00 2001 From: Anthony Petrov Date: Tue, 19 Apr 2011 14:44:09 +0400 Subject: [PATCH 04/80] 7036669: Simplify revalidating component hierarchy with multiple validate roots Introduce Component.revalidate() method Reviewed-by: art, alexp --- jdk/src/share/classes/java/awt/Component.java | 40 ++++++ .../plaf/basic/BasicSplitPaneDivider.java | 6 +- .../awt/Component/Revalidate/Revalidate.java | 122 ++++++++++++++++++ 3 files changed, 165 insertions(+), 3 deletions(-) create mode 100644 jdk/test/java/awt/Component/Revalidate/Revalidate.java diff --git a/jdk/src/share/classes/java/awt/Component.java b/jdk/src/share/classes/java/awt/Component.java index 5b572797d84..f577887abe6 100644 --- a/jdk/src/share/classes/java/awt/Component.java +++ b/jdk/src/share/classes/java/awt/Component.java @@ -2944,6 +2944,46 @@ public abstract class Component implements ImageObserver, MenuContainer, } } + /** + * Revalidates the component hierarchy up to the nearest validate root. + *

+ * This method first invalidates the component hierarchy starting from this + * component up to the nearest validate root. Afterwards, the component + * hierarchy is validated starting from the nearest validate root. + *

+ * This is a convenience method supposed to help application developers + * avoid looking for validate roots manually. Basically, it's equivalent to + * first calling the {@link #invalidate()} method on this component, and + * then calling the {@link #validate()} method on the nearest validate + * root. + * + * @see Container#isValidateRoot + * @since 1.7 + */ + public void revalidate() { + synchronized (getTreeLock()) { + invalidate(); + + Container root = getContainer(); + if (root == null) { + // There's no parents. Just validate itself. + validate(); + } else { + while (!root.isValidateRoot()) { + if (root.getContainer() == null) { + // If there's no validate roots, we'll validate the + // topmost container + break; + } + + root = root.getContainer(); + } + + root.validate(); + } + } + } + /** * Creates a graphics context for this component. This method will * return null if this component is currently not diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneDivider.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneDivider.java index 42c88e02823..70b0bffaac7 100644 --- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneDivider.java +++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicSplitPaneDivider.java @@ -154,7 +154,7 @@ public class BasicSplitPaneDivider extends Container setBackground(UIManager.getColor("SplitPane.background")); } - private void revalidate() { + private void revalidateSplitPane() { invalidate(); if (splitPane != null) { splitPane.revalidate(); @@ -315,7 +315,7 @@ public class BasicSplitPaneDivider extends Container setCursor((orientation == JSplitPane.HORIZONTAL_SPLIT) ? Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR) : Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR)); - revalidate(); + revalidateSplitPane(); } else if (e.getPropertyName() == JSplitPane. ONE_TOUCH_EXPANDABLE_PROPERTY) { @@ -376,7 +376,7 @@ public class BasicSplitPaneDivider extends Container add(rightButton); } } - revalidate(); + revalidateSplitPane(); } diff --git a/jdk/test/java/awt/Component/Revalidate/Revalidate.java b/jdk/test/java/awt/Component/Revalidate/Revalidate.java new file mode 100644 index 00000000000..670c374f87d --- /dev/null +++ b/jdk/test/java/awt/Component/Revalidate/Revalidate.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 7036669 + @summary Test Component.revalidate() method + @author anthony.petrov@oracle.com: area=awt.component + @run main Revalidate +*/ + +import java.awt.*; + +public class Revalidate { + private static Frame frame = new Frame(); + private static Panel panel = new Panel() { + @Override + public boolean isValidateRoot() { + return true; + } + }; + private static Button button = new Button("Test"); + + private static void sleep() { + try { Thread.sleep(500); } catch (Exception e) {} + } + + private static void printState(String str) { + System.out.println(str + " isValid state: "); + System.out.println(" frame: " + frame.isValid()); + System.out.println(" panel: " + panel.isValid()); + System.out.println(" button: " + button.isValid()); + } + + private static void fail(String msg) { + frame.dispose(); + throw new RuntimeException(msg); + } + + private static void check(String n, Component c, boolean v) { + if (c.isValid() != v) { + fail(n + ".isValid() = " + c.isValid() + "; expected: " + v); + } + } + private static void check(String str, boolean f, boolean p, boolean b) { + printState(str); + + check("frame", frame, f); + check("panel", panel, p); + check("button", button, b); + } + + public static void main(String[] args) { + // setup + frame.add(panel); + panel.add(button); + frame.setBounds(200, 200, 300, 200); + frame.setVisible(true); + sleep(); + check("Upon showing", true, true, true); + + button.setBounds(1, 1, 30, 30); + sleep(); + check("button.setBounds():", true, false, false); + + button.revalidate(); + sleep(); + check("button.revalidate():", true, true, true); + + button.setBounds(1, 1, 30, 30); + sleep(); + check("button.setBounds():", true, false, false); + + panel.revalidate(); + sleep(); + // because the panel's validate root is actually OK + check("panel.revalidate():", true, false, false); + + button.revalidate(); + sleep(); + check("button.revalidate():", true, true, true); + + panel.setBounds(2, 2, 125, 130); + sleep(); + check("panel.setBounds():", false, false, true); + + button.revalidate(); + sleep(); + check("button.revalidate():", false, true, true); + + panel.setBounds(3, 3, 152, 121); + sleep(); + check("panel.setBounds():", false, false, true); + + panel.revalidate(); + sleep(); + check("panel.revalidate():", true, true, true); + + // cleanup + frame.dispose(); + } +} From d097a2cab142e19c36b1d8c4ca5455eb125ba719 Mon Sep 17 00:00:00 2001 From: Andrei Dmitriev Date: Tue, 19 Apr 2011 18:52:49 +0400 Subject: [PATCH 05/80] 7036733: Regression : NullPointerException when scrolling horizontally on AWT List Reviewed-by: dcherepanov --- .../classes/sun/awt/X11/XListPeer.java | 5 +- .../awt/List/ScrollOutside/ScrollOut.java | 84 +++++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 jdk/test/java/awt/List/ScrollOutside/ScrollOut.java diff --git a/jdk/src/solaris/classes/sun/awt/X11/XListPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XListPeer.java index c8799a1ad07..838899e49b8 100644 --- a/jdk/src/solaris/classes/sun/awt/X11/XListPeer.java +++ b/jdk/src/solaris/classes/sun/awt/X11/XListPeer.java @@ -1479,16 +1479,19 @@ class XListPeer extends XComponentPeer implements ListPeer, XScrollbarClient { int h = height - (SCROLLBAR_AREA + (2 * MARGIN)); hsb.setValue(hsb.getValue() + x); + int options = PAINT_ITEMS | PAINT_HSCROLL; + Rectangle source = null; Point distance = null; if (x < 0) { source = new Rectangle(MARGIN + SPACE, MARGIN, w + x, h); distance = new Point(-x, 0); + options |= COPY_AREA; } else if (x > 0) { source = new Rectangle(MARGIN + SPACE + x, MARGIN, w - x, h); distance = new Point(-x, 0); + options |= COPY_AREA; } - int options = COPY_AREA | PAINT_ITEMS | PAINT_HSCROLL; repaint(vsb.getValue(), lastItemDisplayed(), options, source, distance); } diff --git a/jdk/test/java/awt/List/ScrollOutside/ScrollOut.java b/jdk/test/java/awt/List/ScrollOutside/ScrollOut.java new file mode 100644 index 00000000000..21b8f848229 --- /dev/null +++ b/jdk/test/java/awt/List/ScrollOutside/ScrollOut.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 7036733 + @summary Regression : NullPointerException when scrolling horizontally on AWT List + @author Andrei Dmitriev area=awt-list + @library ../../regtesthelpers + @build Util + @run main ScrollOut +*/ + +import java.awt.*; +import java.awt.event.*; +import sun.awt.SunToolkit; +import test.java.awt.regtesthelpers.Util; + +public class ScrollOut +{ + public static final void main(String args[]) + { + final Frame frame = new Frame(); + final List list = new List(); + Robot robot = null; + + for (int i = 0; i < 5; i++){ + list.add("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"); + } + + frame.add(list); + + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + + ((SunToolkit)Toolkit.getDefaultToolkit()).realSync(); + + try{ + robot = new Robot(); + }catch(AWTException e){ + throw new RuntimeException(e); + } + + //Drag from center to the outside on left + Point from = new Point(list.getLocationOnScreen().x + list.getWidth()/2, + list.getLocationOnScreen().y + list.getHeight()/2); + Point to = new Point(list.getLocationOnScreen().x - 30, + from.y); + + ((SunToolkit)Toolkit.getDefaultToolkit()).realSync(); + Util.drag(robot, from, to, InputEvent.BUTTON1_MASK); + + ((SunToolkit)Toolkit.getDefaultToolkit()).realSync(); + + //Drag from center to the outside on up + to = new Point(from.x, + list.getLocationOnScreen().y - 50); + + ((SunToolkit)Toolkit.getDefaultToolkit()).realSync(); + Util.drag(robot, from, to, InputEvent.BUTTON1_MASK); + + }//End init() +} From e8d2ed978ffa48cba68457642727d708cd390a69 Mon Sep 17 00:00:00 2001 From: Tom Deneau Date: Tue, 19 Apr 2011 09:30:17 -0700 Subject: [PATCH 06/80] 7037812: few more defaults changes for new AMD processors Use PREFETCHW as default prefetch instruction, set UseXMMForArrayCopy and UseUnalignedLoadStores to true by default. Reviewed-by: kvn --- hotspot/src/cpu/x86/vm/vm_version_x86.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp index 87982e9ab04..fb81bf3d475 100644 --- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp +++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp @@ -441,12 +441,25 @@ void VM_Version::get_processor_features() { } } - // On family 21 processors default is no sw prefetch - if ( cpu_family() == 21 ) { + // some defaults for AMD family 15h + if ( cpu_family() == 0x15 ) { + // On family 15h processors default is no sw prefetch if (FLAG_IS_DEFAULT(AllocatePrefetchStyle)) { AllocatePrefetchStyle = 0; } + // Also, if some other prefetch style is specified, default instruction type is PREFETCHW + if (FLAG_IS_DEFAULT(AllocatePrefetchInstr)) { + AllocatePrefetchInstr = 3; + } + // On family 15h processors use XMM and UnalignedLoadStores for Array Copy + if( FLAG_IS_DEFAULT(UseXMMForArrayCopy) ) { + UseXMMForArrayCopy = true; + } + if( FLAG_IS_DEFAULT(UseUnalignedLoadStores) && UseXMMForArrayCopy ) { + UseUnalignedLoadStores = true; + } } + } if( is_intel() ) { // Intel cpus specific settings From 12d1d9acc1d4f2c3cf5addbdd21f5f7c0cdcf05a Mon Sep 17 00:00:00 2001 From: Antonios Printezis Date: Tue, 19 Apr 2011 15:46:59 -0400 Subject: [PATCH 07/80] 7011855: G1: non-product flag to artificially grow the heap It introduces non-product cmd line parameter G1DummyRegionsPerGC which indicates how many "dummy" regions to allocate at the end of each GC. This allows the G1 heap to grow artificially and makes concurrent marking cycles more frequent irrespective of what the application that is running is doing. The dummy regions will be found totally empty during cleanup so this parameter can also be used to stress the concurrent cleanup operation. Reviewed-by: brutisso, johnc --- .../gc_implementation/g1/g1CollectedHeap.cpp | 24 +++++++++++++++++++ .../gc_implementation/g1/g1CollectedHeap.hpp | 8 +++++++ .../vm/gc_implementation/g1/g1_globals.hpp | 5 ++++ 3 files changed, 37 insertions(+) diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index 1c2b116a5ba..becc9451265 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -2113,6 +2113,28 @@ bool G1CollectedHeap::should_do_concurrent_full_gc(GCCause::Cause cause) { (cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent)); } +#ifndef PRODUCT +void G1CollectedHeap::allocate_dummy_regions() { + // Let's fill up most of the region + size_t word_size = HeapRegion::GrainWords - 1024; + // And as a result the region we'll allocate will be humongous. + guarantee(isHumongous(word_size), "sanity"); + + for (uintx i = 0; i < G1DummyRegionsPerGC; ++i) { + // Let's use the existing mechanism for the allocation + HeapWord* dummy_obj = humongous_obj_allocate(word_size); + if (dummy_obj != NULL) { + MemRegion mr(dummy_obj, word_size); + CollectedHeap::fill_with_object(mr); + } else { + // If we can't allocate once, we probably cannot allocate + // again. Let's get out of the loop. + break; + } + } +} +#endif // !PRODUCT + void G1CollectedHeap::increment_full_collections_completed(bool concurrent) { MonitorLockerEx x(FullGCCount_lock, Mutex::_no_safepoint_check_flag); @@ -3338,6 +3360,8 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) { doConcurrentMark(); } + allocate_dummy_regions(); + #if YOUNG_LIST_VERBOSE gclog_or_tty->print_cr("\nEnd of the pause.\nYoung_list:"); _young_list->print(); diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp index a9412774486..1b7e6a307bc 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp @@ -298,6 +298,14 @@ private: // started is maintained in _total_full_collections in CollectedHeap. volatile unsigned int _full_collections_completed; + // This is a non-product method that is helpful for testing. It is + // called at the end of a GC and artificially expands the heap by + // allocating a number of dead regions. This way we can induce very + // frequent marking cycles and stress the cleanup / concurrent + // cleanup code more (as all the regions that will be allocated by + // this method will be found dead by the marking cycle). + void allocate_dummy_regions() PRODUCT_RETURN; + // These are macros so that, if the assert fires, we get the correct // line number, file, etc. diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp index 5fd535533e1..cea90240141 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp @@ -300,6 +300,11 @@ develop(uintx, G1StressConcRegionFreeingDelayMillis, 0, \ "Artificial delay during concurrent region freeing") \ \ + develop(uintx, G1DummyRegionsPerGC, 0, \ + "The number of dummy regions G1 will allocate at the end of " \ + "each evacuation pause in order to artificially fill up the " \ + "heap and stress the marking implementation.") \ + \ develop(bool, ReduceInitialCardMarksForG1, false, \ "When ReduceInitialCardMarks is true, this flag setting " \ " controls whether G1 allows the RICM optimization") \ From e45512128a063241bb4de8c1463aa7fc11016cf7 Mon Sep 17 00:00:00 2001 From: Alex Menkov Date: Wed, 20 Apr 2011 16:46:31 +0400 Subject: [PATCH 08/80] 7030629: closed/sun/audio/AudioClipClose/AudioClipClose.java test fails just against jdk7 b134 7033899: SoundTestSuite: test050 fails on Ubuntu Linux Reviewed-by: bae --- .../sound/PLATFORM_API_LinuxOS_ALSA_PCM.c | 56 ++++++++++++++++--- 1 file changed, 49 insertions(+), 7 deletions(-) diff --git a/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCM.c b/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCM.c index fb2ba3c5da3..0c5784bc496 100644 --- a/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCM.c +++ b/jdk/src/solaris/native/com/sun/media/sound/PLATFORM_API_LinuxOS_ALSA_PCM.c @@ -239,6 +239,13 @@ void DAUDIO_GetFormats(INT32 mixerIndex, INT32 deviceID, int isSource, void* cre snd_pcm_close(handle); } +/** Workaround for cr 7033899, 7030629: + * dmix plugin doesn't like flush (snd_pcm_drop) when the buffer is empty + * (just opened, underruned or already flushed). + * Sometimes it causes PCM falls to -EBADFD error, + * sometimes causes bufferSize change. + * To prevent unnecessary flushes AlsaPcmInfo::isRunning & isFlushed are used. + */ /* ******* ALSA PCM INFO ******************** */ typedef struct tag_AlsaPcmInfo { snd_pcm_t* handle; @@ -248,6 +255,8 @@ typedef struct tag_AlsaPcmInfo { int frameSize; // storage size in Bytes unsigned int periods; snd_pcm_uframes_t periodSize; + short int isRunning; // see comment above + short int isFlushed; // see comment above #ifdef GET_POSITION_METHOD2 // to be used exclusively by getBytePosition! snd_pcm_status_t* positionStatus; @@ -432,6 +441,9 @@ void* DAUDIO_Open(INT32 mixerIndex, INT32 deviceID, int isSource, return NULL; } memset(info, 0, sizeof(AlsaPcmInfo)); + // initial values are: stopped, flushed + info->isRunning = 0; + info->isFlushed = 1; ret = openPCMfromDeviceID(deviceID, &(info->handle), isSource, FALSE /* do open device*/); if (ret == 0) { @@ -587,6 +599,14 @@ int DAUDIO_Start(void* id, int isSource) { || (state == SND_PCM_STATE_RUNNING) || (state == SND_PCM_STATE_XRUN) || (state == SND_PCM_STATE_SUSPENDED); + if (ret) { + info->isRunning = 1; + // source line should keep isFlushed value until Write() is called; + // for target data line reset it right now. + if (!isSource) { + info->isFlushed = 0; + } + } TRACE1("< DAUDIO_Start %s\n", ret?"success":"error"); return ret?TRUE:FALSE; } @@ -606,6 +626,7 @@ int DAUDIO_Stop(void* id, int isSource) { ERROR1("ERROR in snd_pcm_pause: %s\n", snd_strerror(ret)); return FALSE; } + info->isRunning = 0; TRACE0("< DAUDIO_Stop success\n"); return TRUE; } @@ -651,8 +672,7 @@ int xrun_recovery(AlsaPcmInfo* info, int err) { return -1; } return 1; - } - else if (err == -ESTRPIPE) { + } else if (err == -ESTRPIPE) { TRACE0("xrun_recovery: suspended.\n"); ret = snd_pcm_resume(info->handle); if (ret < 0) { @@ -667,11 +687,11 @@ int xrun_recovery(AlsaPcmInfo* info, int err) { return -1; } return 1; - } - else if (err == -EAGAIN) { + } else if (err == -EAGAIN) { TRACE0("xrun_recovery: EAGAIN try again flag.\n"); return 0; } + TRACE2("xrun_recovery: unexpected error %d: %s\n", err, snd_strerror(err)); return -1; } @@ -691,6 +711,7 @@ int DAUDIO_Write(void* id, char* data, int byteSize) { TRACE0("< DAUDIO_Write returning -1\n"); return -1; } + count = 2; // maximum number of trials to recover from underrun //frameSize = snd_pcm_bytes_to_frames(info->handle, byteSize); frameSize = (snd_pcm_sframes_t) (byteSize / info->frameSize); @@ -712,6 +733,12 @@ int DAUDIO_Write(void* id, char* data, int byteSize) { } } while (TRUE); //ret = snd_pcm_frames_to_bytes(info->handle, writtenFrames); + + if (writtenFrames > 0) { + // reset "flushed" flag + info->isFlushed = 0; + } + ret = (int) (writtenFrames * info->frameSize); TRACE1("< DAUDIO_Write: returning %d bytes.\n", ret); return ret; @@ -736,6 +763,11 @@ int DAUDIO_Read(void* id, char* data, int byteSize) { TRACE0("< DAUDIO_Read returning -1\n"); return -1; } + if (!info->isRunning && info->isFlushed) { + // PCM has nothing to read + return 0; + } + count = 2; // maximum number of trials to recover from error //frameSize = snd_pcm_bytes_to_frames(info->handle, byteSize); frameSize = (snd_pcm_sframes_t) (byteSize / info->frameSize); @@ -784,12 +816,22 @@ int DAUDIO_Flush(void* id, int isSource) { int ret; TRACE0("DAUDIO_Flush\n"); + + if (info->isFlushed) { + // nothing to drop + return 1; + } + ret = snd_pcm_drop(info->handle); if (ret != 0) { ERROR1("ERROR in snd_pcm_drop: %s\n", snd_strerror(ret)); return FALSE; } - ret = DAUDIO_Start(id, isSource); + + info->isFlushed = 1; + if (info->isRunning) { + ret = DAUDIO_Start(id, isSource); + } return ret; } @@ -800,7 +842,7 @@ int DAUDIO_GetAvailable(void* id, int isSource) { int ret; state = snd_pcm_state(info->handle); - if (state == SND_PCM_STATE_XRUN) { + if (info->isFlushed || state == SND_PCM_STATE_XRUN) { // if in xrun state then we have the entire buffer available, // not 0 as alsa reports ret = info->bufferSizeInBytes; @@ -841,7 +883,7 @@ INT64 DAUDIO_GetBytePosition(void* id, int isSource, INT64 javaBytePos) { snd_pcm_state_t state; state = snd_pcm_state(info->handle); - if (state != SND_PCM_STATE_XRUN) { + if (!info->isFlushed && state != SND_PCM_STATE_XRUN) { #ifdef GET_POSITION_METHOD2 snd_timestamp_t* ts; snd_pcm_uframes_t framesAvail; From f3c1d5f3ea80220483e024f9f3fffa80063f5267 Mon Sep 17 00:00:00 2001 From: Jennifer Godinez Date: Wed, 20 Apr 2011 09:10:36 -0700 Subject: [PATCH 09/80] 6989724: font warnings in the build, native code Reviewed-by: bae, igor --- .../share/native/sun/awt/giflib/dgif_lib.c | 2 +- .../share/native/sun/font/fontscalerdefs.h | 4 +++- .../sun/font/layout/HangulLayoutEngine.cpp | 2 +- .../native/sun/font/layout/MPreFixups.cpp | 4 ++-- jdk/src/solaris/native/sun/awt/fontpath.c | 3 ++- jdk/src/windows/native/sun/font/fontpath.c | 24 +++++++++---------- 6 files changed, 21 insertions(+), 18 deletions(-) diff --git a/jdk/src/share/native/sun/awt/giflib/dgif_lib.c b/jdk/src/share/native/sun/awt/giflib/dgif_lib.c index b566e7e1cc1..742ae9c3335 100644 --- a/jdk/src/share/native/sun/awt/giflib/dgif_lib.c +++ b/jdk/src/share/native/sun/awt/giflib/dgif_lib.c @@ -70,7 +70,7 @@ /* avoid extra function call in case we use fread (TVT) */ #define READ(_gif,_buf,_len) \ (((GifFilePrivateType*)_gif->Private)->Read ? \ - ((GifFilePrivateType*)_gif->Private)->Read(_gif,_buf,_len) : \ + (size_t)((GifFilePrivateType*)_gif->Private)->Read(_gif,_buf,_len) : \ fread(_buf,1,_len,((GifFilePrivateType*)_gif->Private)->File)) static int DGifGetWord(GifFileType *GifFile, int *Word); diff --git a/jdk/src/share/native/sun/font/fontscalerdefs.h b/jdk/src/share/native/sun/font/fontscalerdefs.h index 4e1bb99e9c3..8f142752af9 100644 --- a/jdk/src/share/native/sun/font/fontscalerdefs.h +++ b/jdk/src/share/native/sun/font/fontscalerdefs.h @@ -55,13 +55,15 @@ typedef Int32 hsFixed; typedef Int32 hsFract; typedef UInt32 Bool32; +#ifndef __cplusplus #ifndef false - #define false 0 + #define false 0 #endif #ifndef true #define true 1 #endif +#endif #define kPosInfinity32 (0x7fffffff) #define kNegInfinity32 (0x80000000) diff --git a/jdk/src/share/native/sun/font/layout/HangulLayoutEngine.cpp b/jdk/src/share/native/sun/font/layout/HangulLayoutEngine.cpp index 806f2dc5813..adc30bd526d 100644 --- a/jdk/src/share/native/sun/font/layout/HangulLayoutEngine.cpp +++ b/jdk/src/share/native/sun/font/layout/HangulLayoutEngine.cpp @@ -162,7 +162,7 @@ static le_int32 decompose(LEUnicode syllable, LEUnicode &lead, LEUnicode &vowel, return 0; } - lead = LJMO_FIRST + (sIndex / HSYL_LVCNT); + lead = (LEUnicode)(LJMO_FIRST + (sIndex / HSYL_LVCNT)); vowel = VJMO_FIRST + (sIndex % HSYL_LVCNT) / TJMO_COUNT; trail = TJMO_FIRST + (sIndex % TJMO_COUNT); diff --git a/jdk/src/share/native/sun/font/layout/MPreFixups.cpp b/jdk/src/share/native/sun/font/layout/MPreFixups.cpp index 673ea32ca16..254b3b01ace 100644 --- a/jdk/src/share/native/sun/font/layout/MPreFixups.cpp +++ b/jdk/src/share/native/sun/font/layout/MPreFixups.cpp @@ -65,9 +65,9 @@ void MPreFixups::add(le_int32 baseIndex, le_int32 mpreIndex) } } -void MPreFixups::apply(LEGlyphStorage &glyphStorage, LEErrorCode& success) +void MPreFixups::apply(LEGlyphStorage &glyphStorage, LEErrorCode& leSuccess) { - if (LE_FAILURE(success)) { + if (LE_FAILURE(leSuccess)) { return; } diff --git a/jdk/src/solaris/native/sun/awt/fontpath.c b/jdk/src/solaris/native/sun/awt/fontpath.c index 68c352db16c..98d6f1419fc 100644 --- a/jdk/src/solaris/native/sun/awt/fontpath.c +++ b/jdk/src/solaris/native/sun/awt/fontpath.c @@ -1107,7 +1107,8 @@ Java_sun_font_FontConfigManager_getFontConfig arrlen = (*env)->GetArrayLength(env, fcCompFontArray); for (i=0; iNewString(env, lpelfe->elfFullName, - wcslen((LPWSTR)lpelfe->elfFullName)); + (jsize)wcslen((LPWSTR)lpelfe->elfFullName)); fullnameLC = (*env)->CallObjectMethod(env, fullname, fmi->toLowerCaseMID, fmi->locale); (*env)->CallBooleanMethod(env, fmi->list, fmi->addMID, fullname); @@ -314,7 +314,7 @@ static int CALLBACK EnumFamilyNamesW( GdiFontMapInfo *fmi = (GdiFontMapInfo*)lParam; JNIEnv *env = fmi->env; jstring familyLC; - int slen; + size_t slen; LOGFONTW lfw; /* Both Vista and XP return DEVICE_FONTTYPE for OTF fonts */ @@ -336,7 +336,7 @@ static int CALLBACK EnumFamilyNamesW( return 1; } slen = wcslen(lpelfe->elfLogFont.lfFaceName); - fmi->family = (*env)->NewString(env,lpelfe->elfLogFont.lfFaceName, slen); + fmi->family = (*env)->NewString(env,lpelfe->elfLogFont.lfFaceName, (jsize)slen); familyLC = (*env)->CallObjectMethod(env, fmi->family, fmi->toLowerCaseMID, fmi->locale); /* check if already seen this family with a different charset */ @@ -386,10 +386,10 @@ static int CALLBACK EnumFamilyNamesW( static BOOL RegistryToBaseTTNameA(LPSTR name) { static const char TTSUFFIX[] = " (TrueType)"; static const char OTSUFFIX[] = " (OpenType)"; - int TTSLEN = strlen(TTSUFFIX); + size_t TTSLEN = strlen(TTSUFFIX); char *suffix; - int len = strlen(name); + size_t len = strlen(name); if (len == 0) { return FALSE; } @@ -412,10 +412,10 @@ static BOOL RegistryToBaseTTNameA(LPSTR name) { static BOOL RegistryToBaseTTNameW(LPWSTR name) { static const wchar_t TTSUFFIX[] = L" (TrueType)"; static const wchar_t OTSUFFIX[] = L" (OpenType)"; - int TTSLEN = wcslen(TTSUFFIX); + size_t TTSLEN = wcslen(TTSUFFIX); wchar_t *suffix; - int len = wcslen(name); + size_t len = wcslen(name); if (len == 0) { return FALSE; } @@ -439,7 +439,7 @@ static void registerFontA(GdiFontMapInfo *fmi, jobject fontToFileMap, LPSTR ptr1, ptr2; jstring fontStr; JNIEnv *env = fmi->env; - int dslen = strlen(data); + size_t dslen = strlen(data); jstring fileStr = JNU_NewStringPlatform(env, data); /* TTC or ttc means it may be a collection. Need to parse out @@ -488,8 +488,8 @@ static void registerFontW(GdiFontMapInfo *fmi, jobject fontToFileMap, wchar_t *ptr1, *ptr2; jstring fontStr; JNIEnv *env = fmi->env; - int dslen = wcslen(data); - jstring fileStr = (*env)->NewString(env, data, dslen); + size_t dslen = wcslen(data); + jstring fileStr = (*env)->NewString(env, data, (jsize)dslen); /* TTC or ttc means it may be a collection. Need to parse out * multiple font face names separated by " & " @@ -510,7 +510,7 @@ static void registerFontW(GdiFontMapInfo *fmi, jobject fontToFileMap, while ((ptr2 = wcsstr(ptr1, L" & ")) != NULL) { ptr1 = ptr2+3; } - fontStr = (*env)->NewString(env, ptr1, wcslen(ptr1)); + fontStr = (*env)->NewString(env, ptr1, (jsize)wcslen(ptr1)); fontStr = (*env)->CallObjectMethod(env, fontStr, fmi->toLowerCaseMID, fmi->locale); @@ -524,7 +524,7 @@ static void registerFontW(GdiFontMapInfo *fmi, jobject fontToFileMap, } } } else { - fontStr = (*env)->NewString(env, name, wcslen(name)); + fontStr = (*env)->NewString(env, name, (jsize)wcslen(name)); fontStr = (*env)->CallObjectMethod(env, fontStr, fmi->toLowerCaseMID, fmi->locale); (*env)->CallObjectMethod(env, fontToFileMap, fmi->putMID, From 75eac4de0f1d459f0fe1dfefa68700662c29a6b5 Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Wed, 20 Apr 2011 09:29:00 -0700 Subject: [PATCH 10/80] 7009346: java/dyn/InvokeDynamicPrintArgs.java fails with NPE on solaris-sparc with -Xcomp Reviewed-by: kvn, jrose, twisti --- hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp b/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp index 397a59431bc..ac9e39fb6bf 100644 --- a/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp @@ -486,7 +486,7 @@ void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHan if (ek == _invokespecial_mh) { // Must load & check the first argument before entering the target method. __ load_method_handle_vmslots(O0_argslot, G3_method_handle, O1_scratch); - __ ld_ptr(__ argument_address(O0_argslot), G3_method_handle); + __ ld_ptr(__ argument_address(O0_argslot, -1), G3_method_handle); __ null_check(G3_method_handle); __ verify_oop(G3_method_handle); } From 46259d93bafd4f37136eed70013a1bf54dbcef91 Mon Sep 17 00:00:00 2001 From: Vladimir Danushevsky Date: Wed, 20 Apr 2011 14:07:57 -0400 Subject: [PATCH 11/80] 7035861: linux-armsflt: assert(ni->data() == (int)(x + o)) failed: instructions must match The change avoids generating relocation info entry for the staging area patching stub on systems that don't support movw/movt instructions Reviewed-by: bdelsart --- hotspot/src/share/vm/c1/c1_Runtime1.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/c1/c1_Runtime1.cpp b/hotspot/src/share/vm/c1/c1_Runtime1.cpp index 03e83420d45..8e012443504 100644 --- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp +++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp @@ -1026,9 +1026,21 @@ JRT_ENTRY(void, Runtime1::patch_code(JavaThread* thread, Runtime1::StubID stub_i // first replace the tail, then the call #ifdef ARM if(stub_id == Runtime1::load_klass_patching_id && !VM_Version::supports_movw()) { + nmethod* nm = CodeCache::find_nmethod(instr_pc); + oop* oop_addr = NULL; + assert(nm != NULL, "invalid nmethod_pc"); + RelocIterator oops(nm, copy_buff, copy_buff + 1); + while (oops.next()) { + if (oops.type() == relocInfo::oop_type) { + oop_Relocation* r = oops.oop_reloc(); + oop_addr = r->oop_addr(); + break; + } + } + assert(oop_addr != NULL, "oop relocation must exist"); copy_buff -= *byte_count; NativeMovConstReg* n_copy2 = nativeMovConstReg_at(copy_buff); - n_copy2->set_data((intx) (load_klass()), instr_pc); + n_copy2->set_pc_relative_offset((address)oop_addr, instr_pc); } #endif From cf6f747d172817d2573e5012b6677d0d21dcbc0e Mon Sep 17 00:00:00 2001 From: Andrew Haley Date: Wed, 20 Apr 2011 17:12:04 -0700 Subject: [PATCH 12/80] 7034464: Support transparent large pages on Linux Support transparent huge pages on Linux available since 2.6.38 Reviewed-by: iveresov, ysr --- hotspot/src/os/linux/vm/globals_linux.hpp | 20 +++-- hotspot/src/os/linux/vm/os_linux.cpp | 102 +++++++++++++++++++--- hotspot/src/os/linux/vm/os_linux.hpp | 3 + 3 files changed, 107 insertions(+), 18 deletions(-) diff --git a/hotspot/src/os/linux/vm/globals_linux.hpp b/hotspot/src/os/linux/vm/globals_linux.hpp index cd74589e40c..9b1a164a6ed 100644 --- a/hotspot/src/os/linux/vm/globals_linux.hpp +++ b/hotspot/src/os/linux/vm/globals_linux.hpp @@ -29,13 +29,19 @@ // Defines Linux specific flags. They are not available on other platforms. // #define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct) \ - product(bool, UseOprofile, false, \ - "enable support for Oprofile profiler") \ - \ - product(bool, UseLinuxPosixThreadCPUClocks, true, \ - "enable fast Linux Posix clocks where available") -// NB: The default value of UseLinuxPosixThreadCPUClocks may be -// overridden in Arguments::parse_each_vm_init_arg. + product(bool, UseOprofile, false, \ + "enable support for Oprofile profiler") \ + \ + product(bool, UseLinuxPosixThreadCPUClocks, true, \ + "enable fast Linux Posix clocks where available") \ +/* NB: The default value of UseLinuxPosixThreadCPUClocks may be \ + overridden in Arguments::parse_each_vm_init_arg. */ \ + \ + product(bool, UseHugeTLBFS, false, \ + "Use MAP_HUGETLB for large pages") \ + \ + product(bool, UseSHM, false, \ + "Use SYSV shared memory for large pages") // // Defines Linux-specific default values. The flags are available on all diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp index a3975d89892..cb3959a6831 100644 --- a/hotspot/src/os/linux/vm/os_linux.cpp +++ b/hotspot/src/os/linux/vm/os_linux.cpp @@ -2465,16 +2465,40 @@ bool os::commit_memory(char* addr, size_t size, bool exec) { return res != (uintptr_t) MAP_FAILED; } +// Define MAP_HUGETLB here so we can build HotSpot on old systems. +#ifndef MAP_HUGETLB +#define MAP_HUGETLB 0x40000 +#endif + +// Define MADV_HUGEPAGE here so we can build HotSpot on old systems. +#ifndef MADV_HUGEPAGE +#define MADV_HUGEPAGE 14 +#endif + bool os::commit_memory(char* addr, size_t size, size_t alignment_hint, bool exec) { + if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) { + int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; + uintptr_t res = + (uintptr_t) ::mmap(addr, size, prot, + MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS|MAP_HUGETLB, + -1, 0); + return res != (uintptr_t) MAP_FAILED; + } + return commit_memory(addr, size, exec); } -void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) { } +void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) { + if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) { + // We don't check the return value: madvise(MADV_HUGEPAGE) may not + // be supported or the memory may already be backed by huge pages. + ::madvise(addr, bytes, MADV_HUGEPAGE); + } +} void os::free_memory(char *addr, size_t bytes) { - ::mmap(addr, bytes, PROT_READ | PROT_WRITE, - MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0); + ::madvise(addr, bytes, MADV_DONTNEED); } void os::numa_make_global(char *addr, size_t bytes) { @@ -2818,6 +2842,43 @@ bool os::unguard_memory(char* addr, size_t size) { return linux_mprotect(addr, size, PROT_READ|PROT_WRITE); } +bool os::Linux::hugetlbfs_sanity_check(bool warn, size_t page_size) { + bool result = false; + void *p = mmap (NULL, page_size, PROT_READ|PROT_WRITE, + MAP_ANONYMOUS|MAP_PRIVATE|MAP_HUGETLB, + -1, 0); + + if (p != (void *) -1) { + // We don't know if this really is a huge page or not. + FILE *fp = fopen("/proc/self/maps", "r"); + if (fp) { + while (!feof(fp)) { + char chars[257]; + long x = 0; + if (fgets(chars, sizeof(chars), fp)) { + if (sscanf(chars, "%lx-%*lx", &x) == 1 + && x == (long)p) { + if (strstr (chars, "hugepage")) { + result = true; + break; + } + } + } + } + fclose(fp); + } + munmap (p, page_size); + if (result) + return true; + } + + if (warn) { + warning("HugeTLBFS is not supported by the operating system."); + } + + return result; +} + /* * Set the coredump_filter bits to include largepages in core dump (bit 6) * @@ -2860,7 +2921,16 @@ static void set_coredump_filter(void) { static size_t _large_page_size = 0; bool os::large_page_init() { - if (!UseLargePages) return false; + if (!UseLargePages) { + UseHugeTLBFS = false; + UseSHM = false; + return false; + } + + if (FLAG_IS_DEFAULT(UseHugeTLBFS) && FLAG_IS_DEFAULT(UseSHM)) { + // Our user has not expressed a preference, so we'll try both. + UseHugeTLBFS = UseSHM = true; + } if (LargePageSizeInBytes) { _large_page_size = LargePageSizeInBytes; @@ -2905,6 +2975,9 @@ bool os::large_page_init() { } } + // print a warning if any large page related flag is specified on command line + bool warn_on_failure = !FLAG_IS_DEFAULT(UseHugeTLBFS); + const size_t default_page_size = (size_t)Linux::page_size(); if (_large_page_size > default_page_size) { _page_sizes[0] = _large_page_size; @@ -2912,6 +2985,14 @@ bool os::large_page_init() { _page_sizes[2] = 0; } + UseHugeTLBFS = UseHugeTLBFS && + Linux::hugetlbfs_sanity_check(warn_on_failure, _large_page_size); + + if (UseHugeTLBFS) + UseSHM = false; + + UseLargePages = UseHugeTLBFS || UseSHM; + set_coredump_filter(); // Large page support is available on 2.6 or newer kernel, some vendors @@ -2928,7 +3009,7 @@ bool os::large_page_init() { char* os::reserve_memory_special(size_t bytes, char* req_addr, bool exec) { // "exec" is passed in but not used. Creating the shared image for // the code cache doesn't have an SHM_X executable permission to check. - assert(UseLargePages, "only for large pages"); + assert(UseLargePages && UseSHM, "only for SHM large pages"); key_t key = IPC_PRIVATE; char *addr; @@ -2995,16 +3076,15 @@ size_t os::large_page_size() { return _large_page_size; } -// Linux does not support anonymous mmap with large page memory. The only way -// to reserve large page memory without file backing is through SysV shared -// memory API. The entire memory region is committed and pinned upfront. -// Hopefully this will change in the future... +// HugeTLBFS allows application to commit large page memory on demand; +// with SysV SHM the entire memory region must be allocated as shared +// memory. bool os::can_commit_large_page_memory() { - return false; + return UseHugeTLBFS; } bool os::can_execute_large_page_memory() { - return false; + return UseHugeTLBFS; } // Reserve memory at an arbitrary address, only if that area is diff --git a/hotspot/src/os/linux/vm/os_linux.hpp b/hotspot/src/os/linux/vm/os_linux.hpp index 18803ac3496..c0a63fe88ea 100644 --- a/hotspot/src/os/linux/vm/os_linux.hpp +++ b/hotspot/src/os/linux/vm/os_linux.hpp @@ -86,6 +86,9 @@ class Linux { static void rebuild_cpu_to_node_map(); static GrowableArray* cpu_to_node() { return _cpu_to_node; } + + static bool hugetlbfs_sanity_check(bool warn, size_t page_size); + public: static void init_thread_fpu_state(); static int get_fpu_control_word(); From abc5f94df75ac9e50fce5a85292e4444206e746c Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Wed, 20 Apr 2011 18:29:35 -0700 Subject: [PATCH 13/80] 7026700: regression in 6u24-rev-b23: Crash in C2 compiler in PhaseIdealLoop::build_loop_late_post Memory slices should be always created for non-static fields after allocation Reviewed-by: never --- hotspot/src/share/vm/opto/escape.cpp | 11 ++-- hotspot/src/share/vm/opto/graphKit.cpp | 12 ++--- hotspot/src/share/vm/opto/graphKit.hpp | 6 +-- hotspot/src/share/vm/opto/library_call.cpp | 10 ++-- hotspot/src/share/vm/opto/memnode.cpp | 58 ++++++++++------------ 5 files changed, 43 insertions(+), 54 deletions(-) diff --git a/hotspot/src/share/vm/opto/escape.cpp b/hotspot/src/share/vm/opto/escape.cpp index a7b509e34c5..21cc00c9cc2 100644 --- a/hotspot/src/share/vm/opto/escape.cpp +++ b/hotspot/src/share/vm/opto/escape.cpp @@ -1437,7 +1437,10 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) // Update the memory inputs of MemNodes with the value we computed // in Phase 2 and move stores memory users to corresponding memory slices. -#ifdef ASSERT + + // Disable memory split verification code until the fix for 6984348. + // Currently it produces false negative results since it does not cover all cases. +#if 0 // ifdef ASSERT visited.Reset(); Node_Stack old_mems(arena, _compile->unique() >> 2); #endif @@ -1447,7 +1450,7 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) Node *n = ptnode_adr(i)->_node; assert(n != NULL, "sanity"); if (n->is_Mem()) { -#ifdef ASSERT +#if 0 // ifdef ASSERT Node* old_mem = n->in(MemNode::Memory); if (!visited.test_set(old_mem->_idx)) { old_mems.push(old_mem, old_mem->outcnt()); @@ -1469,13 +1472,13 @@ void ConnectionGraph::split_unique_types(GrowableArray &alloc_worklist) } } } -#ifdef ASSERT +#if 0 // ifdef ASSERT // Verify that memory was split correctly while (old_mems.is_nonempty()) { Node* old_mem = old_mems.node(); uint old_cnt = old_mems.index(); old_mems.pop(); - assert(old_cnt = old_mem->outcnt(), "old mem could be lost"); + assert(old_cnt == old_mem->outcnt(), "old mem could be lost"); } #endif } diff --git a/hotspot/src/share/vm/opto/graphKit.cpp b/hotspot/src/share/vm/opto/graphKit.cpp index afa2efff986..590c05fb35d 100644 --- a/hotspot/src/share/vm/opto/graphKit.cpp +++ b/hotspot/src/share/vm/opto/graphKit.cpp @@ -2950,8 +2950,7 @@ static void hook_memory_on_init(GraphKit& kit, int alias_idx, //---------------------------set_output_for_allocation------------------------- Node* GraphKit::set_output_for_allocation(AllocateNode* alloc, - const TypeOopPtr* oop_type, - bool raw_mem_only) { + const TypeOopPtr* oop_type) { int rawidx = Compile::AliasIdxRaw; alloc->set_req( TypeFunc::FramePtr, frameptr() ); add_safepoint_edges(alloc); @@ -2975,7 +2974,7 @@ Node* GraphKit::set_output_for_allocation(AllocateNode* alloc, rawoop)->as_Initialize(); assert(alloc->initialization() == init, "2-way macro link must work"); assert(init ->allocation() == alloc, "2-way macro link must work"); - if (ReduceFieldZeroing && !raw_mem_only) { + { // Extract memory strands which may participate in the new object's // initialization, and source them from the new InitializeNode. // This will allow us to observe initializations when they occur, @@ -3036,11 +3035,9 @@ Node* GraphKit::set_output_for_allocation(AllocateNode* alloc, // the type to a constant. // The optional arguments are for specialized use by intrinsics: // - If 'extra_slow_test' if not null is an extra condition for the slow-path. -// - If 'raw_mem_only', do not cast the result to an oop. // - If 'return_size_val', report the the total object size to the caller. Node* GraphKit::new_instance(Node* klass_node, Node* extra_slow_test, - bool raw_mem_only, // affect only raw memory Node* *return_size_val) { // Compute size in doublewords // The size is always an integral number of doublewords, represented @@ -3111,7 +3108,7 @@ Node* GraphKit::new_instance(Node* klass_node, size, klass_node, initial_slow_test); - return set_output_for_allocation(alloc, oop_type, raw_mem_only); + return set_output_for_allocation(alloc, oop_type); } //-------------------------------new_array------------------------------------- @@ -3121,7 +3118,6 @@ Node* GraphKit::new_instance(Node* klass_node, Node* GraphKit::new_array(Node* klass_node, // array klass (maybe variable) Node* length, // number of array elements int nargs, // number of arguments to push back for uncommon trap - bool raw_mem_only, // affect only raw memory Node* *return_size_val) { jint layout_con = Klass::_lh_neutral_value; Node* layout_val = get_layout_helper(klass_node, layout_con); @@ -3266,7 +3262,7 @@ Node* GraphKit::new_array(Node* klass_node, // array klass (maybe variable) ary_type = ary_type->is_aryptr()->cast_to_size(length_type); } - Node* javaoop = set_output_for_allocation(alloc, ary_type, raw_mem_only); + Node* javaoop = set_output_for_allocation(alloc, ary_type); // Cast length on remaining path to be as narrow as possible if (map()->find_edge(length) >= 0) { diff --git a/hotspot/src/share/vm/opto/graphKit.hpp b/hotspot/src/share/vm/opto/graphKit.hpp index 4523326dbaf..724e5bda501 100644 --- a/hotspot/src/share/vm/opto/graphKit.hpp +++ b/hotspot/src/share/vm/opto/graphKit.hpp @@ -769,15 +769,13 @@ class GraphKit : public Phase { // implementation of object creation Node* set_output_for_allocation(AllocateNode* alloc, - const TypeOopPtr* oop_type, - bool raw_mem_only); + const TypeOopPtr* oop_type); Node* get_layout_helper(Node* klass_node, jint& constant_value); Node* new_instance(Node* klass_node, Node* slow_test = NULL, - bool raw_mem_only = false, Node* *return_size_val = NULL); Node* new_array(Node* klass_node, Node* count_val, int nargs, - bool raw_mem_only = false, Node* *return_size_val = NULL); + Node* *return_size_val = NULL); // Handy for making control flow IfNode* create_and_map_if(Node* ctrl, Node* tst, float prob, float cnt) { diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp index 0f73e144d17..2ace3655978 100644 --- a/hotspot/src/share/vm/opto/library_call.cpp +++ b/hotspot/src/share/vm/opto/library_call.cpp @@ -3376,8 +3376,7 @@ bool LibraryCallKit::inline_array_copyOf(bool is_copyOfRange) { Node* orig_tail = _gvn.transform( new(C, 3) SubINode(orig_length, start) ); Node* moved = generate_min_max(vmIntrinsics::_min, orig_tail, length); - const bool raw_mem_only = true; - newcopy = new_array(klass_node, length, 0, raw_mem_only); + newcopy = new_array(klass_node, length, 0); // Generate a direct call to the right arraycopy function(s). // We know the copy is disjoint but we might not know if the @@ -4174,8 +4173,6 @@ bool LibraryCallKit::inline_native_clone(bool is_virtual) { const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM; int raw_adr_idx = Compile::AliasIdxRaw; - const bool raw_mem_only = true; - Node* array_ctl = generate_array_guard(obj_klass, (RegionNode*)NULL); if (array_ctl != NULL) { @@ -4184,8 +4181,7 @@ bool LibraryCallKit::inline_native_clone(bool is_virtual) { set_control(array_ctl); Node* obj_length = load_array_length(obj); Node* obj_size = NULL; - Node* alloc_obj = new_array(obj_klass, obj_length, 0, - raw_mem_only, &obj_size); + Node* alloc_obj = new_array(obj_klass, obj_length, 0, &obj_size); if (!use_ReduceInitialCardMarks()) { // If it is an oop array, it requires very special treatment, @@ -4257,7 +4253,7 @@ bool LibraryCallKit::inline_native_clone(bool is_virtual) { // It's an instance, and it passed the slow-path tests. PreserveJVMState pjvms(this); Node* obj_size = NULL; - Node* alloc_obj = new_instance(obj_klass, NULL, raw_mem_only, &obj_size); + Node* alloc_obj = new_instance(obj_klass, NULL, &obj_size); copy_to_clone(obj, alloc_obj, obj_size, false, !use_ReduceInitialCardMarks()); diff --git a/hotspot/src/share/vm/opto/memnode.cpp b/hotspot/src/share/vm/opto/memnode.cpp index d5d53132a3a..804ebee5d1b 100644 --- a/hotspot/src/share/vm/opto/memnode.cpp +++ b/hotspot/src/share/vm/opto/memnode.cpp @@ -1259,15 +1259,18 @@ Node *LoadNode::split_through_phi(PhaseGVN *phase) { return NULL; // Wait stable graph } uint cnt = mem->req(); - for( uint i = 1; i < cnt; i++ ) { + for (uint i = 1; i < cnt; i++) { + Node* rc = region->in(i); + if (rc == NULL || phase->type(rc) == Type::TOP) + return NULL; // Wait stable graph Node *in = mem->in(i); - if( in == NULL ) { + if (in == NULL) { return NULL; // Wait stable graph } } // Check for loop invariant. if (cnt == 3) { - for( uint i = 1; i < cnt; i++ ) { + for (uint i = 1; i < cnt; i++) { Node *in = mem->in(i); Node* m = MemNode::optimize_memory_chain(in, addr_t, phase); if (m == mem) { @@ -1281,38 +1284,37 @@ Node *LoadNode::split_through_phi(PhaseGVN *phase) { // Do nothing here if Identity will find a value // (to avoid infinite chain of value phis generation). - if ( !phase->eqv(this, this->Identity(phase)) ) + if (!phase->eqv(this, this->Identity(phase))) return NULL; // Skip the split if the region dominates some control edge of the address. - if (cnt == 3 && !MemNode::all_controls_dominate(address, region)) + if (!MemNode::all_controls_dominate(address, region)) return NULL; const Type* this_type = this->bottom_type(); int this_index = phase->C->get_alias_index(addr_t); int this_offset = addr_t->offset(); int this_iid = addr_t->is_oopptr()->instance_id(); - int wins = 0; PhaseIterGVN *igvn = phase->is_IterGVN(); Node *phi = new (igvn->C, region->req()) PhiNode(region, this_type, NULL, this_iid, this_index, this_offset); - for( uint i = 1; i < region->req(); i++ ) { + for (uint i = 1; i < region->req(); i++) { Node *x; Node* the_clone = NULL; - if( region->in(i) == phase->C->top() ) { + if (region->in(i) == phase->C->top()) { x = phase->C->top(); // Dead path? Use a dead data op } else { x = this->clone(); // Else clone up the data op the_clone = x; // Remember for possible deletion. // Alter data node to use pre-phi inputs - if( this->in(0) == region ) { - x->set_req( 0, region->in(i) ); + if (this->in(0) == region) { + x->set_req(0, region->in(i)); } else { - x->set_req( 0, NULL ); + x->set_req(0, NULL); } - for( uint j = 1; j < this->req(); j++ ) { + for (uint j = 1; j < this->req(); j++) { Node *in = this->in(j); - if( in->is_Phi() && in->in(0) == region ) - x->set_req( j, in->in(i) ); // Use pre-Phi input for the clone + if (in->is_Phi() && in->in(0) == region) + x->set_req(j, in->in(i)); // Use pre-Phi input for the clone } } // Check for a 'win' on some paths @@ -1321,12 +1323,11 @@ Node *LoadNode::split_through_phi(PhaseGVN *phase) { bool singleton = t->singleton(); // See comments in PhaseIdealLoop::split_thru_phi(). - if( singleton && t == Type::TOP ) { + if (singleton && t == Type::TOP) { singleton &= region->is_Loop() && (i != LoopNode::EntryControl); } - if( singleton ) { - wins++; + if (singleton) { x = igvn->makecon(t); } else { // We now call Identity to try to simplify the cloned node. @@ -1340,13 +1341,11 @@ Node *LoadNode::split_through_phi(PhaseGVN *phase) { // igvn->type(x) is set to x->Value() already. x->raise_bottom_type(t); Node *y = x->Identity(igvn); - if( y != x ) { - wins++; + if (y != x) { x = y; } else { y = igvn->hash_find(x); - if( y ) { - wins++; + if (y) { x = y; } else { // Else x is a new node we are keeping @@ -1360,13 +1359,9 @@ Node *LoadNode::split_through_phi(PhaseGVN *phase) { igvn->remove_dead_node(the_clone); phi->set_req(i, x); } - if( wins > 0 ) { - // Record Phi - igvn->register_new_node_with_optimizer(phi); - return phi; - } - igvn->remove_dead_node(phi); - return NULL; + // Record Phi + igvn->register_new_node_with_optimizer(phi); + return phi; } //------------------------------Ideal------------------------------------------ @@ -1677,14 +1672,15 @@ const Type *LoadNode::Value( PhaseTransform *phase ) const { // If we are loading from a freshly-allocated object, produce a zero, // if the load is provably beyond the header of the object. // (Also allow a variable load from a fresh array to produce zero.) - if (ReduceFieldZeroing) { + const TypeOopPtr *tinst = tp->isa_oopptr(); + bool is_instance = (tinst != NULL) && tinst->is_known_instance_field(); + if (ReduceFieldZeroing || is_instance) { Node* value = can_see_stored_value(mem,phase); if (value != NULL && value->is_Con()) return value->bottom_type(); } - const TypeOopPtr *tinst = tp->isa_oopptr(); - if (tinst != NULL && tinst->is_known_instance_field()) { + if (is_instance) { // If we have an instance type and our memory input is the // programs's initial memory state, there is no matching store, // so just return a zero of the appropriate type From b4d40650b2f38f81ade028db8cb5f17ae7eb940e Mon Sep 17 00:00:00 2001 From: "Y. Srinivas Ramakrishna" Date: Wed, 20 Apr 2011 19:19:30 -0700 Subject: [PATCH 14/80] 7037276: Unnecessary double traversal of dirty card windows Short-circuited an unnecessary double traversal of dirty card windows when iterating younger refs. Also renamed some cardtable methods for more clarity. Reviewed-by: jmasa, stefank, poonam --- .../parNew/parCardTableModRefBS.cpp | 79 ++++---- .../src/share/vm/memory/cardTableModRefBS.cpp | 32 +-- .../src/share/vm/memory/cardTableModRefBS.hpp | 40 ++-- hotspot/src/share/vm/memory/cardTableRS.cpp | 190 +++++++++--------- hotspot/src/share/vm/memory/cardTableRS.hpp | 19 +- 5 files changed, 198 insertions(+), 162 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp b/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp index 58dea49b77f..afc8797ea33 100644 --- a/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp +++ b/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp @@ -33,44 +33,43 @@ #include "runtime/mutexLocker.hpp" #include "runtime/virtualspace.hpp" -void CardTableModRefBS::par_non_clean_card_iterate_work(Space* sp, MemRegion mr, - DirtyCardToOopClosure* dcto_cl, - MemRegionClosure* cl, - int n_threads) { - if (n_threads > 0) { - assert((n_threads == 1 && ParallelGCThreads == 0) || - n_threads <= (int)ParallelGCThreads, - "# worker threads != # requested!"); - // Make sure the LNC array is valid for the space. - jbyte** lowest_non_clean; - uintptr_t lowest_non_clean_base_chunk_index; - size_t lowest_non_clean_chunk_size; - get_LNC_array_for_space(sp, lowest_non_clean, - lowest_non_clean_base_chunk_index, - lowest_non_clean_chunk_size); +void CardTableModRefBS::non_clean_card_iterate_parallel_work(Space* sp, MemRegion mr, + DirtyCardToOopClosure* dcto_cl, + ClearNoncleanCardWrapper* cl, + int n_threads) { + assert(n_threads > 0, "Error: expected n_threads > 0"); + assert((n_threads == 1 && ParallelGCThreads == 0) || + n_threads <= (int)ParallelGCThreads, + "# worker threads != # requested!"); + // Make sure the LNC array is valid for the space. + jbyte** lowest_non_clean; + uintptr_t lowest_non_clean_base_chunk_index; + size_t lowest_non_clean_chunk_size; + get_LNC_array_for_space(sp, lowest_non_clean, + lowest_non_clean_base_chunk_index, + lowest_non_clean_chunk_size); - int n_strides = n_threads * StridesPerThread; - SequentialSubTasksDone* pst = sp->par_seq_tasks(); - pst->set_n_threads(n_threads); - pst->set_n_tasks(n_strides); + int n_strides = n_threads * StridesPerThread; + SequentialSubTasksDone* pst = sp->par_seq_tasks(); + pst->set_n_threads(n_threads); + pst->set_n_tasks(n_strides); - int stride = 0; - while (!pst->is_task_claimed(/* reference */ stride)) { - process_stride(sp, mr, stride, n_strides, dcto_cl, cl, - lowest_non_clean, - lowest_non_clean_base_chunk_index, - lowest_non_clean_chunk_size); - } - if (pst->all_tasks_completed()) { - // Clear lowest_non_clean array for next time. - intptr_t first_chunk_index = addr_to_chunk_index(mr.start()); - uintptr_t last_chunk_index = addr_to_chunk_index(mr.last()); - for (uintptr_t ch = first_chunk_index; ch <= last_chunk_index; ch++) { - intptr_t ind = ch - lowest_non_clean_base_chunk_index; - assert(0 <= ind && ind < (intptr_t)lowest_non_clean_chunk_size, - "Bounds error"); - lowest_non_clean[ind] = NULL; - } + int stride = 0; + while (!pst->is_task_claimed(/* reference */ stride)) { + process_stride(sp, mr, stride, n_strides, dcto_cl, cl, + lowest_non_clean, + lowest_non_clean_base_chunk_index, + lowest_non_clean_chunk_size); + } + if (pst->all_tasks_completed()) { + // Clear lowest_non_clean array for next time. + intptr_t first_chunk_index = addr_to_chunk_index(mr.start()); + uintptr_t last_chunk_index = addr_to_chunk_index(mr.last()); + for (uintptr_t ch = first_chunk_index; ch <= last_chunk_index; ch++) { + intptr_t ind = ch - lowest_non_clean_base_chunk_index; + assert(0 <= ind && ind < (intptr_t)lowest_non_clean_chunk_size, + "Bounds error"); + lowest_non_clean[ind] = NULL; } } } @@ -81,7 +80,7 @@ process_stride(Space* sp, MemRegion used, jint stride, int n_strides, DirtyCardToOopClosure* dcto_cl, - MemRegionClosure* cl, + ClearNoncleanCardWrapper* cl, jbyte** lowest_non_clean, uintptr_t lowest_non_clean_base_chunk_index, size_t lowest_non_clean_chunk_size) { @@ -127,7 +126,11 @@ process_stride(Space* sp, lowest_non_clean_base_chunk_index, lowest_non_clean_chunk_size); - non_clean_card_iterate_work(chunk_mr, cl); + // We do not call the non_clean_card_iterate_serial() version because + // we want to clear the cards, and the ClearNoncleanCardWrapper closure + // itself does the work of finding contiguous dirty ranges of cards to + // process (and clear). + cl->do_MemRegion(chunk_mr); // Find the next chunk of the stride. chunk_card_start += CardsPerStrideChunk * n_strides; diff --git a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp index 0f221653985..abdd31bdb27 100644 --- a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp +++ b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp @@ -456,31 +456,35 @@ bool CardTableModRefBS::mark_card_deferred(size_t card_index) { } -void CardTableModRefBS::non_clean_card_iterate(Space* sp, - MemRegion mr, - DirtyCardToOopClosure* dcto_cl, - MemRegionClosure* cl) { +void CardTableModRefBS::non_clean_card_iterate_possibly_parallel(Space* sp, + MemRegion mr, + DirtyCardToOopClosure* dcto_cl, + ClearNoncleanCardWrapper* cl) { if (!mr.is_empty()) { int n_threads = SharedHeap::heap()->n_par_threads(); if (n_threads > 0) { #ifndef SERIALGC - par_non_clean_card_iterate_work(sp, mr, dcto_cl, cl, n_threads); + non_clean_card_iterate_parallel_work(sp, mr, dcto_cl, cl, n_threads); #else // SERIALGC fatal("Parallel gc not supported here."); #endif // SERIALGC } else { - non_clean_card_iterate_work(mr, cl); + // We do not call the non_clean_card_iterate_serial() version below because + // we want to clear the cards (which non_clean_card_iterate_serial() does not + // do for us), and the ClearNoncleanCardWrapper closure itself does the work + // of finding contiguous dirty ranges of cards to process (and clear). + cl->do_MemRegion(mr); } } } -// NOTE: For this to work correctly, it is important that -// we look for non-clean cards below (so as to catch those -// marked precleaned), rather than look explicitly for dirty -// cards (and miss those marked precleaned). In that sense, -// the name precleaned is currently somewhat of a misnomer. -void CardTableModRefBS::non_clean_card_iterate_work(MemRegion mr, - MemRegionClosure* cl) { +// The iterator itself is not MT-aware, but +// MT-aware callers and closures can use this to +// accomplish dirty card iteration in parallel. The +// iterator itself does not clear the dirty cards, or +// change their values in any manner. +void CardTableModRefBS::non_clean_card_iterate_serial(MemRegion mr, + MemRegionClosure* cl) { for (int i = 0; i < _cur_covered_regions; i++) { MemRegion mri = mr.intersection(_covered[i]); if (mri.word_size() > 0) { @@ -661,7 +665,7 @@ public: void CardTableModRefBS::verify_clean_region(MemRegion mr) { GuaranteeNotModClosure blk(this); - non_clean_card_iterate_work(mr, &blk); + non_clean_card_iterate_serial(mr, &blk); } // To verify a MemRegion is entirely dirty this closure is passed to diff --git a/hotspot/src/share/vm/memory/cardTableModRefBS.hpp b/hotspot/src/share/vm/memory/cardTableModRefBS.hpp index 833a67109b2..770a8e578cc 100644 --- a/hotspot/src/share/vm/memory/cardTableModRefBS.hpp +++ b/hotspot/src/share/vm/memory/cardTableModRefBS.hpp @@ -44,6 +44,7 @@ class Generation; class OopsInGenClosure; class DirtyCardToOopClosure; +class ClearNoncleanCardWrapper; class CardTableModRefBS: public ModRefBarrierSet { // Some classes get to look at some private stuff. @@ -165,22 +166,28 @@ class CardTableModRefBS: public ModRefBarrierSet { // Iterate over the portion of the card-table which covers the given // region mr in the given space and apply cl to any dirty sub-regions - // of mr. cl and dcto_cl must either be the same closure or cl must - // wrap dcto_cl. Both are required - neither may be NULL. Also, dcto_cl - // may be modified. Note that this function will operate in a parallel - // mode if worker threads are available. - void non_clean_card_iterate(Space* sp, MemRegion mr, - DirtyCardToOopClosure* dcto_cl, - MemRegionClosure* cl); + // of mr. Dirty cards are _not_ cleared by the iterator method itself, + // but closures may arrange to do so on their own should they so wish. + void non_clean_card_iterate_serial(MemRegion mr, MemRegionClosure* cl); - // Utility function used to implement the other versions below. - void non_clean_card_iterate_work(MemRegion mr, MemRegionClosure* cl); + // A variant of the above that will operate in a parallel mode if + // worker threads are available, and clear the dirty cards as it + // processes them. + // ClearNoncleanCardWrapper cl must wrap the DirtyCardToOopClosure dcto_cl, + // which may itself be modified by the method. + void non_clean_card_iterate_possibly_parallel(Space* sp, MemRegion mr, + DirtyCardToOopClosure* dcto_cl, + ClearNoncleanCardWrapper* cl); - void par_non_clean_card_iterate_work(Space* sp, MemRegion mr, - DirtyCardToOopClosure* dcto_cl, - MemRegionClosure* cl, - int n_threads); + private: + // Work method used to implement non_clean_card_iterate_possibly_parallel() + // above in the parallel case. + void non_clean_card_iterate_parallel_work(Space* sp, MemRegion mr, + DirtyCardToOopClosure* dcto_cl, + ClearNoncleanCardWrapper* cl, + int n_threads); + protected: // Dirty the bytes corresponding to "mr" (not all of which must be // covered.) void dirty_MemRegion(MemRegion mr); @@ -237,7 +244,7 @@ class CardTableModRefBS: public ModRefBarrierSet { MemRegion used, jint stride, int n_strides, DirtyCardToOopClosure* dcto_cl, - MemRegionClosure* cl, + ClearNoncleanCardWrapper* cl, jbyte** lowest_non_clean, uintptr_t lowest_non_clean_base_chunk_index, size_t lowest_non_clean_chunk_size); @@ -409,14 +416,14 @@ public: // marking, where a dirty card may cause scanning, and summarization // marking, of objects that extend onto subsequent cards.) void mod_card_iterate(MemRegionClosure* cl) { - non_clean_card_iterate_work(_whole_heap, cl); + non_clean_card_iterate_serial(_whole_heap, cl); } // Like the "mod_cards_iterate" above, except only invokes the closure // for cards within the MemRegion "mr" (which is required to be // card-aligned and sized.) void mod_card_iterate(MemRegion mr, MemRegionClosure* cl) { - non_clean_card_iterate_work(mr, cl); + non_clean_card_iterate_serial(mr, cl); } static uintx ct_max_alignment_constraint(); @@ -493,4 +500,5 @@ public: void set_CTRS(CardTableRS* rs) { _rs = rs; } }; + #endif // SHARE_VM_MEMORY_CARDTABLEMODREFBS_HPP diff --git a/hotspot/src/share/vm/memory/cardTableRS.cpp b/hotspot/src/share/vm/memory/cardTableRS.cpp index 3f8b46a4b5f..4a22ba73a21 100644 --- a/hotspot/src/share/vm/memory/cardTableRS.cpp +++ b/hotspot/src/share/vm/memory/cardTableRS.cpp @@ -105,107 +105,111 @@ void CardTableRS::younger_refs_iterate(Generation* g, g->younger_refs_iterate(blk); } -class ClearNoncleanCardWrapper: public MemRegionClosure { - MemRegionClosure* _dirty_card_closure; - CardTableRS* _ct; - bool _is_par; -private: - // Clears the given card, return true if the corresponding card should be - // processed. - bool clear_card(jbyte* entry) { - if (_is_par) { - while (true) { - // In the parallel case, we may have to do this several times. - jbyte entry_val = *entry; - assert(entry_val != CardTableRS::clean_card_val(), - "We shouldn't be looking at clean cards, and this should " - "be the only place they get cleaned."); - if (CardTableRS::card_is_dirty_wrt_gen_iter(entry_val) - || _ct->is_prev_youngergen_card_val(entry_val)) { - jbyte res = - Atomic::cmpxchg(CardTableRS::clean_card_val(), entry, entry_val); - if (res == entry_val) { - break; - } else { - assert(res == CardTableRS::cur_youngergen_and_prev_nonclean_card, - "The CAS above should only fail if another thread did " - "a GC write barrier."); - } - } else if (entry_val == - CardTableRS::cur_youngergen_and_prev_nonclean_card) { - // Parallelism shouldn't matter in this case. Only the thread - // assigned to scan the card should change this value. - *entry = _ct->cur_youngergen_card_val(); - break; - } else { - assert(entry_val == _ct->cur_youngergen_card_val(), - "Should be the only possibility."); - // In this case, the card was clean before, and become - // cur_youngergen only because of processing of a promoted object. - // We don't have to look at the card. - return false; - } +inline bool ClearNoncleanCardWrapper::clear_card(jbyte* entry) { + if (_is_par) { + return clear_card_parallel(entry); + } else { + return clear_card_serial(entry); + } +} + +inline bool ClearNoncleanCardWrapper::clear_card_parallel(jbyte* entry) { + while (true) { + // In the parallel case, we may have to do this several times. + jbyte entry_val = *entry; + assert(entry_val != CardTableRS::clean_card_val(), + "We shouldn't be looking at clean cards, and this should " + "be the only place they get cleaned."); + if (CardTableRS::card_is_dirty_wrt_gen_iter(entry_val) + || _ct->is_prev_youngergen_card_val(entry_val)) { + jbyte res = + Atomic::cmpxchg(CardTableRS::clean_card_val(), entry, entry_val); + if (res == entry_val) { + break; + } else { + assert(res == CardTableRS::cur_youngergen_and_prev_nonclean_card, + "The CAS above should only fail if another thread did " + "a GC write barrier."); } - return true; + } else if (entry_val == + CardTableRS::cur_youngergen_and_prev_nonclean_card) { + // Parallelism shouldn't matter in this case. Only the thread + // assigned to scan the card should change this value. + *entry = _ct->cur_youngergen_card_val(); + break; } else { - jbyte entry_val = *entry; - assert(entry_val != CardTableRS::clean_card_val(), - "We shouldn't be looking at clean cards, and this should " - "be the only place they get cleaned."); - assert(entry_val != CardTableRS::cur_youngergen_and_prev_nonclean_card, - "This should be possible in the sequential case."); - *entry = CardTableRS::clean_card_val(); - return true; + assert(entry_val == _ct->cur_youngergen_card_val(), + "Should be the only possibility."); + // In this case, the card was clean before, and become + // cur_youngergen only because of processing of a promoted object. + // We don't have to look at the card. + return false; } } + return true; +} -public: - ClearNoncleanCardWrapper(MemRegionClosure* dirty_card_closure, - CardTableRS* ct) : + +inline bool ClearNoncleanCardWrapper::clear_card_serial(jbyte* entry) { + jbyte entry_val = *entry; + assert(entry_val != CardTableRS::clean_card_val(), + "We shouldn't be looking at clean cards, and this should " + "be the only place they get cleaned."); + assert(entry_val != CardTableRS::cur_youngergen_and_prev_nonclean_card, + "This should be possible in the sequential case."); + *entry = CardTableRS::clean_card_val(); + return true; +} + +ClearNoncleanCardWrapper::ClearNoncleanCardWrapper( + MemRegionClosure* dirty_card_closure, CardTableRS* ct) : _dirty_card_closure(dirty_card_closure), _ct(ct) { _is_par = (SharedHeap::heap()->n_par_threads() > 0); - } - void do_MemRegion(MemRegion mr) { - // We start at the high end of "mr", walking backwards - // while accumulating a contiguous dirty range of cards in - // [start_of_non_clean, end_of_non_clean) which we then - // process en masse. - HeapWord* end_of_non_clean = mr.end(); - HeapWord* start_of_non_clean = end_of_non_clean; - jbyte* entry = _ct->byte_for(mr.last()); - const jbyte* first_entry = _ct->byte_for(mr.start()); - while (entry >= first_entry) { - HeapWord* cur = _ct->addr_for(entry); - if (!clear_card(entry)) { - // We hit a clean card; process any non-empty - // dirty range accumulated so far. - if (start_of_non_clean < end_of_non_clean) { - MemRegion mr2(start_of_non_clean, end_of_non_clean); - _dirty_card_closure->do_MemRegion(mr2); - } - // Reset the dirty window while continuing to - // look for the next dirty window to process. - end_of_non_clean = cur; - start_of_non_clean = end_of_non_clean; +} + +void ClearNoncleanCardWrapper::do_MemRegion(MemRegion mr) { + assert(mr.word_size() > 0, "Error"); + assert(_ct->is_aligned(mr.start()), "mr.start() should be card aligned"); + // mr.end() may not necessarily be card aligned. + jbyte* cur_entry = _ct->byte_for(mr.last()); + const jbyte* limit = _ct->byte_for(mr.start()); + HeapWord* end_of_non_clean = mr.end(); + HeapWord* start_of_non_clean = end_of_non_clean; + while (cur_entry >= limit) { + HeapWord* cur_hw = _ct->addr_for(cur_entry); + if ((*cur_entry != CardTableRS::clean_card_val()) && clear_card(cur_entry)) { + // Continue the dirty range by opening the + // dirty window one card to the left. + start_of_non_clean = cur_hw; + } else { + // We hit a "clean" card; process any non-empty + // "dirty" range accumulated so far. + if (start_of_non_clean < end_of_non_clean) { + const MemRegion mrd(start_of_non_clean, end_of_non_clean); + _dirty_card_closure->do_MemRegion(mrd); } - // Open the left end of the window one card to the left. - start_of_non_clean = cur; - // Note that "entry" leads "start_of_non_clean" in - // its leftward excursion after this point - // in the loop and, when we hit the left end of "mr", - // will point off of the left end of the card-table - // for "mr". - entry--; - } - // If the first card of "mr" was dirty, we will have - // been left with a dirty window, co-initial with "mr", - // which we now process. - if (start_of_non_clean < end_of_non_clean) { - MemRegion mr2(start_of_non_clean, end_of_non_clean); - _dirty_card_closure->do_MemRegion(mr2); + // Reset the dirty window, while continuing to look + // for the next dirty card that will start a + // new dirty window. + end_of_non_clean = cur_hw; + start_of_non_clean = cur_hw; } + // Note that "cur_entry" leads "start_of_non_clean" in + // its leftward excursion after this point + // in the loop and, when we hit the left end of "mr", + // will point off of the left end of the card-table + // for "mr". + cur_entry--; } -}; + // If the first card of "mr" was dirty, we will have + // been left with a dirty window, co-initial with "mr", + // which we now process. + if (start_of_non_clean < end_of_non_clean) { + const MemRegion mrd(start_of_non_clean, end_of_non_clean); + _dirty_card_closure->do_MemRegion(mrd); + } +} + // clean (by dirty->clean before) ==> cur_younger_gen // dirty ==> cur_youngergen_and_prev_nonclean_card // precleaned ==> cur_youngergen_and_prev_nonclean_card @@ -246,8 +250,8 @@ void CardTableRS::younger_refs_in_space_iterate(Space* sp, cl->gen_boundary()); ClearNoncleanCardWrapper clear_cl(dcto_cl, this); - _ct_bs->non_clean_card_iterate(sp, sp->used_region_at_save_marks(), - dcto_cl, &clear_cl); + _ct_bs->non_clean_card_iterate_possibly_parallel(sp, sp->used_region_at_save_marks(), + dcto_cl, &clear_cl); } void CardTableRS::clear_into_younger(Generation* gen, bool clear_perm) { diff --git a/hotspot/src/share/vm/memory/cardTableRS.hpp b/hotspot/src/share/vm/memory/cardTableRS.hpp index 13015488550..72c5dacf83d 100644 --- a/hotspot/src/share/vm/memory/cardTableRS.hpp +++ b/hotspot/src/share/vm/memory/cardTableRS.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2011, 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 @@ -166,4 +166,21 @@ public: }; +class ClearNoncleanCardWrapper: public MemRegionClosure { + MemRegionClosure* _dirty_card_closure; + CardTableRS* _ct; + bool _is_par; +private: + // Clears the given card, return true if the corresponding card should be + // processed. + inline bool clear_card(jbyte* entry); + // Work methods called by the clear_card() + inline bool clear_card_serial(jbyte* entry); + inline bool clear_card_parallel(jbyte* entry); + +public: + ClearNoncleanCardWrapper(MemRegionClosure* dirty_card_closure, CardTableRS* ct); + void do_MemRegion(MemRegion mr); +}; + #endif // SHARE_VM_MEMORY_CARDTABLERS_HPP From 868bf68a3e0640e12cb0af432848cd7b75395f50 Mon Sep 17 00:00:00 2001 From: Christian Thalinger Date: Thu, 21 Apr 2011 00:25:40 -0700 Subject: [PATCH 15/80] 6993078: JSR 292 too many pushes: Lesp points into register window Reviewed-by: kvn, never --- .../src/cpu/sparc/vm/templateTable_sparc.cpp | 4 ++-- .../src/cpu/x86/vm/templateTable_x86_32.cpp | 14 ++++++------- .../src/cpu/x86/vm/templateTable_x86_64.cpp | 13 ++++++------ hotspot/src/share/vm/ci/ciEnv.cpp | 4 ++-- hotspot/src/share/vm/oops/cpCacheOop.cpp | 20 ++++++++++--------- 5 files changed, 28 insertions(+), 27 deletions(-) diff --git a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp index 9f4bcc6b4d6..85c34513fca 100644 --- a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp @@ -3289,8 +3289,6 @@ void TemplateTable::invokedynamic(int byte_no) { /*virtual*/ false, /*vfinal*/ false, /*indy*/ true); __ mov(SP, O5_savedSP); // record SP that we wanted the callee to restore - __ verify_oop(G5_callsite); - // profile this call __ profile_call(O4); @@ -3303,8 +3301,10 @@ void TemplateTable::invokedynamic(int byte_no) { __ sll(Rret, LogBytesPerWord, Rret); __ ld_ptr(Rtemp, Rret, Rret); // get return address + __ verify_oop(G5_callsite); __ load_heap_oop(G5_callsite, __ delayed_value(java_lang_invoke_CallSite::target_offset_in_bytes, Rscratch), G3_method_handle); __ null_check(G3_method_handle); + __ verify_oop(G3_method_handle); // Adjust Rret first so Llast_SP can be same as Rret __ add(Rret, -frame::pc_return_offset, O7); diff --git a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp index 483660826ac..a1aa37d7870 100644 --- a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp @@ -3074,6 +3074,7 @@ void TemplateTable::invokeinterface(int byte_no) { void TemplateTable::invokedynamic(int byte_no) { transition(vtos, vtos); + assert(byte_no == f1_oop, "use this argument"); if (!EnableInvokeDynamic) { // We should not encounter this bytecode if !EnableInvokeDynamic. @@ -3086,7 +3087,6 @@ void TemplateTable::invokedynamic(int byte_no) { return; } - assert(byte_no == f1_oop, "use this argument"); prepare_invoke(rax, rbx, byte_no); // rax: CallSite object (f1) @@ -3097,14 +3097,14 @@ void TemplateTable::invokedynamic(int byte_no) { Register rax_callsite = rax; Register rcx_method_handle = rcx; - if (ProfileInterpreter) { - // %%% should make a type profile for any invokedynamic that takes a ref argument - // profile this call - __ profile_call(rsi); - } + // %%% should make a type profile for any invokedynamic that takes a ref argument + // profile this call + __ profile_call(rsi); - __ load_heap_oop(rcx_method_handle, Address(rax_callsite, __ delayed_value(java_lang_invoke_CallSite::target_offset_in_bytes, rcx))); + __ verify_oop(rax_callsite); + __ load_heap_oop(rcx_method_handle, Address(rax_callsite, __ delayed_value(java_lang_invoke_CallSite::target_offset_in_bytes, rdx))); __ null_check(rcx_method_handle); + __ verify_oop(rcx_method_handle); __ prepare_to_jump_from_interpreted(); __ jump_to_method_handle_entry(rcx_method_handle, rdx); } diff --git a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp index e1ec5ad4474..446c23f9de7 100644 --- a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp @@ -3128,7 +3128,6 @@ void TemplateTable::invokedynamic(int byte_no) { return; } - assert(byte_no == f1_oop, "use this argument"); prepare_invoke(rax, rbx, byte_no); // rax: CallSite object (f1) @@ -3139,14 +3138,14 @@ void TemplateTable::invokedynamic(int byte_no) { Register rax_callsite = rax; Register rcx_method_handle = rcx; - if (ProfileInterpreter) { - // %%% should make a type profile for any invokedynamic that takes a ref argument - // profile this call - __ profile_call(r13); - } + // %%% should make a type profile for any invokedynamic that takes a ref argument + // profile this call + __ profile_call(r13); - __ load_heap_oop(rcx_method_handle, Address(rax_callsite, __ delayed_value(java_lang_invoke_CallSite::target_offset_in_bytes, rcx))); + __ verify_oop(rax_callsite); + __ load_heap_oop(rcx_method_handle, Address(rax_callsite, __ delayed_value(java_lang_invoke_CallSite::target_offset_in_bytes, rdx))); __ null_check(rcx_method_handle); + __ verify_oop(rcx_method_handle); __ prepare_to_jump_from_interpreted(); __ jump_to_method_handle_entry(rcx_method_handle, rdx); } diff --git a/hotspot/src/share/vm/ci/ciEnv.cpp b/hotspot/src/share/vm/ci/ciEnv.cpp index 66e23490c09..96ff5a0e8e3 100644 --- a/hotspot/src/share/vm/ci/ciEnv.cpp +++ b/hotspot/src/share/vm/ci/ciEnv.cpp @@ -756,7 +756,7 @@ ciMethod* ciEnv::get_fake_invokedynamic_method_impl(constantPoolHandle cpool, assert(bc == Bytecodes::_invokedynamic, "must be invokedynamic"); bool is_resolved = cpool->cache()->main_entry_at(index)->is_resolved(bc); - if (is_resolved && (oop) cpool->cache()->secondary_entry_at(index)->f1() == NULL) + if (is_resolved && cpool->cache()->secondary_entry_at(index)->is_f1_null()) // FIXME: code generation could allow for null (unlinked) call site is_resolved = false; @@ -770,7 +770,7 @@ ciMethod* ciEnv::get_fake_invokedynamic_method_impl(constantPoolHandle cpool, // Get the invoker methodOop from the constant pool. oop f1_value = cpool->cache()->main_entry_at(index)->f1(); - methodOop signature_invoker = methodOop(f1_value); + methodOop signature_invoker = (methodOop) f1_value; assert(signature_invoker != NULL && signature_invoker->is_method() && signature_invoker->is_method_handle_invoke(), "correct result from LinkResolver::resolve_invokedynamic"); diff --git a/hotspot/src/share/vm/oops/cpCacheOop.cpp b/hotspot/src/share/vm/oops/cpCacheOop.cpp index 953ac789fee..049247b9d7f 100644 --- a/hotspot/src/share/vm/oops/cpCacheOop.cpp +++ b/hotspot/src/share/vm/oops/cpCacheOop.cpp @@ -104,7 +104,7 @@ void ConstantPoolCacheEntry::set_f1_if_null_atomic(oop f1) { void* result = Atomic::cmpxchg_ptr(f1, f1_addr, NULL); bool success = (result == NULL); if (success) { - update_barrier_set(f1_addr, f1); + update_barrier_set((void*) f1_addr, f1); } } @@ -275,21 +275,23 @@ int ConstantPoolCacheEntry::bootstrap_method_index_in_cache() { return (int) bsm_cache_index; } -void ConstantPoolCacheEntry::set_dynamic_call(Handle call_site, - methodHandle signature_invoker) { +void ConstantPoolCacheEntry::set_dynamic_call(Handle call_site, methodHandle signature_invoker) { assert(is_secondary_entry(), ""); + // NOTE: it's important that all other values are set before f1 is + // set since some users short circuit on f1 being set + // (i.e. non-null) and that may result in uninitialized values for + // other racing threads (e.g. flags). int param_size = signature_invoker->size_of_parameters(); assert(param_size >= 1, "method argument size must include MH.this"); - param_size -= 1; // do not count MH.this; it is not stacked for invokedynamic - if (Atomic::cmpxchg_ptr(call_site(), &_f1, NULL) == NULL) { - // racing threads might be trying to install their own favorites - set_f1(call_site()); - } + param_size -= 1; // do not count MH.this; it is not stacked for invokedynamic bool is_final = true; assert(signature_invoker->is_final_method(), "is_final"); - set_flags(as_flags(as_TosState(signature_invoker->result_type()), is_final, false, false, false, true) | param_size); + int flags = as_flags(as_TosState(signature_invoker->result_type()), is_final, false, false, false, true) | param_size; + assert(_flags == 0 || _flags == flags, "flags should be the same"); + set_flags(flags); // do not do set_bytecode on a secondary CP cache entry //set_bytecode_1(Bytecodes::_invokedynamic); + set_f1_if_null_atomic(call_site()); // This must be the last one to set (see NOTE above)! } From 90df638cdcc3f7651ba244ee0c7c16b2701f310b Mon Sep 17 00:00:00 2001 From: Pavel Porvatov Date: Thu, 21 Apr 2011 14:29:23 +0400 Subject: [PATCH 16/80] 7021058: The Create folder button produces error in the Details mode (JFileChooser) Reviewed-by: malenkov --- jdk/src/share/classes/sun/swing/FilePane.java | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/jdk/src/share/classes/sun/swing/FilePane.java b/jdk/src/share/classes/sun/swing/FilePane.java index a5e7dffda32..5bf5c1f43b0 100644 --- a/jdk/src/share/classes/sun/swing/FilePane.java +++ b/jdk/src/share/classes/sun/swing/FilePane.java @@ -763,7 +763,7 @@ public class FilePane extends JPanel implements PropertyChangeListener { public void setValueAt(Object value, int row, int col) { if (col == COLUMN_FILENAME) { - JFileChooser chooser = getFileChooser(); + final JFileChooser chooser = getFileChooser(); File f = (File)getValueAt(row, col); if (f != null) { String oldDisplayName = chooser.getName(f); @@ -782,18 +782,25 @@ public class FilePane extends JPanel implements PropertyChangeListener { // rename FileSystemView fsv = chooser.getFileSystemView(); - File f2 = fsv.createFileObject(f.getParentFile(), newFileName); + final File f2 = fsv.createFileObject(f.getParentFile(), newFileName); if (f2.exists()) { JOptionPane.showMessageDialog(chooser, MessageFormat.format(renameErrorFileExistsText, oldFileName), renameErrorTitleText, JOptionPane.ERROR_MESSAGE); } else { if (FilePane.this.getModel().renameFile(f, f2)) { if (fsv.isParent(chooser.getCurrentDirectory(), f2)) { - if (chooser.isMultiSelectionEnabled()) { - chooser.setSelectedFiles(new File[]{f2}); - } else { - chooser.setSelectedFile(f2); - } + // The setSelectedFile method produces a new setValueAt invocation while the JTable + // is editing. Postpone file selection to be sure that edit mode of the JTable + // is completed + SwingUtilities.invokeLater(new Runnable() { + public void run() { + if (chooser.isMultiSelectionEnabled()) { + chooser.setSelectedFiles(new File[]{f2}); + } else { + chooser.setSelectedFile(f2); + } + } + }); } else { // Could be because of delay in updating Desktop folder // chooser.setSelectedFile(null); From 6663052a885feb41704d0463ddc986c9a02f53bc Mon Sep 17 00:00:00 2001 From: Jon Masamitsu Date: Thu, 21 Apr 2011 10:23:44 -0700 Subject: [PATCH 17/80] 6946417: G1: Java VisualVM does not support G1 properly Added counters for jstat Reviewed-by: tonyp, jwilhelm, stefank, ysr, johnc --- .../gc_implementation/g1/g1CollectedHeap.cpp | 10 + .../gc_implementation/g1/g1CollectedHeap.hpp | 9 + .../g1/g1MonitoringSupport.cpp | 178 +++++++++++++++ .../g1/g1MonitoringSupport.hpp | 203 ++++++++++++++++++ .../shared/generationCounters.cpp | 7 +- .../shared/generationCounters.hpp | 7 +- .../shared/hSpaceCounters.cpp | 66 ++++++ .../shared/hSpaceCounters.hpp | 87 ++++++++ .../src/share/vm/services/g1MemoryPool.cpp | 37 +--- .../src/share/vm/services/g1MemoryPool.hpp | 88 +------- 10 files changed, 575 insertions(+), 117 deletions(-) create mode 100644 hotspot/src/share/vm/gc_implementation/g1/g1MonitoringSupport.cpp create mode 100644 hotspot/src/share/vm/gc_implementation/g1/g1MonitoringSupport.hpp create mode 100644 hotspot/src/share/vm/gc_implementation/shared/hSpaceCounters.cpp create mode 100644 hotspot/src/share/vm/gc_implementation/shared/hSpaceCounters.hpp diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index becc9451265..d8a9c07f522 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -1161,6 +1161,7 @@ bool G1CollectedHeap::do_collection(bool explicit_gc, TraceTime t(system_gc ? "Full GC (System.gc())" : "Full GC", PrintGC, true, gclog_or_tty); + TraceCollectorStats tcs(g1mm()->full_collection_counters()); TraceMemoryManagerStats tms(true /* fullGC */); double start = os::elapsedTime(); @@ -1339,6 +1340,7 @@ bool G1CollectedHeap::do_collection(bool explicit_gc, if (PrintHeapAtGC) { Universe::print_heap_after_gc(); } + g1mm()->update_counters(); return true; } @@ -1971,6 +1973,10 @@ jint G1CollectedHeap::initialize() { init_mutator_alloc_region(); + // Do create of the monitoring and management support so that + // values in the heap have been properly initialized. + _g1mm = new G1MonitoringSupport(this, &_g1_storage); + return JNI_OK; } @@ -3186,6 +3192,7 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) { TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); TraceTime t(verbose_str, PrintGC && !PrintGCDetails, true, gclog_or_tty); + TraceCollectorStats tcs(g1mm()->incremental_collection_counters()); TraceMemoryManagerStats tms(false /* fullGC */); // If the secondary_free_list is not empty, append it to the @@ -3425,6 +3432,8 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) { if (PrintHeapAtGC) { Universe::print_heap_after_gc(); } + g1mm()->update_counters(); + if (G1SummarizeRSetStats && (G1SummarizeRSetStatsPeriod > 0) && (total_collections() % G1SummarizeRSetStatsPeriod == 0)) { @@ -5338,6 +5347,7 @@ HeapRegion* G1CollectedHeap::new_mutator_alloc_region(size_t word_size, if (new_alloc_region != NULL) { g1_policy()->update_region_num(true /* next_is_young */); set_region_short_lived_locked(new_alloc_region); + g1mm()->update_eden_counters(); return new_alloc_region; } } diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp index 1b7e6a307bc..7c318a577b5 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp @@ -28,7 +28,9 @@ #include "gc_implementation/g1/concurrentMark.hpp" #include "gc_implementation/g1/g1AllocRegion.hpp" #include "gc_implementation/g1/g1RemSet.hpp" +#include "gc_implementation/g1/g1MonitoringSupport.hpp" #include "gc_implementation/g1/heapRegionSets.hpp" +#include "gc_implementation/shared/hSpaceCounters.hpp" #include "gc_implementation/parNew/parGCAllocBuffer.hpp" #include "memory/barrierSet.hpp" #include "memory/memRegion.hpp" @@ -57,6 +59,7 @@ class HeapRegionRemSetIterator; class ConcurrentMark; class ConcurrentMarkThread; class ConcurrentG1Refine; +class GenerationCounters; typedef OverflowTaskQueue RefToScanQueue; typedef GenericTaskQueueSet RefToScanQueueSet; @@ -236,6 +239,9 @@ private: // current collection. HeapRegion* _gc_alloc_region_list; + // Helper for monitoring and management support. + G1MonitoringSupport* _g1mm; + // Determines PLAB size for a particular allocation purpose. static size_t desired_plab_sz(GCAllocPurpose purpose); @@ -550,6 +556,9 @@ protected: HeapWord* expand_and_allocate(size_t word_size); public: + + G1MonitoringSupport* g1mm() { return _g1mm; } + // Expand the garbage-first heap by at least the given size (in bytes!). // Returns true if the heap was expanded by the requested amount; // false otherwise. diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1MonitoringSupport.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1MonitoringSupport.cpp new file mode 100644 index 00000000000..aab16dba661 --- /dev/null +++ b/hotspot/src/share/vm/gc_implementation/g1/g1MonitoringSupport.cpp @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2011, 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. + * + */ + +#include "precompiled.hpp" +#include "gc_implementation/g1/g1MonitoringSupport.hpp" +#include "gc_implementation/g1/g1CollectedHeap.inline.hpp" +#include "gc_implementation/g1/g1CollectorPolicy.hpp" + +G1MonitoringSupport::G1MonitoringSupport(G1CollectedHeap* g1h, + VirtualSpace* g1_storage_addr) : + _g1h(g1h), + _incremental_collection_counters(NULL), + _full_collection_counters(NULL), + _non_young_collection_counters(NULL), + _old_space_counters(NULL), + _young_collection_counters(NULL), + _eden_counters(NULL), + _from_counters(NULL), + _to_counters(NULL), + _g1_storage_addr(g1_storage_addr) +{ + // Counters for GC collections + // + // name "collector.0". In a generational collector this would be the + // young generation collection. + _incremental_collection_counters = + new CollectorCounters("G1 incremental collections", 0); + // name "collector.1". In a generational collector this would be the + // old generation collection. + _full_collection_counters = + new CollectorCounters("G1 stop-the-world full collections", 1); + + // timer sampling for all counters supporting sampling only update the + // used value. See the take_sample() method. G1 requires both used and + // capacity updated so sampling is not currently used. It might + // be sufficient to update all counters in take_sample() even though + // take_sample() only returns "used". When sampling was used, there + // were some anomolous values emitted which may have been the consequence + // of not updating all values simultaneously (i.e., see the calculation done + // in eden_space_used(), is it possbile that the values used to + // calculate either eden_used or survivor_used are being updated by + // the collector when the sample is being done?). + const bool sampled = false; + + // "Generation" and "Space" counters. + // + // name "generation.1" This is logically the old generation in + // generational GC terms. The "1, 1" parameters are for + // the n-th generation (=1) with 1 space. + // Counters are created from minCapacity, maxCapacity, and capacity + _non_young_collection_counters = + new GenerationCounters("whole heap", 1, 1, _g1_storage_addr); + + // name "generation.1.space.0" + // Counters are created from maxCapacity, capacity, initCapacity, + // and used. + _old_space_counters = new HSpaceCounters("space", 0, + _g1h->max_capacity(), _g1h->capacity(), _non_young_collection_counters); + + // Young collection set + // name "generation.0". This is logically the young generation. + // The "0, 3" are paremeters for the n-th genertaion (=0) with 3 spaces. + // See _non_young_collection_counters for additional counters + _young_collection_counters = new GenerationCounters("young", 0, 3, NULL); + + // Replace "max_heap_byte_size() with maximum young gen size for + // g1Collectedheap + // name "generation.0.space.0" + // See _old_space_counters for additional counters + _eden_counters = new HSpaceCounters("eden", 0, + _g1h->max_capacity(), eden_space_committed(), + _young_collection_counters); + + // name "generation.0.space.1" + // See _old_space_counters for additional counters + // Set the arguments to indicate that this survivor space is not used. + _from_counters = new HSpaceCounters("s0", 1, (long) 0, (long) 0, + _young_collection_counters); + + // name "generation.0.space.2" + // See _old_space_counters for additional counters + _to_counters = new HSpaceCounters("s1", 2, + _g1h->max_capacity(), + survivor_space_committed(), + _young_collection_counters); +} + +size_t G1MonitoringSupport::overall_committed() { + return g1h()->capacity(); +} + +size_t G1MonitoringSupport::overall_used() { + return g1h()->used_unlocked(); +} + +size_t G1MonitoringSupport::eden_space_committed() { + return MAX2(eden_space_used(), (size_t) HeapRegion::GrainBytes); +} + +size_t G1MonitoringSupport::eden_space_used() { + size_t young_list_length = g1h()->young_list()->length(); + size_t eden_used = young_list_length * HeapRegion::GrainBytes; + size_t survivor_used = survivor_space_used(); + eden_used = subtract_up_to_zero(eden_used, survivor_used); + return eden_used; +} + +size_t G1MonitoringSupport::survivor_space_committed() { + return MAX2(survivor_space_used(), + (size_t) HeapRegion::GrainBytes); +} + +size_t G1MonitoringSupport::survivor_space_used() { + size_t survivor_num = g1h()->g1_policy()->recorded_survivor_regions(); + size_t survivor_used = survivor_num * HeapRegion::GrainBytes; + return survivor_used; +} + +size_t G1MonitoringSupport::old_space_committed() { + size_t committed = overall_committed(); + size_t eden_committed = eden_space_committed(); + size_t survivor_committed = survivor_space_committed(); + committed = subtract_up_to_zero(committed, eden_committed); + committed = subtract_up_to_zero(committed, survivor_committed); + committed = MAX2(committed, (size_t) HeapRegion::GrainBytes); + return committed; +} + +// See the comment near the top of g1MonitoringSupport.hpp for +// an explanation of these calculations for "used" and "capacity". +size_t G1MonitoringSupport::old_space_used() { + size_t used = overall_used(); + size_t eden_used = eden_space_used(); + size_t survivor_used = survivor_space_used(); + used = subtract_up_to_zero(used, eden_used); + used = subtract_up_to_zero(used, survivor_used); + return used; +} + +void G1MonitoringSupport::update_counters() { + if (UsePerfData) { + eden_counters()->update_capacity(eden_space_committed()); + eden_counters()->update_used(eden_space_used()); + to_counters()->update_capacity(survivor_space_committed()); + to_counters()->update_used(survivor_space_used()); + old_space_counters()->update_capacity(old_space_committed()); + old_space_counters()->update_used(old_space_used()); + non_young_collection_counters()->update_all(); + } +} + +void G1MonitoringSupport::update_eden_counters() { + if (UsePerfData) { + eden_counters()->update_capacity(eden_space_committed()); + eden_counters()->update_used(eden_space_used()); + } +} diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1MonitoringSupport.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1MonitoringSupport.hpp new file mode 100644 index 00000000000..61de266fe5f --- /dev/null +++ b/hotspot/src/share/vm/gc_implementation/g1/g1MonitoringSupport.hpp @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2011, 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_GC_IMPLEMENTATION_G1_G1MONITORINGSUPPORT_HPP +#define SHARE_VM_GC_IMPLEMENTATION_G1_G1MONITORINGSUPPORT_HPP + +#include "gc_implementation/shared/hSpaceCounters.hpp" + +class G1CollectedHeap; +class G1SpaceMonitoringSupport; + +// Class for monitoring logical spaces in G1. +// G1 defines a set of regions as a young +// collection (analogous to a young generation). +// The young collection is a logical generation +// with no fixed chunk (see space.hpp) reflecting +// the address space for the generation. In addition +// to the young collection there is its complement +// the non-young collection that is simply the regions +// not in the young collection. The non-young collection +// is treated here as a logical old generation only +// because the monitoring tools expect a generational +// heap. The monitoring tools expect that a Space +// (see space.hpp) exists that describe the +// address space of young collection and non-young +// collection and such a view is provided here. +// +// This class provides interfaces to access +// the value of variables for the young collection +// that include the "capacity" and "used" of the +// young collection along with constant values +// for the minimum and maximum capacities for +// the logical spaces. Similarly for the non-young +// collection. +// +// Also provided are counters for G1 concurrent collections +// and stop-the-world full heap collecitons. +// +// Below is a description of how "used" and "capactiy" +// (or committed) is calculated for the logical spaces. +// +// 1) The used space calculation for a pool is not necessarily +// independent of the others. We can easily get from G1 the overall +// used space in the entire heap, the number of regions in the young +// generation (includes both eden and survivors), and the number of +// survivor regions. So, from that we calculate: +// +// survivor_used = survivor_num * region_size +// eden_used = young_region_num * region_size - survivor_used +// old_gen_used = overall_used - eden_used - survivor_used +// +// Note that survivor_used and eden_used are upper bounds. To get the +// actual value we would have to iterate over the regions and add up +// ->used(). But that'd be expensive. So, we'll accept some lack of +// accuracy for those two. But, we have to be careful when calculating +// old_gen_used, in case we subtract from overall_used more then the +// actual number and our result goes negative. +// +// 2) Calculating the used space is straightforward, as described +// above. However, how do we calculate the committed space, given that +// we allocate space for the eden, survivor, and old gen out of the +// same pool of regions? One way to do this is to use the used value +// as also the committed value for the eden and survivor spaces and +// then calculate the old gen committed space as follows: +// +// old_gen_committed = overall_committed - eden_committed - survivor_committed +// +// Maybe a better way to do that would be to calculate used for eden +// and survivor as a sum of ->used() over their regions and then +// calculate committed as region_num * region_size (i.e., what we use +// to calculate the used space now). This is something to consider +// in the future. +// +// 3) Another decision that is again not straightforward is what is +// the max size that each memory pool can grow to. One way to do this +// would be to use the committed size for the max for the eden and +// survivors and calculate the old gen max as follows (basically, it's +// a similar pattern to what we use for the committed space, as +// described above): +// +// old_gen_max = overall_max - eden_max - survivor_max +// +// Unfortunately, the above makes the max of each pool fluctuate over +// time and, even though this is allowed according to the spec, it +// broke several assumptions in the M&M framework (there were cases +// where used would reach a value greater than max). So, for max we +// use -1, which means "undefined" according to the spec. +// +// 4) Now, there is a very subtle issue with all the above. The +// framework will call get_memory_usage() on the three pools +// asynchronously. As a result, each call might get a different value +// for, say, survivor_num which will yield inconsistent values for +// eden_used, survivor_used, and old_gen_used (as survivor_num is used +// in the calculation of all three). This would normally be +// ok. However, it's possible that this might cause the sum of +// eden_used, survivor_used, and old_gen_used to go over the max heap +// size and this seems to sometimes cause JConsole (and maybe other +// clients) to get confused. There's not a really an easy / clean +// solution to this problem, due to the asynchrounous nature of the +// framework. + +class G1MonitoringSupport : public CHeapObj { + G1CollectedHeap* _g1h; + VirtualSpace* _g1_storage_addr; + + // jstat performance counters + // incremental collections both fully and partially young + CollectorCounters* _incremental_collection_counters; + // full stop-the-world collections + CollectorCounters* _full_collection_counters; + // young collection set counters. The _eden_counters, + // _from_counters, and _to_counters are associated with + // this "generational" counter. + GenerationCounters* _young_collection_counters; + // non-young collection set counters. The _old_space_counters + // below are associated with this "generational" counter. + GenerationCounters* _non_young_collection_counters; + // Counters for the capacity and used for + // the whole heap + HSpaceCounters* _old_space_counters; + // the young collection + HSpaceCounters* _eden_counters; + // the survivor collection (only one, _to_counters, is actively used) + HSpaceCounters* _from_counters; + HSpaceCounters* _to_counters; + + // It returns x - y if x > y, 0 otherwise. + // As described in the comment above, some of the inputs to the + // calculations we have to do are obtained concurrently and hence + // may be inconsistent with each other. So, this provides a + // defensive way of performing the subtraction and avoids the value + // going negative (which would mean a very large result, given that + // the parameter are size_t). + static size_t subtract_up_to_zero(size_t x, size_t y) { + if (x > y) { + return x - y; + } else { + return 0; + } + } + + public: + G1MonitoringSupport(G1CollectedHeap* g1h, VirtualSpace* g1_storage_addr); + + G1CollectedHeap* g1h() { return _g1h; } + VirtualSpace* g1_storage_addr() { return _g1_storage_addr; } + + // Performance Counter accessors + void update_counters(); + void update_eden_counters(); + + CollectorCounters* incremental_collection_counters() { + return _incremental_collection_counters; + } + CollectorCounters* full_collection_counters() { + return _full_collection_counters; + } + GenerationCounters* non_young_collection_counters() { + return _non_young_collection_counters; + } + HSpaceCounters* old_space_counters() { return _old_space_counters; } + HSpaceCounters* eden_counters() { return _eden_counters; } + HSpaceCounters* from_counters() { return _from_counters; } + HSpaceCounters* to_counters() { return _to_counters; } + + // Monitoring support used by + // MemoryService + // jstat counters + size_t overall_committed(); + size_t overall_used(); + + size_t eden_space_committed(); + size_t eden_space_used(); + + size_t survivor_space_committed(); + size_t survivor_space_used(); + + size_t old_space_committed(); + size_t old_space_used(); +}; + +#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1MONITORINGSUPPORT_HPP diff --git a/hotspot/src/share/vm/gc_implementation/shared/generationCounters.cpp b/hotspot/src/share/vm/gc_implementation/shared/generationCounters.cpp index 4548189335c..f07f486e895 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/generationCounters.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/generationCounters.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2011, 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 @@ -51,15 +51,18 @@ GenerationCounters::GenerationCounters(const char* name, cname = PerfDataManager::counter_name(_name_space, "minCapacity"); PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes, + _virtual_space == NULL ? 0 : _virtual_space->committed_size(), CHECK); cname = PerfDataManager::counter_name(_name_space, "maxCapacity"); PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes, + _virtual_space == NULL ? 0 : _virtual_space->reserved_size(), CHECK); cname = PerfDataManager::counter_name(_name_space, "capacity"); _current_size = PerfDataManager::create_variable(SUN_GC, cname, - PerfData::U_Bytes, + PerfData::U_Bytes, + _virtual_space == NULL ? 0 : _virtual_space->committed_size(), CHECK); } } diff --git a/hotspot/src/share/vm/gc_implementation/shared/generationCounters.hpp b/hotspot/src/share/vm/gc_implementation/shared/generationCounters.hpp index 4fd05e493dc..21f76918c17 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/generationCounters.hpp +++ b/hotspot/src/share/vm/gc_implementation/shared/generationCounters.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2011, 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 @@ -61,10 +61,11 @@ class GenerationCounters: public CHeapObj { } virtual void update_all() { - _current_size->set_value(_virtual_space->committed_size()); + _current_size->set_value(_virtual_space == NULL ? 0 : + _virtual_space->committed_size()); } const char* name_space() const { return _name_space; } -}; +}; #endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_GENERATIONCOUNTERS_HPP diff --git a/hotspot/src/share/vm/gc_implementation/shared/hSpaceCounters.cpp b/hotspot/src/share/vm/gc_implementation/shared/hSpaceCounters.cpp new file mode 100644 index 00000000000..17a69fa832e --- /dev/null +++ b/hotspot/src/share/vm/gc_implementation/shared/hSpaceCounters.cpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2011, 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. + * + */ + +#include "precompiled.hpp" +#include "gc_implementation/shared/hSpaceCounters.hpp" +#include "memory/generation.hpp" +#include "memory/resourceArea.hpp" + +HSpaceCounters::HSpaceCounters(const char* name, + int ordinal, + size_t max_size, + size_t initial_capacity, + GenerationCounters* gc) { + + if (UsePerfData) { + EXCEPTION_MARK; + ResourceMark rm; + + const char* cns = + PerfDataManager::name_space(gc->name_space(), "space", ordinal); + + _name_space = NEW_C_HEAP_ARRAY(char, strlen(cns)+1); + strcpy(_name_space, cns); + + const char* cname = PerfDataManager::counter_name(_name_space, "name"); + PerfDataManager::create_string_constant(SUN_GC, cname, name, CHECK); + + cname = PerfDataManager::counter_name(_name_space, "maxCapacity"); + PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes, + (jlong)max_size, CHECK); + + cname = PerfDataManager::counter_name(_name_space, "capacity"); + _capacity = PerfDataManager::create_variable(SUN_GC, cname, + PerfData::U_Bytes, + initial_capacity, CHECK); + + cname = PerfDataManager::counter_name(_name_space, "used"); + _used = PerfDataManager::create_variable(SUN_GC, cname, PerfData::U_Bytes, + (jlong) 0, CHECK); + + cname = PerfDataManager::counter_name(_name_space, "initCapacity"); + PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_Bytes, + initial_capacity, CHECK); + } +} diff --git a/hotspot/src/share/vm/gc_implementation/shared/hSpaceCounters.hpp b/hotspot/src/share/vm/gc_implementation/shared/hSpaceCounters.hpp new file mode 100644 index 00000000000..a55d443a91f --- /dev/null +++ b/hotspot/src/share/vm/gc_implementation/shared/hSpaceCounters.hpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2011, 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_GC_IMPLEMENTATION_SHARED_HSPACECOUNTERS_HPP +#define SHARE_VM_GC_IMPLEMENTATION_SHARED_HSPACECOUNTERS_HPP + +#ifndef SERIALGC +#include "gc_implementation/shared/generationCounters.hpp" +#include "memory/generation.hpp" +#include "runtime/perfData.hpp" +#endif + +// A HSpaceCounter is a holder class for performance counters +// that track a collections (logical spaces) in a heap; + +class HeapSpaceUsedHelper; +class G1SpaceMonitoringSupport; + +class HSpaceCounters: public CHeapObj { + friend class VMStructs; + + private: + PerfVariable* _capacity; + PerfVariable* _used; + + // Constant PerfData types don't need to retain a reference. + // However, it's a good idea to document them here. + + char* _name_space; + + public: + + HSpaceCounters(const char* name, int ordinal, size_t max_size, + size_t initial_capacity, GenerationCounters* gc); + + ~HSpaceCounters() { + if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space); + } + + inline void update_capacity(size_t v) { + _capacity->set_value(v); + } + + inline void update_used(size_t v) { + _used->set_value(v); + } + + debug_only( + // for security reasons, we do not allow arbitrary reads from + // the counters as they may live in shared memory. + jlong used() { + return _used->get_value(); + } + jlong capacity() { + return _used->get_value(); + } + ) + + inline void update_all(size_t capacity, size_t used) { + update_capacity(capacity); + update_used(used); + } + + const char* name_space() const { return _name_space; } +}; +#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_HSPACECOUNTERS_HPP diff --git a/hotspot/src/share/vm/services/g1MemoryPool.cpp b/hotspot/src/share/vm/services/g1MemoryPool.cpp index 1a441595011..ce64f0e3d13 100644 --- a/hotspot/src/share/vm/services/g1MemoryPool.cpp +++ b/hotspot/src/share/vm/services/g1MemoryPool.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2011, 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 @@ -34,10 +34,10 @@ G1MemoryPoolSuper::G1MemoryPoolSuper(G1CollectedHeap* g1h, size_t init_size, bool support_usage_threshold) : _g1h(g1h), CollectedMemoryPool(name, - MemoryPool::Heap, - init_size, - undefined_max(), - support_usage_threshold) { + MemoryPool::Heap, + init_size, + undefined_max(), + support_usage_threshold) { assert(UseG1GC, "sanity"); } @@ -48,44 +48,27 @@ size_t G1MemoryPoolSuper::eden_space_committed(G1CollectedHeap* g1h) { // See the comment at the top of g1MemoryPool.hpp size_t G1MemoryPoolSuper::eden_space_used(G1CollectedHeap* g1h) { - size_t young_list_length = g1h->young_list()->length(); - size_t eden_used = young_list_length * HeapRegion::GrainBytes; - size_t survivor_used = survivor_space_used(g1h); - eden_used = subtract_up_to_zero(eden_used, survivor_used); - return eden_used; + return g1h->g1mm()->eden_space_used(); } // See the comment at the top of g1MemoryPool.hpp size_t G1MemoryPoolSuper::survivor_space_committed(G1CollectedHeap* g1h) { - return MAX2(survivor_space_used(g1h), (size_t) HeapRegion::GrainBytes); + return g1h->g1mm()->survivor_space_committed(); } // See the comment at the top of g1MemoryPool.hpp size_t G1MemoryPoolSuper::survivor_space_used(G1CollectedHeap* g1h) { - size_t survivor_num = g1h->g1_policy()->recorded_survivor_regions(); - size_t survivor_used = survivor_num * HeapRegion::GrainBytes; - return survivor_used; + return g1h->g1mm()->survivor_space_used(); } // See the comment at the top of g1MemoryPool.hpp size_t G1MemoryPoolSuper::old_space_committed(G1CollectedHeap* g1h) { - size_t committed = overall_committed(g1h); - size_t eden_committed = eden_space_committed(g1h); - size_t survivor_committed = survivor_space_committed(g1h); - committed = subtract_up_to_zero(committed, eden_committed); - committed = subtract_up_to_zero(committed, survivor_committed); - committed = MAX2(committed, (size_t) HeapRegion::GrainBytes); - return committed; + return g1h->g1mm()->old_space_committed(); } // See the comment at the top of g1MemoryPool.hpp size_t G1MemoryPoolSuper::old_space_used(G1CollectedHeap* g1h) { - size_t used = overall_used(g1h); - size_t eden_used = eden_space_used(g1h); - size_t survivor_used = survivor_space_used(g1h); - used = subtract_up_to_zero(used, eden_used); - used = subtract_up_to_zero(used, survivor_used); - return used; + return g1h->g1mm()->old_space_used(); } G1EdenPool::G1EdenPool(G1CollectedHeap* g1h) : diff --git a/hotspot/src/share/vm/services/g1MemoryPool.hpp b/hotspot/src/share/vm/services/g1MemoryPool.hpp index 9d7d6fd2e46..958a0885b98 100644 --- a/hotspot/src/share/vm/services/g1MemoryPool.hpp +++ b/hotspot/src/share/vm/services/g1MemoryPool.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2011, 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 @@ -46,68 +46,9 @@ class G1CollectedHeap; // get, as this does affect the performance and behavior of G1. Which // is why we introduce the three memory pools implemented here. // -// The above approach inroduces a couple of challenging issues in the -// implementation of the three memory pools: +// See comments in g1MonitoringSupport.hpp for additional details +// on this model. // -// 1) The used space calculation for a pool is not necessarily -// independent of the others. We can easily get from G1 the overall -// used space in the entire heap, the number of regions in the young -// generation (includes both eden and survivors), and the number of -// survivor regions. So, from that we calculate: -// -// survivor_used = survivor_num * region_size -// eden_used = young_region_num * region_size - survivor_used -// old_gen_used = overall_used - eden_used - survivor_used -// -// Note that survivor_used and eden_used are upper bounds. To get the -// actual value we would have to iterate over the regions and add up -// ->used(). But that'd be expensive. So, we'll accept some lack of -// accuracy for those two. But, we have to be careful when calculating -// old_gen_used, in case we subtract from overall_used more then the -// actual number and our result goes negative. -// -// 2) Calculating the used space is straightforward, as described -// above. However, how do we calculate the committed space, given that -// we allocate space for the eden, survivor, and old gen out of the -// same pool of regions? One way to do this is to use the used value -// as also the committed value for the eden and survivor spaces and -// then calculate the old gen committed space as follows: -// -// old_gen_committed = overall_committed - eden_committed - survivor_committed -// -// Maybe a better way to do that would be to calculate used for eden -// and survivor as a sum of ->used() over their regions and then -// calculate committed as region_num * region_size (i.e., what we use -// to calculate the used space now). This is something to consider -// in the future. -// -// 3) Another decision that is again not straightforward is what is -// the max size that each memory pool can grow to. One way to do this -// would be to use the committed size for the max for the eden and -// survivors and calculate the old gen max as follows (basically, it's -// a similar pattern to what we use for the committed space, as -// described above): -// -// old_gen_max = overall_max - eden_max - survivor_max -// -// Unfortunately, the above makes the max of each pool fluctuate over -// time and, even though this is allowed according to the spec, it -// broke several assumptions in the M&M framework (there were cases -// where used would reach a value greater than max). So, for max we -// use -1, which means "undefined" according to the spec. -// -// 4) Now, there is a very subtle issue with all the above. The -// framework will call get_memory_usage() on the three pools -// asynchronously. As a result, each call might get a different value -// for, say, survivor_num which will yield inconsistent values for -// eden_used, survivor_used, and old_gen_used (as survivor_num is used -// in the calculation of all three). This would normally be -// ok. However, it's possible that this might cause the sum of -// eden_used, survivor_used, and old_gen_used to go over the max heap -// size and this seems to sometimes cause JConsole (and maybe other -// clients) to get confused. There's not a really an easy / clean -// solution to this problem, due to the asynchrounous nature of the -// framework. // This class is shared by the three G1 memory pool classes @@ -116,22 +57,6 @@ class G1CollectedHeap; // (see comment above), we put the calculations in this class so that // we can easily share them among the subclasses. class G1MemoryPoolSuper : public CollectedMemoryPool { -private: - // It returns x - y if x > y, 0 otherwise. - // As described in the comment above, some of the inputs to the - // calculations we have to do are obtained concurrently and hence - // may be inconsistent with each other. So, this provides a - // defensive way of performing the subtraction and avoids the value - // going negative (which would mean a very large result, given that - // the parameter are size_t). - static size_t subtract_up_to_zero(size_t x, size_t y) { - if (x > y) { - return x - y; - } else { - return 0; - } - } - protected: G1CollectedHeap* _g1h; @@ -148,13 +73,6 @@ protected: return (size_t) -1; } - static size_t overall_committed(G1CollectedHeap* g1h) { - return g1h->capacity(); - } - static size_t overall_used(G1CollectedHeap* g1h) { - return g1h->used_unlocked(); - } - static size_t eden_space_committed(G1CollectedHeap* g1h); static size_t eden_space_used(G1CollectedHeap* g1h); From 6431b121c725e931240020868be7f13e26a436c5 Mon Sep 17 00:00:00 2001 From: Alexander Potochkin Date: Fri, 22 Apr 2011 20:54:37 +0400 Subject: [PATCH 18/80] 7036871: Some JCK interactive JSplitPane tests that test continuous layout fail with Nimbus L&F Reviewed-by: rupashka --- jdk/src/share/classes/javax/swing/JSplitPane.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/share/classes/javax/swing/JSplitPane.java b/jdk/src/share/classes/javax/swing/JSplitPane.java index d947329d663..fa773e5ae67 100644 --- a/jdk/src/share/classes/javax/swing/JSplitPane.java +++ b/jdk/src/share/classes/javax/swing/JSplitPane.java @@ -671,7 +671,7 @@ public class JSplitPane extends JComponent implements Accessible * which must be true for the child components * to be continuously * redisplayed and laid out during user intervention. - * The default value of this property is false. + * The default value of this property is look and feel dependent. * Some look and feels might not support continuous layout; * they will ignore this property. * From b5141e63fd863154e856d0147176b7fd65a8f620 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Fri, 22 Apr 2011 12:59:15 -0700 Subject: [PATCH 19/80] 7031011: fallbackfont testing failed on OEL 6 Reviewed-by: igor, jgodinez --- jdk/src/solaris/classes/sun/font/FcFontConfiguration.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/jdk/src/solaris/classes/sun/font/FcFontConfiguration.java b/jdk/src/solaris/classes/sun/font/FcFontConfiguration.java index ce2c935ba71..14d8e7ed221 100644 --- a/jdk/src/solaris/classes/sun/font/FcFontConfiguration.java +++ b/jdk/src/solaris/classes/sun/font/FcFontConfiguration.java @@ -256,9 +256,9 @@ public class FcFontConfiguration extends FontConfiguration { } if (installedFallbackFontFiles != null) { - System.arraycopy(fileNames, index, - installedFallbackFontFiles, - 0, installedFallbackFontFiles.length); + System.arraycopy(installedFallbackFontFiles, 0, + fileNames, fcFonts.length, + installedFallbackFontFiles.length); } result[fontIndex * NUM_STYLES + styleIndex] From 385e7253a7f3163bbd38527288e5e051bcee1ce0 Mon Sep 17 00:00:00 2001 From: John Coomes Date: Sat, 23 Apr 2011 04:20:09 -0700 Subject: [PATCH 20/80] 7037250: cscope.make database generation is silently broken Reviewed-by: stefank --- .../make/{solaris/makefiles => }/cscope.make | 113 +++++-------- hotspot/make/linux/Makefile | 2 +- hotspot/make/linux/makefiles/cscope.make | 160 ------------------ hotspot/make/solaris/Makefile | 2 +- 4 files changed, 48 insertions(+), 229 deletions(-) rename hotspot/make/{solaris/makefiles => }/cscope.make (52%) delete mode 100644 hotspot/make/linux/makefiles/cscope.make diff --git a/hotspot/make/solaris/makefiles/cscope.make b/hotspot/make/cscope.make similarity index 52% rename from hotspot/make/solaris/makefiles/cscope.make rename to hotspot/make/cscope.make index 3fa51fb30af..17c3aa37481 100644 --- a/hotspot/make/solaris/makefiles/cscope.make +++ b/hotspot/make/cscope.make @@ -22,29 +22,23 @@ # # -# -# The cscope.out file is made in the current directory and spans the entire -# source tree. -# -# Things to note: -# 1. We use relative names for cscope. -# 2. We *don't* remove the old cscope.out file, because cscope is smart -# enough to only build what has changed. It can be confused, however, -# if files are renamed or removed, so it may be necessary to manually -# remove cscope.out if a lot of reorganization has occurred. -# +# The cscope.out file is generated in the current directory. The old cscope.out +# file is *not* removed because cscope is smart enough to only build what has +# changed. cscope can be confused if files are renamed or removed, so it may be +# necessary to remove cscope.out (gmake cscope.clean) if a lot of reorganization +# has occurred. include $(GAMMADIR)/make/scm.make -NAWK = /usr/xpg4/bin/awk RM = rm -f HG = hg -CS_TOP = ../.. +CS_TOP = $(GAMMADIR) CSDIRS = $(CS_TOP)/src $(CS_TOP)/make CSINCS = $(CSDIRS:%=-I%) CSCOPE = cscope +CSCOPE_OUT = cscope.out CSCOPE_FLAGS = -b # Allow .java files to be added from the environment (CSCLASSES=yes). @@ -61,25 +55,22 @@ ifndef CSHEADERS RMCCHEADERS= -o -name CClassHeaders endif -# Use CS_GENERATED=x to include auto-generated files in the make directories. -ifdef CS_GENERATED -CS_ADD_GENERATED = -o -name '*.incl' -else -CS_PRUNE_GENERATED = -o -name '${OS}_*_core' -o -name '${OS}_*_compiler?' +# Ignore build products. +CS_PRUNE_GENERATED = -o -name '${OSNAME}_*_core' -o \ + -name '${OSNAME}_*_compiler?' + +# O/S-specific files for all systems are included by default. Set CS_OS to a +# space-separated list of identifiers to include only those systems. +ifdef CS_OS +CS_PRUNE_OS = $(patsubst %,-o -name '*%*',\ + $(filter-out ${CS_OS},linux macos solaris windows)) endif -# OS-specific files for other systems are excluded by default. Use CS_OS=yes -# to include platform-specific files for other platforms. -ifndef CS_OS -CS_OS = linux macos solaris win32 -CS_PRUNE_OS = $(patsubst %,-o -name '*%*',$(filter-out ${OS},${CS_OS})) -endif - -# Processor-specific files for other processors are excluded by default. Use -# CS_CPU=x to include platform-specific files for other platforms. -ifndef CS_CPU -CS_CPU = i486 sparc amd64 ia64 -CS_PRUNE_CPU = $(patsubst %,-o -name '*%*',$(filter-out ${SRCARCH},${CS_CPU})) +# CPU-specific files for all processors are included by default. Set CS_CPU +# space-separated list identifiers to include only those CPUs. +ifdef CS_CPU +CS_PRUNE_CPU = $(patsubst %,-o -name '*%*',\ + $(filter-out ${CS_CPU},arm ppc sparc x86 zero)) endif # What files should we include? A simple rule might be just those files under @@ -95,10 +86,14 @@ CS_PRUNE_STD = $(SCM_DIRS) \ -o -name '*demo' \ -o -name pkgarchive +# Placeholder for user-defined excludes. +CS_PRUNE_EX = + CS_PRUNE = $(CS_PRUNE_STD) \ $(CS_PRUNE_OS) \ $(CS_PRUNE_CPU) \ $(CS_PRUNE_GENERATED) \ + $(CS_PRUNE_EX) \ $(RMCCHEADERS) # File names to include. @@ -114,49 +109,33 @@ CSFILENAMES = -name '*.[ch]pp' \ -o -name '*.ad' \ $(ADDCLASSES) +.PHONY: cscope cscope.clean cscope.scratch TAGS.clean FORCE .PRECIOUS: cscope.out -cscope cscope.out: cscope.files FORCE - $(CSCOPE) $(CSCOPE_FLAGS) +cscope $(CSCOPE_OUT): cscope.files FORCE + $(CSCOPE) -f $(CSCOPE_OUT) $(CSCOPE_FLAGS) -# The .raw file is reordered here in an attempt to make cscope display the most -# relevant files first. -cscope.files: .cscope.files.raw - echo "$(CSINCS)" > $@ - -egrep -v "\.java|\/make\/" $< >> $@ - -fgrep ".java" $< >> $@ - -fgrep "/make/" $< >> $@ +cscope.clean: + $(QUIETLY) $(RM) $(CSCOPE_OUT) cscope.files -.cscope.files.raw: .nametable.files - -find $(CSDIRS) -type d \( $(CS_PRUNE) \) -prune -o \ - -type f \( $(CSFILENAMES) \) -print > $@ +cscope.scratch: cscope.clean cscope -cscope.clean: nametable.clean - -$(RM) cscope.out cscope.files .cscope.files.raw +# The raw list is reordered so cscope displays the most relevant files first. +cscope.files: + $(QUIETLY) \ + raw=cscope.$$$$; \ + find $(CSDIRS) -type d \( $(CS_PRUNE) \) -prune -o \ + -type f \( $(CSFILENAMES) \) -print > $$raw; \ + { \ + echo "$(CSINCS)"; \ + egrep -v "\.java|/make/" $$raw; \ + fgrep ".java" $$raw; \ + fgrep "/make/" $$raw; \ + } > $@; \ + rm -f $$raw TAGS: cscope.files FORCE egrep -v '^-|^$$' $< | etags --members - -TAGS.clean: nametable.clean - -$(RM) TAGS - -# .nametable.files and .nametable.files.tmp are used to determine if any files -# were added to/deleted from/renamed in the workspace. If not, then there's -# normally no need to rebuild the cscope database. To force a rebuild of -# the cscope database: gmake nametable.clean. -.nametable.files: .nametable.files.tmp - ( cmp -s $@ $< ) || ( cp $< $@ ) - -$(RM) $< - -# `hg status' is slightly faster than `hg fstatus'. Both are -# quite a bit slower on an NFS mounted file system, so this is -# really geared towards repos on local file systems. -.nametable.files.tmp: - -$(HG) fstatus -acmn > $@ - -nametable.clean: - -$(RM) .nametable.files .nametable.files.tmp - -FORCE: - -.PHONY: cscope cscope.clean TAGS.clean nametable.clean FORCE +TAGS.clean: + $(RM) TAGS diff --git a/hotspot/make/linux/Makefile b/hotspot/make/linux/Makefile index 49ac97c199e..fa1f56dd855 100644 --- a/hotspot/make/linux/Makefile +++ b/hotspot/make/linux/Makefile @@ -359,7 +359,7 @@ clean_compiler1 clean_compiler2 clean_core clean_zero clean_shark: clean: clean_compiler2 clean_compiler1 clean_core clean_zero clean_shark clean_docs -include $(GAMMADIR)/make/$(OSNAME)/makefiles/cscope.make +include $(GAMMADIR)/make/cscope.make #------------------------------------------------------------------------------- diff --git a/hotspot/make/linux/makefiles/cscope.make b/hotspot/make/linux/makefiles/cscope.make deleted file mode 100644 index e045c2dde96..00000000000 --- a/hotspot/make/linux/makefiles/cscope.make +++ /dev/null @@ -1,160 +0,0 @@ -# -# Copyright (c) 2005, 2008, 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. -# -# - -# -# The cscope.out file is made in the current directory and spans the entire -# source tree. -# -# Things to note: -# 1. We use relative names for cscope. -# 2. We *don't* remove the old cscope.out file, because cscope is smart -# enough to only build what has changed. It can be confused, however, -# if files are renamed or removed, so it may be necessary to manually -# remove cscope.out if a lot of reorganization has occurred. -# - -include $(GAMMADIR)/make/scm.make - -NAWK = awk -RM = rm -f -HG = hg -CS_TOP = ../.. - -CSDIRS = $(CS_TOP)/src $(CS_TOP)/build -CSINCS = $(CSDIRS:%=-I%) - -CSCOPE = cscope -CSCOPE_FLAGS = -b - -# Allow .java files to be added from the environment (CSCLASSES=yes). -ifdef CSCLASSES -ADDCLASSES= -o -name '*.java' -endif - -# Adding CClassHeaders also pushes the file count of a full workspace up about -# 200 files (these files also don't exist in a new workspace, and thus will -# cause the recreation of the database as they get created, which might seem -# a little confusing). Thus allow these files to be added from the environment -# (CSHEADERS=yes). -ifndef CSHEADERS -RMCCHEADERS= -o -name CClassHeaders -endif - -# Use CS_GENERATED=x to include auto-generated files in the build directories. -ifdef CS_GENERATED -CS_ADD_GENERATED = -o -name '*.incl' -else -CS_PRUNE_GENERATED = -o -name '${OS}_*_core' -o -name '${OS}_*_compiler?' -endif - -# OS-specific files for other systems are excluded by default. Use CS_OS=yes -# to include platform-specific files for other platforms. -ifndef CS_OS -CS_OS = linux macos solaris win32 -CS_PRUNE_OS = $(patsubst %,-o -name '*%*',$(filter-out ${OS},${CS_OS})) -endif - -# Processor-specific files for other processors are excluded by default. Use -# CS_CPU=x to include platform-specific files for other platforms. -ifndef CS_CPU -CS_CPU = i486 sparc amd64 ia64 -CS_PRUNE_CPU = $(patsubst %,-o -name '*%*',$(filter-out ${SRCARCH},${CS_CPU})) -endif - -# What files should we include? A simple rule might be just those files under -# SCCS control, however this would miss files we create like the opcodes and -# CClassHeaders. The following attempts to find everything that is *useful*. -# (.del files are created by sccsrm, demo directories contain many .java files -# that probably aren't useful for development, and the pkgarchive may contain -# duplicates of files within the source hierarchy). - -# Directories to exclude. -CS_PRUNE_STD = $(SCM_DIRS) \ - -o -name '.del-*' \ - -o -name '*demo' \ - -o -name pkgarchive - -CS_PRUNE = $(CS_PRUNE_STD) \ - $(CS_PRUNE_OS) \ - $(CS_PRUNE_CPU) \ - $(CS_PRUNE_GENERATED) \ - $(RMCCHEADERS) - -# File names to include. -CSFILENAMES = -name '*.[ch]pp' \ - -o -name '*.[Ccshlxy]' \ - $(CS_ADD_GENERATED) \ - -o -name '*.il' \ - -o -name '*.cc' \ - -o -name '*[Mm]akefile*' \ - -o -name '*.gmk' \ - -o -name '*.make' \ - -o -name '*.ad' \ - $(ADDCLASSES) - -.PRECIOUS: cscope.out - -cscope cscope.out: cscope.files FORCE - $(CSCOPE) $(CSCOPE_FLAGS) - -# The .raw file is reordered here in an attempt to make cscope display the most -# relevant files first. -cscope.files: .cscope.files.raw - echo "$(CSINCS)" > $@ - -egrep -v "\.java|\/make\/" $< >> $@ - -fgrep ".java" $< >> $@ - -fgrep "/make/" $< >> $@ - -.cscope.files.raw: .nametable.files - -find $(CSDIRS) -type d \( $(CS_PRUNE) \) -prune -o \ - -type f \( $(CSFILENAMES) \) -print > $@ - -cscope.clean: nametable.clean - -$(RM) cscope.out cscope.files .cscope.files.raw - -TAGS: cscope.files FORCE - egrep -v '^-|^$$' $< | etags --members - - -TAGS.clean: nametable.clean - -$(RM) TAGS - -# .nametable.files and .nametable.files.tmp are used to determine if any files -# were added to/deleted from/renamed in the workspace. If not, then there's -# normally no need to rebuild the cscope database. To force a rebuild of -# the cscope database: gmake nametable.clean. -.nametable.files: .nametable.files.tmp - ( cmp -s $@ $< ) || ( cp $< $@ ) - -$(RM) $< - -# `hg status' is slightly faster than `hg fstatus'. Both are -# quite a bit slower on an NFS mounted file system, so this is -# really geared towards repos on local file systems. -.nametable.files.tmp: - -$(HG) fstatus -acmn > $@ -nametable.clean: - -$(RM) .nametable.files .nametable.files.tmp - -FORCE: - -.PHONY: cscope cscope.clean TAGS.clean nametable.clean FORCE diff --git a/hotspot/make/solaris/Makefile b/hotspot/make/solaris/Makefile index d4bcb90f57a..b3af8513a73 100644 --- a/hotspot/make/solaris/Makefile +++ b/hotspot/make/solaris/Makefile @@ -296,7 +296,7 @@ clean_compiler1 clean_compiler2 clean_core clean_kernel: clean: clean_compiler2 clean_compiler1 clean_core clean_docs clean_kernel -include $(GAMMADIR)/make/$(OSNAME)/makefiles/cscope.make +include $(GAMMADIR)/make/cscope.make #------------------------------------------------------------------------------- From b91701fce632312a5aacec63e7f9126dccc2dec0 Mon Sep 17 00:00:00 2001 From: Andrei Dmitriev Date: Mon, 25 Apr 2011 21:08:14 +0400 Subject: [PATCH 21/80] 7030632: Pasting HTML that was copied from MS Word results in IOException Reviewed-by: uta, denis --- .../windows/classes/sun/awt/windows/WDataTransferer.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/jdk/src/windows/classes/sun/awt/windows/WDataTransferer.java b/jdk/src/windows/classes/sun/awt/windows/WDataTransferer.java index 21c1945140f..47dcf275430 100644 --- a/jdk/src/windows/classes/sun/awt/windows/WDataTransferer.java +++ b/jdk/src/windows/classes/sun/awt/windows/WDataTransferer.java @@ -830,7 +830,14 @@ class HTMLCodec extends InputStream { if( -1 == iStartOffset ){ throw new IOException(FAILURE_MSG + "invalid HTML format."); } - iReadCount = bufferedStream.skip(iStartOffset); + + int curOffset = 0; + while (curOffset < iStartOffset){ + curOffset += bufferedStream.skip(iStartOffset - curOffset); + } + + iReadCount = curOffset; + if( iStartOffset != iReadCount ){ throw new IOException(FAILURE_MSG + "Byte stream ends in description."); } From 5621d404bfbc05943b42affbba32ad2e43cda565 Mon Sep 17 00:00:00 2001 From: Denis Fokin Date: Mon, 25 Apr 2011 20:39:35 +0400 Subject: [PATCH 22/80] 6888182: Readable and permitted to delete files could not be transferred through Clipboard and DnD Reviewed-by: uta --- jdk/src/windows/native/sun/windows/awt_Clipboard.cpp | 2 +- jdk/src/windows/native/sun/windows/awt_DnDDS.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jdk/src/windows/native/sun/windows/awt_Clipboard.cpp b/jdk/src/windows/native/sun/windows/awt_Clipboard.cpp index d978090b8b3..6cea4a715fb 100644 --- a/jdk/src/windows/native/sun/windows/awt_Clipboard.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Clipboard.cpp @@ -294,7 +294,7 @@ Java_sun_awt_windows_WClipboard_publishClipboardData(JNIEnv *env, if (format == CF_HDROP) { DROPFILES *dropfiles = (DROPFILES *)dataout; dropfiles->pFiles = sizeof(DROPFILES); - dropfiles->fWide = FALSE; // good guess! + dropfiles->fWide = TRUE; // we publish only Unicode dataout += sizeof(DROPFILES); } diff --git a/jdk/src/windows/native/sun/windows/awt_DnDDS.cpp b/jdk/src/windows/native/sun/windows/awt_DnDDS.cpp index 1aea026c885..2d585e0330a 100644 --- a/jdk/src/windows/native/sun/windows/awt_DnDDS.cpp +++ b/jdk/src/windows/native/sun/windows/awt_DnDDS.cpp @@ -843,7 +843,7 @@ HRESULT __stdcall AwtDragSource::GetData(FORMATETC __RPC_FAR *pFormatEtc, dropfiles->pt.x = m_dropPoint.x; dropfiles->pt.y = m_dropPoint.y; dropfiles->fNC = m_fNC; - dropfiles->fWide = TRUE; // good guess! + dropfiles->fWide = TRUE; // we publish only Unicode dataout += sizeof(DROPFILES); } From 16d641461964970c44daf92c898a648335156913 Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Mon, 25 Apr 2011 16:25:58 -0700 Subject: [PATCH 23/80] 7030715: JSR 292 JRuby test/test_super_call_site_caching.rb asserts with +DoEscapeAnalysis Reviewed-by: twisti --- hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp | 9 +-------- hotspot/src/share/vm/ci/ciMethod.hpp | 19 ++++++++++++++++++- hotspot/src/share/vm/opto/graphKit.cpp | 6 +----- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp index 45910919080..97b414448ae 100644 --- a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp +++ b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp @@ -232,14 +232,7 @@ void BCEscapeAnalyzer::invoke(StateInfo &state, Bytecodes::Code code, ciMethod* } // compute size of arguments - int arg_size = target->arg_size(); - if (code == Bytecodes::_invokedynamic) { - assert(!target->is_static(), "receiver explicit in method"); - arg_size--; // implicit, not really on stack - } - if (!target->is_loaded() && code == Bytecodes::_invokestatic) { - arg_size--; - } + int arg_size = target->invoke_arg_size(code); int arg_base = MAX2(state._stack_height - arg_size, 0); // direct recursive calls are skipped if they can be bound statically without introducing diff --git a/hotspot/src/share/vm/ci/ciMethod.hpp b/hotspot/src/share/vm/ci/ciMethod.hpp index 840fb5da020..bf9568306b7 100644 --- a/hotspot/src/share/vm/ci/ciMethod.hpp +++ b/hotspot/src/share/vm/ci/ciMethod.hpp @@ -127,7 +127,24 @@ class ciMethod : public ciObject { ciSignature* signature() const { return _signature; } ciType* return_type() const { return _signature->return_type(); } int arg_size_no_receiver() const { return _signature->size(); } - int arg_size() const { return _signature->size() + (_flags.is_static() ? 0 : 1); } + // Can only be used on loaded ciMethods + int arg_size() const { + check_is_loaded(); + return _signature->size() + (_flags.is_static() ? 0 : 1); + } + // Report the number of elements on stack when invoking this method. + // This is different than the regular arg_size because invokdynamic + // has an implicit receiver. + int invoke_arg_size(Bytecodes::Code code) const { + int arg_size = _signature->size(); + // Add a receiver argument, maybe: + if (code != Bytecodes::_invokestatic && + code != Bytecodes::_invokedynamic) { + arg_size++; + } + return arg_size; + } + // Method code and related information. address code() { if (_code == NULL) load_code(); return _code; } diff --git a/hotspot/src/share/vm/opto/graphKit.cpp b/hotspot/src/share/vm/opto/graphKit.cpp index 590c05fb35d..e1612b843dc 100644 --- a/hotspot/src/share/vm/opto/graphKit.cpp +++ b/hotspot/src/share/vm/opto/graphKit.cpp @@ -1033,14 +1033,10 @@ bool GraphKit::compute_stack_effects(int& inputs, int& depth) { iter.reset_to_bci(bci()); iter.next(); ciMethod* method = iter.get_method(ignore); - inputs = method->arg_size_no_receiver(); - // Add a receiver argument, maybe: - if (code != Bytecodes::_invokestatic && - code != Bytecodes::_invokedynamic) - inputs += 1; // (Do not use ciMethod::arg_size(), because // it might be an unloaded method, which doesn't // know whether it is static or not.) + inputs = method->invoke_arg_size(code); int size = method->return_type()->size(); depth = size - inputs; } From 58aa826b315dbb63a3d5844c221920af0d660922 Mon Sep 17 00:00:00 2001 From: Yuka Kamiya Date: Tue, 26 Apr 2011 10:46:19 +0900 Subject: [PATCH 24/80] 7039469: (tz) Support tzdata2011g Reviewed-by: okutsu --- jdk/make/sun/javazic/tzdata/VERSION | 2 +- jdk/make/sun/javazic/tzdata/africa | 18 ++++++++++++++++-- jdk/make/sun/javazic/tzdata/europe | 4 ++-- jdk/make/sun/javazic/tzdata/southamerica | 23 +++++++++++++++++++++-- 4 files changed, 40 insertions(+), 7 deletions(-) diff --git a/jdk/make/sun/javazic/tzdata/VERSION b/jdk/make/sun/javazic/tzdata/VERSION index c19847f5a11..c52096254ae 100644 --- a/jdk/make/sun/javazic/tzdata/VERSION +++ b/jdk/make/sun/javazic/tzdata/VERSION @@ -21,4 +21,4 @@ # or visit www.oracle.com if you need additional information or have any # questions. # -tzdata2011e +tzdata2011g diff --git a/jdk/make/sun/javazic/tzdata/africa b/jdk/make/sun/javazic/tzdata/africa index bea5f8157bb..a43e73ce10b 100644 --- a/jdk/make/sun/javazic/tzdata/africa +++ b/jdk/make/sun/javazic/tzdata/africa @@ -234,7 +234,21 @@ Rule Egypt 1989 only - May 6 1:00 1:00 S Rule Egypt 1990 1994 - May 1 1:00 1:00 S # IATA (after 1990) says transitions are at 0:00. # Go with IATA starting in 1995, except correct 1995 entry from 09-30 to 09-29. -Rule Egypt 1995 max - Apr lastFri 0:00s 1:00 S + +# From Alexander Krivenyshev (2011-04-20): +# "...Egypt's interim cabinet decided on Wednesday to cancel daylight +# saving time after a poll posted on its website showed the majority of +# Egyptians would approve the cancellation." +# +# Egypt to cancel daylight saving time +# +# http://www.almasryalyoum.com/en/node/407168 +# +# or +# +# http://www.worldtimezone.com/dst_news/dst_news_egypt04.html +# +Rule Egypt 1995 2010 - Apr lastFri 0:00s 1:00 S Rule Egypt 1995 2005 - Sep lastThu 23:00s 0 - # From Steffen Thorsen (2006-09-19): # The Egyptian Gazette, issue 41,090 (2006-09-18), page 1, reports: @@ -335,7 +349,7 @@ Rule Egypt 2008 only - Aug lastThu 23:00s 0 - Rule Egypt 2009 only - Aug 20 23:00s 0 - Rule Egypt 2010 only - Aug 11 0:00 0 - Rule Egypt 2010 only - Sep 10 0:00 1:00 S -Rule Egypt 2010 max - Sep lastThu 23:00s 0 - +Rule Egypt 2010 only - Sep lastThu 23:00s 0 - # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Africa/Cairo 2:05:00 - LMT 1900 Oct diff --git a/jdk/make/sun/javazic/tzdata/europe b/jdk/make/sun/javazic/tzdata/europe index 5b11dfb5122..89bf6c5d3dc 100644 --- a/jdk/make/sun/javazic/tzdata/europe +++ b/jdk/make/sun/javazic/tzdata/europe @@ -168,7 +168,7 @@ # A monument to Willett was unveiled on 1927-05-21, in an open space in # a 45-acre wood near Chislehurst, Kent that was purchased by popular # subscription and open to the public. On the south face of the monolith, -# designed by G. W. Miller, is the the William Willett Memorial Sundial, +# designed by G. W. Miller, is the...William Willett Memorial Sundial, # which is permanently set to Summer Time. # From Winston Churchill (1934-04-28): @@ -1808,7 +1808,7 @@ Zone Europe/Oslo 0:43:00 - LMT 1895 Jan 1 # # All these events predate our cutoff date of 1970. Unless we can # come up with more definitive info about the timekeeping during the -# war years it's probably best just do do the following for now: +# war years it's probably best just do...the following for now: Link Europe/Oslo Arctic/Longyearbyen # Poland diff --git a/jdk/make/sun/javazic/tzdata/southamerica b/jdk/make/sun/javazic/tzdata/southamerica index 7afec35d696..7717d12d17a 100644 --- a/jdk/make/sun/javazic/tzdata/southamerica +++ b/jdk/make/sun/javazic/tzdata/southamerica @@ -767,7 +767,7 @@ Zone America/La_Paz -4:32:36 - LMT 1890 # # As a result of the above Decree I believe the America/Rio_Branco # timezone shall be modified from UTC-5 to UTC-4 and a new timezone shall -# be created to represent the the west side of the Para State. I +# be created to represent the...west side of the Para State. I # suggest this new timezone be called Santarem as the most # important/populated city in the affected area. # @@ -1365,6 +1365,24 @@ Zone Pacific/Galapagos -5:58:24 - LMT 1931 # Puerto Baquerizo Moreno # For now, we'll just record the time in Stanley, since we have no # better info. +# From Steffen Thorsen (2011-04-01): +# The Falkland Islands will not turn back clocks this winter, but stay on +# daylight saving time. +# +# One source: +# +# http://www.falklandnews.com/public/story.cfm?get=5914&source=3 +# +# +# We have gotten this confirmed by a clerk of the legislative assembly: +# Normally the clocks revert to Local Mean Time (UTC/GMT -4 hours) on the +# third Sunday of April at 0200hrs and advance to Summer Time (UTC/GMT -3 +# hours) on the first Sunday of September at 0200hrs. +# +# IMPORTANT NOTE: During 2011, on a trial basis, the Falkland Islands +# will not revert to local mean time, but clocks will remain on Summer +# time (UTC/GMT - 3 hours) throughout the whole of 2011. Any long term +# change to local time following the trial period will be notified. # Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S Rule Falk 1937 1938 - Sep lastSun 0:00 1:00 S Rule Falk 1938 1942 - Mar Sun>=19 0:00 0 - @@ -1376,7 +1394,8 @@ Rule Falk 1984 1985 - Apr lastSun 0:00 0 - Rule Falk 1984 only - Sep 16 0:00 1:00 S Rule Falk 1985 2000 - Sep Sun>=9 0:00 1:00 S Rule Falk 1986 2000 - Apr Sun>=16 0:00 0 - -Rule Falk 2001 max - Apr Sun>=15 2:00 0 - +Rule Falk 2001 2010 - Apr Sun>=15 2:00 0 - +Rule Falk 2012 max - Apr Sun>=15 2:00 0 - Rule Falk 2001 max - Sep Sun>=1 2:00 1:00 S # Zone NAME GMTOFF RULES FORMAT [UNTIL] Zone Atlantic/Stanley -3:51:24 - LMT 1890 From 8b9fe065648dd28f7272009f66e061cb676afe14 Mon Sep 17 00:00:00 2001 From: Michael Fang Date: Mon, 25 Apr 2011 20:16:46 -0700 Subject: [PATCH 25/80] 7039493: incorporating WPTG translation bug fixes Reviewed-by: yhuang --- .../com/sun/tools/javadoc/resources/javadoc_zh_CN.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc_zh_CN.properties b/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc_zh_CN.properties index 8bcfafdb1eb..8bbe4a7abf8 100644 --- a/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc_zh_CN.properties +++ b/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc_zh_CN.properties @@ -43,7 +43,7 @@ main.Building_tree=\u6B63\u5728\u6784\u9020 Javadoc \u4FE1\u606F... main.no_source_files_for_package=\u6CA1\u6709\u7A0B\u5E8F\u5305{0}\u7684\u6E90\u6587\u4EF6 main.fatal.error=\u81F4\u547D\u9519\u8BEF main.fatal.exception=\u81F4\u547D\u5F02\u5E38\u9519\u8BEF -main.out.of.memory=java.lang.OutOfMemoryError: \u8BF7\u589E\u5927\u5185\u5B58\u3002\n\u4F8B\u5982, \u5BF9\u4E8E JDK \u7ECF\u5178\u6216\u70ED\u70B9 VM, \u8BF7\u589E\u5927\u9009\u9879 -J-Xmx,\n\u4F8B\u5982 -J-Xmx32m\u3002 +main.out.of.memory=java.lang.OutOfMemoryError: \u8BF7\u589E\u5927\u5185\u5B58\u3002\n\u4F8B\u5982, \u5BF9\u4E8E JDK \u7ECF\u5178\u6216 HotSpot VM, \u8BF7\u589E\u5927\u9009\u9879 -J-Xmx,\n\u4F8B\u5982 -J-Xmx32m\u3002 main.done_in=[\u5728 {0} \u6BEB\u79D2\u5185\u5B8C\u6210] main.doclet_method_must_be_static=\u5728 doclet \u7C7B{0}\u4E2D, \u65B9\u6CD5{1}\u5FC5\u987B\u4E3A\u9759\u6001\u3002 main.must_return_int=\u5728 doclet \u7C7B{0}\u4E2D, \u65B9\u6CD5{1}\u5FC5\u987B\u8FD4\u56DE\u6574\u578B\u503C\u3002 From ab86f12c440160ec5332208de68494552183dba1 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore Date: Tue, 26 Apr 2011 14:04:43 -0400 Subject: [PATCH 26/80] 7009923: JSR 292: VM crash in JavaThread::last_frame Handle stack overflow before the first frame is called, by printing out the called method and not walking the stack. Reviewed-by: dholmes, phh, dsamersoff --- hotspot/src/share/vm/classfile/javaClasses.cpp | 16 +++++++++++++--- hotspot/src/share/vm/classfile/javaClasses.hpp | 4 ++-- hotspot/src/share/vm/runtime/javaCalls.cpp | 2 +- hotspot/src/share/vm/utilities/exceptions.cpp | 6 +++--- hotspot/src/share/vm/utilities/exceptions.hpp | 2 +- 5 files changed, 20 insertions(+), 10 deletions(-) diff --git a/hotspot/src/share/vm/classfile/javaClasses.cpp b/hotspot/src/share/vm/classfile/javaClasses.cpp index 81b3e65d4ee..fa422673d48 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.cpp +++ b/hotspot/src/share/vm/classfile/javaClasses.cpp @@ -1357,7 +1357,7 @@ class BacktraceBuilder: public StackObj { }; -void java_lang_Throwable::fill_in_stack_trace(Handle throwable, TRAPS) { +void java_lang_Throwable::fill_in_stack_trace(Handle throwable, methodHandle method, TRAPS) { if (!StackTraceInThrowable) return; ResourceMark rm(THREAD); @@ -1374,6 +1374,16 @@ void java_lang_Throwable::fill_in_stack_trace(Handle throwable, TRAPS) { JavaThread* thread = (JavaThread*)THREAD; BacktraceBuilder bt(CHECK); + // If there is no Java frame just return the method that was being called + // with bci 0 + if (!thread->has_last_Java_frame()) { + if (max_depth >= 1 && method() != NULL) { + bt.push(method(), 0, CHECK); + set_backtrace(throwable(), bt.backtrace()); + } + return; + } + // Instead of using vframe directly, this version of fill_in_stack_trace // basically handles everything by hand. This significantly improved the // speed of this method call up to 28.5% on Solaris sparc. 27.1% on Windows. @@ -1477,7 +1487,7 @@ void java_lang_Throwable::fill_in_stack_trace(Handle throwable, TRAPS) { set_backtrace(throwable(), bt.backtrace()); } -void java_lang_Throwable::fill_in_stack_trace(Handle throwable) { +void java_lang_Throwable::fill_in_stack_trace(Handle throwable, methodHandle method) { // No-op if stack trace is disabled if (!StackTraceInThrowable) { return; @@ -1491,7 +1501,7 @@ void java_lang_Throwable::fill_in_stack_trace(Handle throwable) { PRESERVE_EXCEPTION_MARK; JavaThread* thread = JavaThread::active(); - fill_in_stack_trace(throwable, thread); + fill_in_stack_trace(throwable, method, thread); // ignore exceptions thrown during stack trace filling CLEAR_PENDING_EXCEPTION; } diff --git a/hotspot/src/share/vm/classfile/javaClasses.hpp b/hotspot/src/share/vm/classfile/javaClasses.hpp index bed2ad46ac2..5701bc3893c 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.hpp +++ b/hotspot/src/share/vm/classfile/javaClasses.hpp @@ -440,8 +440,8 @@ class java_lang_Throwable: AllStatic { static void fill_in_stack_trace_of_preallocated_backtrace(Handle throwable); // Fill in current stack trace, can cause GC - static void fill_in_stack_trace(Handle throwable, TRAPS); - static void fill_in_stack_trace(Handle throwable); + static void fill_in_stack_trace(Handle throwable, methodHandle method, TRAPS); + static void fill_in_stack_trace(Handle throwable, methodHandle method = methodHandle()); // Programmatic access to stack trace static oop get_stack_trace_element(oop throwable, int index, TRAPS); static int get_stack_trace_depth(oop throwable, TRAPS); diff --git a/hotspot/src/share/vm/runtime/javaCalls.cpp b/hotspot/src/share/vm/runtime/javaCalls.cpp index aaa2805e7e7..eca02a49629 100644 --- a/hotspot/src/share/vm/runtime/javaCalls.cpp +++ b/hotspot/src/share/vm/runtime/javaCalls.cpp @@ -389,7 +389,7 @@ void JavaCalls::call_helper(JavaValue* result, methodHandle* m, JavaCallArgument // to Java if (!os::stack_shadow_pages_available(THREAD, method)) { // Throw stack overflow exception with preinitialized exception. - Exceptions::throw_stack_overflow_exception(THREAD, __FILE__, __LINE__); + Exceptions::throw_stack_overflow_exception(THREAD, __FILE__, __LINE__, method); return; } else { // Touch pages checked if the OS needs them to be touched to be mapped. diff --git a/hotspot/src/share/vm/utilities/exceptions.cpp b/hotspot/src/share/vm/utilities/exceptions.cpp index 5d8a33b4d2e..3d2f3cfea64 100644 --- a/hotspot/src/share/vm/utilities/exceptions.cpp +++ b/hotspot/src/share/vm/utilities/exceptions.cpp @@ -207,7 +207,7 @@ void Exceptions::_throw_args(Thread* thread, const char* file, int line, Symbol* } -void Exceptions::throw_stack_overflow_exception(Thread* THREAD, const char* file, int line) { +void Exceptions::throw_stack_overflow_exception(Thread* THREAD, const char* file, int line, methodHandle method) { Handle exception; if (!THREAD->has_pending_exception()) { klassOop k = SystemDictionary::StackOverflowError_klass(); @@ -215,13 +215,13 @@ void Exceptions::throw_stack_overflow_exception(Thread* THREAD, const char* file exception = Handle(THREAD, e); // fill_in_stack trace does gc assert(instanceKlass::cast(k)->is_initialized(), "need to increase min_stack_allowed calculation"); if (StackTraceInThrowable) { - java_lang_Throwable::fill_in_stack_trace(exception); + java_lang_Throwable::fill_in_stack_trace(exception, method()); } } else { // if prior exception, throw that one instead exception = Handle(THREAD, THREAD->pending_exception()); } - _throw_oop(THREAD, file, line, exception()); + _throw(THREAD, file, line, exception); } void Exceptions::fthrow(Thread* thread, const char* file, int line, Symbol* h_name, const char* format, ...) { diff --git a/hotspot/src/share/vm/utilities/exceptions.hpp b/hotspot/src/share/vm/utilities/exceptions.hpp index 5649f4e600d..52540f31f65 100644 --- a/hotspot/src/share/vm/utilities/exceptions.hpp +++ b/hotspot/src/share/vm/utilities/exceptions.hpp @@ -144,7 +144,7 @@ class Exceptions { const char* message, ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8); - static void throw_stack_overflow_exception(Thread* thread, const char* file, int line); + static void throw_stack_overflow_exception(Thread* thread, const char* file, int line, methodHandle method); // for AbortVMOnException flag NOT_PRODUCT(static void debug_check_abort(Handle exception, const char* message = NULL);) From e3121a5a43b52af20efb1e4017bf805f682f2d6a Mon Sep 17 00:00:00 2001 From: Igor Veresov Date: Tue, 26 Apr 2011 11:46:34 -0700 Subject: [PATCH 27/80] 7037939: NUMA: Disable adaptive resizing if SHM large pages are used Make the NUMA allocator behave properly with SHM and ISM large pages. Reviewed-by: ysr --- hotspot/src/os/linux/vm/os_linux.cpp | 17 +++++++++++++++++ hotspot/src/os/solaris/vm/os_solaris.cpp | 18 +++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp index 0c6213d1a56..aea9c8f9da3 100644 --- a/hotspot/src/os/linux/vm/os_linux.cpp +++ b/hotspot/src/os/linux/vm/os_linux.cpp @@ -4170,6 +4170,23 @@ jint os::init_2(void) UseNUMA = false; } } + // With SHM large pages we cannot uncommit a page, so there's not way + // we can make the adaptive lgrp chunk resizing work. If the user specified + // both UseNUMA and UseLargePages (or UseSHM) on the command line - warn and + // disable adaptive resizing. + if (UseNUMA && UseLargePages && UseSHM) { + if (!FLAG_IS_DEFAULT(UseNUMA)) { + if (FLAG_IS_DEFAULT(UseLargePages) && FLAG_IS_DEFAULT(UseSHM)) { + UseLargePages = false; + } else { + warning("UseNUMA is not fully compatible with SHM large pages, disabling adaptive resizing"); + UseAdaptiveSizePolicy = false; + UseAdaptiveNUMAChunkSizing = false; + } + } else { + UseNUMA = false; + } + } if (!UseNUMA && ForceNUMA) { UseNUMA = true; } diff --git a/hotspot/src/os/solaris/vm/os_solaris.cpp b/hotspot/src/os/solaris/vm/os_solaris.cpp index ca49264dc6c..7c8fa0af6cf 100644 --- a/hotspot/src/os/solaris/vm/os_solaris.cpp +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp @@ -2826,7 +2826,9 @@ bool os::remove_stack_guard_pages(char* addr, size_t size) { void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) { assert((intptr_t)addr % alignment_hint == 0, "Address should be aligned."); assert((intptr_t)(addr + bytes) % alignment_hint == 0, "End should be aligned."); - Solaris::set_mpss_range(addr, bytes, alignment_hint); + if (UseLargePages && UseMPSS) { + Solaris::set_mpss_range(addr, bytes, alignment_hint); + } } // Tell the OS to make the range local to the first-touching LWP @@ -5044,6 +5046,20 @@ jint os::init_2(void) { UseNUMA = false; } } + // ISM is not compatible with the NUMA allocator - it always allocates + // pages round-robin across the lgroups. + if (UseNUMA && UseLargePages && UseISM) { + if (!FLAG_IS_DEFAULT(UseNUMA)) { + if (FLAG_IS_DEFAULT(UseLargePages) && FLAG_IS_DEFAULT(UseISM)) { + UseLargePages = false; + } else { + warning("UseNUMA is not compatible with ISM large pages, disabling NUMA allocator"); + UseNUMA = false; + } + } else { + UseNUMA = false; + } + } if (!UseNUMA && ForceNUMA) { UseNUMA = true; } From 6c8fc4b347befd35f9be7c9802d49c2f647ca4c3 Mon Sep 17 00:00:00 2001 From: Vladimir Kozlov Date: Tue, 26 Apr 2011 12:14:22 -0700 Subject: [PATCH 28/80] 7039586: test/java/util/Collections/Rotate.java failing with hs21-b09 A predicate should not be moved in partial peel optimization since it will invalidate jvm state of its uncommon trap. Reviewed-by: never --- hotspot/src/share/vm/opto/loopopts.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/hotspot/src/share/vm/opto/loopopts.cpp b/hotspot/src/share/vm/opto/loopopts.cpp index 1be37420607..6498d3c679b 100644 --- a/hotspot/src/share/vm/opto/loopopts.cpp +++ b/hotspot/src/share/vm/opto/loopopts.cpp @@ -2262,6 +2262,9 @@ bool PhaseIdealLoop::is_valid_clone_loop_form( IdealLoopTree *loop, Node_List& p // stmt1 // | // v +// loop predicate +// | +// v // stmt2 clone // | // v @@ -2272,9 +2275,6 @@ bool PhaseIdealLoop::is_valid_clone_loop_form( IdealLoopTree *loop, Node_List& p // : false true // : | | // : | v -// : | loop predicate -// : | | -// : | v // : | newloop<-----+ // : | | | // : | stmt3 clone | @@ -2330,7 +2330,6 @@ bool PhaseIdealLoop::partial_peel( IdealLoopTree *loop, Node_List &old_new ) { } } - Node* entry = head->in(LoopNode::EntryControl); int dd = dom_depth(head); // Step 1: find cut point @@ -2627,8 +2626,6 @@ bool PhaseIdealLoop::partial_peel( IdealLoopTree *loop, Node_List &old_new ) { // Backedge of the surviving new_head (the clone) is original last_peel _igvn.hash_delete(new_head_clone); - Node* new_entry = move_loop_predicates(entry, new_head_clone->in(LoopNode::EntryControl)); - new_head_clone->set_req(LoopNode::EntryControl, new_entry); new_head_clone->set_req(LoopNode::LoopBackControl, last_peel); _igvn._worklist.push(new_head_clone); From 74225e1f348d38e278a9e1d7cc63cf80b030328e Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Tue, 26 Apr 2011 16:20:22 -0700 Subject: [PATCH 29/80] 6631003: Add hg tip changeset to build image Reviewed-by: mduigou --- hotspot/.hgignore | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgignore b/hotspot/.hgignore index 9818ff1af6e..482470820ef 100644 --- a/hotspot/.hgignore +++ b/hotspot/.hgignore @@ -5,3 +5,4 @@ ^src/share/tools/IdealGraphVisualizer/[a-zA-Z0-9]*/build/ ^src/share/tools/IdealGraphVisualizer/build/ ^src/share/tools/IdealGraphVisualizer/dist/ +^.hgtip From c2bdfcee053972c4255c9eb8f6163651d928afa6 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Tue, 26 Apr 2011 16:22:41 -0700 Subject: [PATCH 30/80] 6631003: Add hg tip changeset to build image Reviewed-by: mduigou --- langtools/.hgignore | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/.hgignore b/langtools/.hgignore index 0092bd4ff5a..83cef213d48 100644 --- a/langtools/.hgignore +++ b/langtools/.hgignore @@ -1,3 +1,4 @@ ^build/ ^dist/ /nbproject/private/ +^.hgtip From 5c45b515379778f70fca3088f3d33c1a52c3a703 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Tue, 26 Apr 2011 16:28:05 -0700 Subject: [PATCH 31/80] 6631003: Add hg tip changeset to build image Reviewed-by: mduigou --- jaxws/.hgignore | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxws/.hgignore b/jaxws/.hgignore index 32df842b67c..970fc82946b 100644 --- a/jaxws/.hgignore +++ b/jaxws/.hgignore @@ -4,3 +4,4 @@ ^drop_included/ ^webrev/ /nbproject/private/ +^.hgtip From a6c3e8087800a58415b027d3261077aa72e9483b Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Tue, 26 Apr 2011 16:28:22 -0700 Subject: [PATCH 32/80] 6631003: Add hg tip changeset to build image Reviewed-by: mduigou --- jaxp/.hgignore | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxp/.hgignore b/jaxp/.hgignore index 32df842b67c..970fc82946b 100644 --- a/jaxp/.hgignore +++ b/jaxp/.hgignore @@ -4,3 +4,4 @@ ^drop_included/ ^webrev/ /nbproject/private/ +^.hgtip From d2dbecb06ba630ec1886f93e0c63225c562b584c Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Tue, 26 Apr 2011 16:29:35 -0700 Subject: [PATCH 33/80] 6631003: Add hg tip changeset to build image Reviewed-by: mduigou --- corba/.hgignore | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgignore b/corba/.hgignore index 0092bd4ff5a..83cef213d48 100644 --- a/corba/.hgignore +++ b/corba/.hgignore @@ -1,3 +1,4 @@ ^build/ ^dist/ /nbproject/private/ +^.hgtip From 4231fbb3e6cc58de5fa54e0b085e5e37b4198529 Mon Sep 17 00:00:00 2001 From: Kelly O'Hair Date: Tue, 26 Apr 2011 16:30:00 -0700 Subject: [PATCH 34/80] 6631003: Add hg tip changeset to build image Reviewed-by: mduigou --- .hgignore | 1 + Makefile | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.hgignore b/.hgignore index 2d339f9988c..8fde2caf08d 100644 --- a/.hgignore +++ b/.hgignore @@ -2,3 +2,4 @@ ^dist/ /nbproject/private/ ^webrev +^.hgtip diff --git a/Makefile b/Makefile index 1d20f79bf83..c8598161cec 100644 --- a/Makefile +++ b/Makefile @@ -97,7 +97,7 @@ define StopTimer endef # Generic build of basic repo series -generic_build_repo_series:: +generic_build_repo_series:: $(SOURCE_TIPS) $(MKDIR) -p $(OUTPUTDIR) $(MKDIR) -p $(OUTPUTDIR)/j2sdk-image @$(call StartTimer) @@ -243,6 +243,14 @@ product_build:: build_product_image debug_build:: build_debug_image fastdebug_build:: build_fastdebug_image +# The source tips are stored with the relative path to the repo. +# This file will be used when constructing the jdk image. +source_tips: $(SOURCE_TIPS) + $(CAT) $< +$(SOURCE_TIPS): FRC + @$(prep-target) + @$(call GetSourceTips) + clobber:: REPORT_BUILD_TIMES= clobber:: $(RM) -r $(OUTPUTDIR)/* From d86311b13c33ae4598c029cfe4e7ec1714ce0a84 Mon Sep 17 00:00:00 2001 From: "Y. Srinivas Ramakrishna" Date: Tue, 26 Apr 2011 21:17:24 -0700 Subject: [PATCH 35/80] 7039089: G1: changeset for 7037276 broke heap verification, and related cleanups In G1 heap verification, we no longer scan perm to G1-collected heap refs as part of process_strong_roots() but rather in a separate explicit oop iteration over the perm gen. This preserves the original perm card-marks. Added a new assertion in younger_refs_iterate() to catch a simple subcase where the user may have forgotten a prior save_marks() call, as happened in the case of G1's attempt to iterate perm to G1 refs when verifying the heap before exit. The assert was deliberately weakened for ParNew+CMS and will be fixed for that combination in a future CR. Also made some (non-G1) cleanups related to code and comments obsoleted by the migration of Symbols to the native heap. Reviewed-by: iveresov, jmasa, tonyp --- .../compactibleFreeListSpace.cpp | 13 ++++++++- .../concurrentMarkSweepGeneration.cpp | 5 ++-- .../gc_implementation/g1/g1CollectedHeap.cpp | 19 ++++++++---- hotspot/src/share/vm/memory/cardTableRS.cpp | 29 ++++++++++++++++++- .../src/share/vm/memory/genCollectedHeap.hpp | 6 ++-- hotspot/src/share/vm/memory/sharedHeap.cpp | 11 ++----- hotspot/src/share/vm/memory/sharedHeap.hpp | 10 +++---- hotspot/src/share/vm/runtime/vmThread.cpp | 4 ++- 8 files changed, 69 insertions(+), 28 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp index 50e073d24aa..482aa15752a 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp @@ -1963,10 +1963,21 @@ CompactibleFreeListSpace::gc_epilogue() { // Iteration support, mostly delegated from a CMS generation void CompactibleFreeListSpace::save_marks() { - // mark the "end" of the used space at the time of this call; + assert(Thread::current()->is_VM_thread(), + "Global variable should only be set when single-threaded"); + // Mark the "end" of the used space at the time of this call; // note, however, that promoted objects from this point // on are tracked in the _promoInfo below. set_saved_mark_word(unallocated_block()); +#ifdef ASSERT + // Check the sanity of save_marks() etc. + MemRegion ur = used_region(); + MemRegion urasm = used_region_at_save_marks(); + assert(ur.contains(urasm), + err_msg(" Error at save_marks(): [" PTR_FORMAT "," PTR_FORMAT ")" + " should contain [" PTR_FORMAT "," PTR_FORMAT ")", + ur.start(), ur.end(), urasm.start(), urasm.end())); +#endif // inform allocator that promotions should be tracked. assert(_promoInfo.noPromotions(), "_promoInfo inconsistency"); _promoInfo.startTrackingPromotions(); diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp index 307a8500ca6..bd49b0f9fc6 100644 --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp @@ -3189,10 +3189,9 @@ bool ConcurrentMarkSweepGeneration::is_too_full() const { } void CMSCollector::setup_cms_unloading_and_verification_state() { - const bool should_verify = VerifyBeforeGC || VerifyAfterGC || VerifyDuringGC + const bool should_verify = VerifyBeforeGC || VerifyAfterGC || VerifyDuringGC || VerifyBeforeExit; - const int rso = SharedHeap::SO_Symbols | SharedHeap::SO_Strings - | SharedHeap::SO_CodeCache; + const int rso = SharedHeap::SO_Strings | SharedHeap::SO_CodeCache; if (should_unload_classes()) { // Should unload classes this cycle remove_root_scanning_option(rso); // Shrink the root set appropriately diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index d8a9c07f522..642c7acb74e 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -2805,17 +2805,26 @@ void G1CollectedHeap::verify(bool allow_dirty, bool silent, bool use_prev_marking) { if (SafepointSynchronize::is_at_safepoint() || ! UseTLAB) { - if (!silent) { gclog_or_tty->print("roots "); } + if (!silent) { gclog_or_tty->print("Roots (excluding permgen) "); } VerifyRootsClosure rootsCl(use_prev_marking); CodeBlobToOopClosure blobsCl(&rootsCl, /*do_marking=*/ false); - process_strong_roots(true, // activate StrongRootsScope - false, - SharedHeap::SO_AllClasses, + // We apply the relevant closures to all the oops in the + // system dictionary, the string table and the code cache. + const int so = SharedHeap::SO_AllClasses | SharedHeap::SO_Strings | SharedHeap::SO_CodeCache; + process_strong_roots(true, // activate StrongRootsScope + true, // we set "collecting perm gen" to true, + // so we don't reset the dirty cards in the perm gen. + SharedHeap::ScanningOption(so), // roots scanning options &rootsCl, &blobsCl, &rootsCl); + // Since we used "collecting_perm_gen" == true above, we will not have + // checked the refs from perm into the G1-collected heap. We check those + // references explicitly below. Whether the relevant cards are dirty + // is checked further below in the rem set verification. + if (!silent) { gclog_or_tty->print("Permgen roots "); } + perm_gen()->oop_iterate(&rootsCl); bool failures = rootsCl.failures(); - rem_set()->invalidate(perm_gen()->used_region(), false); if (!silent) { gclog_or_tty->print("HeapRegionSets "); } verify_region_sets(); if (!silent) { gclog_or_tty->print("HeapRegions "); } diff --git a/hotspot/src/share/vm/memory/cardTableRS.cpp b/hotspot/src/share/vm/memory/cardTableRS.cpp index 4a22ba73a21..551ba7eb8a4 100644 --- a/hotspot/src/share/vm/memory/cardTableRS.cpp +++ b/hotspot/src/share/vm/memory/cardTableRS.cpp @@ -250,7 +250,34 @@ void CardTableRS::younger_refs_in_space_iterate(Space* sp, cl->gen_boundary()); ClearNoncleanCardWrapper clear_cl(dcto_cl, this); - _ct_bs->non_clean_card_iterate_possibly_parallel(sp, sp->used_region_at_save_marks(), + const MemRegion urasm = sp->used_region_at_save_marks(); +#ifdef ASSERT + // Convert the assertion check to a warning if we are running + // CMS+ParNew until related bug is fixed. + MemRegion ur = sp->used_region(); + assert(ur.contains(urasm) || (UseConcMarkSweepGC && UseParNewGC), + err_msg("Did you forget to call save_marks()? " + "[" PTR_FORMAT ", " PTR_FORMAT ") is not contained in " + "[" PTR_FORMAT ", " PTR_FORMAT ")", + urasm.start(), urasm.end(), ur.start(), ur.end())); + // In the case of CMS+ParNew, issue a warning + if (!ur.contains(urasm)) { + assert(UseConcMarkSweepGC && UseParNewGC, "Tautology: see assert above"); + warning("CMS+ParNew: Did you forget to call save_marks()? " + "[" PTR_FORMAT ", " PTR_FORMAT ") is not contained in " + "[" PTR_FORMAT ", " PTR_FORMAT ")", + urasm.start(), urasm.end(), ur.start(), ur.end()); + MemRegion ur2 = sp->used_region(); + MemRegion urasm2 = sp->used_region_at_save_marks(); + if (!ur.equals(ur2)) { + warning("CMS+ParNew: Flickering used_region()!!"); + } + if (!urasm.equals(urasm2)) { + warning("CMS+ParNew: Flickering used_region_at_save_marks()!!"); + } + } +#endif + _ct_bs->non_clean_card_iterate_possibly_parallel(sp, urasm, dcto_cl, &clear_cl); } diff --git a/hotspot/src/share/vm/memory/genCollectedHeap.hpp b/hotspot/src/share/vm/memory/genCollectedHeap.hpp index de8070b81c7..383936699d6 100644 --- a/hotspot/src/share/vm/memory/genCollectedHeap.hpp +++ b/hotspot/src/share/vm/memory/genCollectedHeap.hpp @@ -427,13 +427,13 @@ public: // explicitly mark reachable objects in younger generations, to avoid // excess storage retention.) If "collecting_perm_gen" is false, then // roots that may only contain references to permGen objects are not - // scanned. The "so" argument determines which of the roots + // scanned; instead, the older_gens closure is applied to all outgoing + // references in the perm gen. The "so" argument determines which of the roots // the closure is applied to: // "SO_None" does none; // "SO_AllClasses" applies the closure to all entries in the SystemDictionary; // "SO_SystemClasses" to all the "system" classes and loaders; - // "SO_Symbols_and_Strings" applies the closure to all entries in - // SymbolsTable and StringTable. + // "SO_Strings" applies the closure to all entries in the StringTable. void gen_process_strong_roots(int level, bool younger_gens_as_roots, // The remaining arguments are in an order diff --git a/hotspot/src/share/vm/memory/sharedHeap.cpp b/hotspot/src/share/vm/memory/sharedHeap.cpp index 37c17b03861..24a2373acec 100644 --- a/hotspot/src/share/vm/memory/sharedHeap.cpp +++ b/hotspot/src/share/vm/memory/sharedHeap.cpp @@ -46,7 +46,6 @@ enum SH_process_strong_roots_tasks { SH_PS_Management_oops_do, SH_PS_SystemDictionary_oops_do, SH_PS_jvmti_oops_do, - SH_PS_SymbolTable_oops_do, SH_PS_StringTable_oops_do, SH_PS_CodeCache_oops_do, // Leave this one last. @@ -161,13 +160,9 @@ void SharedHeap::process_strong_roots(bool activate_scope, if (!_process_strong_tasks->is_task_claimed(SH_PS_SystemDictionary_oops_do)) { if (so & SO_AllClasses) { SystemDictionary::oops_do(roots); - } else - if (so & SO_SystemClasses) { - SystemDictionary::always_strong_oops_do(roots); - } - } - - if (!_process_strong_tasks->is_task_claimed(SH_PS_SymbolTable_oops_do)) { + } else if (so & SO_SystemClasses) { + SystemDictionary::always_strong_oops_do(roots); + } } if (!_process_strong_tasks->is_task_claimed(SH_PS_StringTable_oops_do)) { diff --git a/hotspot/src/share/vm/memory/sharedHeap.hpp b/hotspot/src/share/vm/memory/sharedHeap.hpp index 54af68a421f..55a9b569d9c 100644 --- a/hotspot/src/share/vm/memory/sharedHeap.hpp +++ b/hotspot/src/share/vm/memory/sharedHeap.hpp @@ -192,9 +192,8 @@ public: SO_None = 0x0, SO_AllClasses = 0x1, SO_SystemClasses = 0x2, - SO_Symbols = 0x4, - SO_Strings = 0x8, - SO_CodeCache = 0x10 + SO_Strings = 0x4, + SO_CodeCache = 0x8 }; FlexibleWorkGang* workers() const { return _workers; } @@ -208,14 +207,13 @@ public: // Invoke the "do_oop" method the closure "roots" on all root locations. // If "collecting_perm_gen" is false, then roots that may only contain - // references to permGen objects are not scanned. If true, the - // "perm_gen" closure is applied to all older-to-younger refs in the + // references to permGen objects are not scanned; instead, in that case, + // the "perm_blk" closure is applied to all outgoing refs in the // permanent generation. The "so" argument determines which of roots // the closure is applied to: // "SO_None" does none; // "SO_AllClasses" applies the closure to all entries in the SystemDictionary; // "SO_SystemClasses" to all the "system" classes and loaders; - // "SO_Symbols" applies the closure to all entries in SymbolsTable; // "SO_Strings" applies the closure to all entries in StringTable; // "SO_CodeCache" applies the closure to all elements of the CodeCache. void process_strong_roots(bool activate_scope, diff --git a/hotspot/src/share/vm/runtime/vmThread.cpp b/hotspot/src/share/vm/runtime/vmThread.cpp index 68890c7d9de..c50e0a1d7a7 100644 --- a/hotspot/src/share/vm/runtime/vmThread.cpp +++ b/hotspot/src/share/vm/runtime/vmThread.cpp @@ -291,7 +291,9 @@ void VMThread::run() { // Among other things, this ensures that Eden top is correct. Universe::heap()->prepare_for_verify(); os::check_heap(); - Universe::verify(true, true); // Silent verification to not polute normal output + // Silent verification so as not to pollute normal output, + // unless we really asked for it. + Universe::verify(true, !(PrintGCDetails || Verbose)); } CompileBroker::set_should_block(); From 1037728a0377bb71fe0fc6e96374004c34527271 Mon Sep 17 00:00:00 2001 From: Shinya Ogino Date: Tue, 26 Apr 2011 21:46:20 -0700 Subject: [PATCH 36/80] 7036955: Japanese man pages in linux should be in utf-8 encoding Reviewed-by: ohair, mfang --- jdk/make/common/Defs-linux.gmk | 2 +- jdk/make/common/Release.gmk | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/jdk/make/common/Defs-linux.gmk b/jdk/make/common/Defs-linux.gmk index fcaad70af32..ee2f8ca43a4 100644 --- a/jdk/make/common/Defs-linux.gmk +++ b/jdk/make/common/Defs-linux.gmk @@ -355,7 +355,7 @@ HAVE_DPS = no # Japanese manpages # JA_SOURCE_ENCODING = eucJP -JA_TARGET_ENCODINGS = eucJP +JA_TARGET_ENCODINGS = UTF-8 # Settings for the JDI - Serviceability Agent binding. HOTSPOT_SALIB_PATH = $(HOTSPOT_IMPORT_PATH)/jre/lib/$(LIBARCH) diff --git a/jdk/make/common/Release.gmk b/jdk/make/common/Release.gmk index 17297d573b0..defc1453018 100644 --- a/jdk/make/common/Release.gmk +++ b/jdk/make/common/Release.gmk @@ -164,7 +164,7 @@ endif # solaris ifeq ($(PLATFORM), linux) MANBASEDIRS=$(JDK_TOPDIR)/src/linux/doc $(IMPORTDOCDIR) MAN1SUBDIR=man - JA_DIRNAME=ja_JP.$(JA_SOURCE_ENCODING) + JA_DIRNAME=ja_JP.UTF-8 endif # linux define copy-man-pages @@ -190,8 +190,7 @@ for manbase in $(MANBASEDIRS:%=%/$(MAN1SUBDIR)) ; do \ done $(java-vm-cleanup) if [ "$(JA_DIRNAME)" != "" ] ; then \ - $(MV) $1/man/ja $1/man/$(JA_DIRNAME); \ - $(CD) $1/man && $(LN) -s $(JA_DIRNAME) ja; \ + $(CD) $1/man && $(RM) ja && $(LN) -s $(JA_DIRNAME) ja; \ fi endef From d21b9aa7bfc5ac29b551a95466d4e8576f9703e2 Mon Sep 17 00:00:00 2001 From: Andrew Brygin Date: Wed, 27 Apr 2011 12:15:34 +0400 Subject: [PATCH 37/80] 7037091: sun/java2d/pipe/Test7027667.java test is not executed Reviewed-by: prr --- jdk/test/sun/java2d/pipe/Test7027667.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/test/sun/java2d/pipe/Test7027667.java b/jdk/test/sun/java2d/pipe/Test7027667.java index 08f478f60b1..e30c72c0504 100644 --- a/jdk/test/sun/java2d/pipe/Test7027667.java +++ b/jdk/test/sun/java2d/pipe/Test7027667.java @@ -23,7 +23,7 @@ /** * @test - * @bug 7027667, 7023591 + * @bug 7027667 7023591 7037091 * * @summary Verifies that aa clipped rectangles are drawn, not filled. * From aa161ffe8d9b643893b13bed12468f399f71e66d Mon Sep 17 00:00:00 2001 From: Pavel Porvatov Date: Wed, 27 Apr 2011 13:43:22 +0400 Subject: [PATCH 38/80] 7039403: Could not compile test/javax/swing/JLabel/6596966/bug6596966.java Reviewed-by: malenkov --- jdk/test/javax/swing/JLabel/6596966/bug6596966.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/jdk/test/javax/swing/JLabel/6596966/bug6596966.java b/jdk/test/javax/swing/JLabel/6596966/bug6596966.java index 5cf0110f700..5e94459bcb7 100644 --- a/jdk/test/javax/swing/JLabel/6596966/bug6596966.java +++ b/jdk/test/javax/swing/JLabel/6596966/bug6596966.java @@ -24,13 +24,13 @@ /* @test @bug 6596966 @summary Some JFileChooser mnemonics do not work with sticky keys - * @library ../../regtesthelpers - * @build Util @run main bug6596966 @author Pavel Porvatov */ +import sun.awt.SunToolkit; + import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; @@ -44,6 +44,7 @@ public class bug6596966 { public static void main(String[] args) throws Exception { Robot robot = new Robot(); + SunToolkit toolkit = (SunToolkit) SunToolkit.getDefaultToolkit(); SwingUtilities.invokeAndWait(new Runnable() { public void run() { @@ -68,17 +69,17 @@ public class bug6596966 { } }); - Util.blockTillDisplayed(frame); + toolkit.realSync(); robot.keyPress(KeyEvent.VK_ALT); robot.keyPress(KeyEvent.VK_L); - robot.waitForIdle(); + toolkit.realSync(); - Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(new KeyEvent(label, KeyEvent.KEY_RELEASED, + toolkit.getSystemEventQueue().postEvent(new KeyEvent(label, KeyEvent.KEY_RELEASED, EventQueue.getMostRecentEventTime(), 0, KeyEvent.VK_L, 'L')); - robot.waitForIdle(); + toolkit.realSync(); try { SwingUtilities.invokeAndWait(new Runnable() { From f5afc05e608009a6805b59072f44a983c1b81350 Mon Sep 17 00:00:00 2001 From: Denis Fokin Date: Wed, 27 Apr 2011 14:58:40 +0400 Subject: [PATCH 39/80] 7020922: java.awt.Toolkit.getPropertyChangeListeners() should mention that it returns proxies Reviewed-by: malenkov --- jdk/src/share/classes/java/awt/Toolkit.java | 40 ++++++++++++++------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/jdk/src/share/classes/java/awt/Toolkit.java b/jdk/src/share/classes/java/awt/Toolkit.java index 58a4ddc7b4f..6e00e6afdbf 100644 --- a/jdk/src/share/classes/java/awt/Toolkit.java +++ b/jdk/src/share/classes/java/awt/Toolkit.java @@ -1870,11 +1870,15 @@ public abstract class Toolkit { /** * Adds the specified property change listener for the named desktop - * property. - * If pcl is null, no exception is thrown and no action is performed. + * property. When a {@link PropertyChangeListenerProxy} object is added, + * its property name is ignored, and the wrapped listener is added. + * If {@code name} is {@code null} or {@code pcl} is {@code null}, + * no exception is thrown and no action is performed. * * @param name The name of the property to listen for * @param pcl The property change listener + * @see PropertyChangeSupport#addPropertyChangeListener(String, + PropertyChangeListener) * @since 1.2 */ public void addPropertyChangeListener(String name, PropertyChangeListener pcl) { @@ -1883,11 +1887,16 @@ public abstract class Toolkit { /** * Removes the specified property change listener for the named - * desktop property. - * If pcl is null, no exception is thrown and no action is performed. + * desktop property. When a {@link PropertyChangeListenerProxy} object + * is removed, its property name is ignored, and + * the wrapped listener is removed. + * If {@code name} is {@code null} or {@code pcl} is {@code null}, + * no exception is thrown and no action is performed. * * @param name The name of the property to remove * @param pcl The property change listener + * @see PropertyChangeSupport#removePropertyChangeListener(String, + PropertyChangeListener) * @since 1.2 */ public void removePropertyChangeListener(String name, PropertyChangeListener pcl) { @@ -1896,12 +1905,15 @@ public abstract class Toolkit { /** * Returns an array of all the property change listeners - * registered on this toolkit. + * registered on this toolkit. The returned array + * contains {@code PropertyChangeListenerProxy} objects + * that associate listeners with the names of desktop properties. * - * @return all of this toolkit's PropertyChangeListeners - * or an empty array if no property change - * listeners are currently registered + * @return all of this toolkit's {@ code PropertyChangeListener} + * objects wrapped in {@code PropertyChangeListenerProxy} objects + * or an empty array if no listeners are added * + * @see PropertyChangeSupport#getPropertyChangeListeners() * @since 1.4 */ public PropertyChangeListener[] getPropertyChangeListeners() { @@ -1909,13 +1921,15 @@ public abstract class Toolkit { } /** - * Returns an array of all the PropertyChangeListeners - * associated with the named property. + * Returns an array of all property change listeners + * associated with the specified name of a desktop property. * * @param propertyName the named property - * @return all of the PropertyChangeListeners associated with - * the named property or an empty array if no such listeners have - * been added + * @return all of the {@code PropertyChangeListener} objects + * associated with the specified name of a desktop property + * or an empty array if no such listeners are added + * + * @see PropertyChangeSupport#getPropertyChangeListeners(String) * @since 1.4 */ public PropertyChangeListener[] getPropertyChangeListeners(String propertyName) { From 57f34d2482bcdc2c4636cc64b5072af3e03e930f Mon Sep 17 00:00:00 2001 From: Oleg Pekhovskiy Date: Wed, 27 Apr 2011 15:26:38 +0400 Subject: [PATCH 40/80] 7035209: 6u26 ea b01 - running an applet with old plugin crashes in awt.dll Reviewed-by: art, amenkov --- jdk/src/windows/native/sun/java2d/d3d/D3DPipelineManager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/src/windows/native/sun/java2d/d3d/D3DPipelineManager.cpp b/jdk/src/windows/native/sun/java2d/d3d/D3DPipelineManager.cpp index a7da3f3b38c..a563c78802b 100644 --- a/jdk/src/windows/native/sun/java2d/d3d/D3DPipelineManager.cpp +++ b/jdk/src/windows/native/sun/java2d/d3d/D3DPipelineManager.cpp @@ -187,6 +187,7 @@ void D3DPipelineManager::NotifyAdapterEventListeners(UINT adapter, } JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); + RETURN_IF_NULL(env); pMgr = D3DPipelineManager::GetInstance(); RETURN_IF_NULL(pMgr); From ed12b2ab1870adf1e80c6c9d03b6ce77f29b2f4d Mon Sep 17 00:00:00 2001 From: Denis Fokin Date: Wed, 27 Apr 2011 17:18:38 +0400 Subject: [PATCH 41/80] 6998716: client vm crashes making browser fails to respond under some scenarios Reviewed-by: art, denis, uta --- .../windows/native/sun/windows/ObjectList.cpp | 7 +++-- .../windows/native/sun/windows/ObjectList.h | 2 +- .../native/sun/windows/awt_Component.cpp | 7 ++--- .../native/sun/windows/awt_MenuItem.cpp | 3 +-- .../windows/native/sun/windows/awt_Object.cpp | 19 +++++++++----- .../windows/native/sun/windows/awt_Object.h | 4 +++ .../windows/native/sun/windows/awt_Robot.cpp | 3 +-- .../native/sun/windows/awt_Toolkit.cpp | 26 +++++++++++++++---- .../native/sun/windows/awt_TrayIcon.cpp | 3 +-- jdk/src/windows/native/sun/windows/awtmsg.h | 1 + 10 files changed, 51 insertions(+), 24 deletions(-) diff --git a/jdk/src/windows/native/sun/windows/ObjectList.cpp b/jdk/src/windows/native/sun/windows/ObjectList.cpp index b0614e6b97f..601c42ce2e3 100644 --- a/jdk/src/windows/native/sun/windows/ObjectList.cpp +++ b/jdk/src/windows/native/sun/windows/ObjectList.cpp @@ -48,7 +48,7 @@ void AwtObjectList::Add(AwtObject* obj) m_head = item; } -void AwtObjectList::Remove(AwtObject* obj) +BOOL AwtObjectList::Remove(AwtObject* obj) { CriticalSection::Lock l(m_lock); @@ -64,11 +64,14 @@ void AwtObjectList::Remove(AwtObject* obj) } DASSERT(item != NULL); delete item; - return; + return TRUE; } lastItem = item; item = item->next; } + + return FALSE; + // DASSERT(FALSE); // should never get here... // even if it does it shouldn't be fatal. } diff --git a/jdk/src/windows/native/sun/windows/ObjectList.h b/jdk/src/windows/native/sun/windows/ObjectList.h index 9775d0c9f1e..1e80732ca39 100644 --- a/jdk/src/windows/native/sun/windows/ObjectList.h +++ b/jdk/src/windows/native/sun/windows/ObjectList.h @@ -46,7 +46,7 @@ public: AwtObjectList(); void Add(AwtObject* obj); - void Remove(AwtObject* obj); + BOOL Remove(AwtObject* obj); #ifdef DEBUG /* Used for sanity checks only. */ AwtObject* LookUp(AwtObject* obj); diff --git a/jdk/src/windows/native/sun/windows/awt_Component.cpp b/jdk/src/windows/native/sun/windows/awt_Component.cpp index fd75b8d52ee..592a9b434b2 100644 --- a/jdk/src/windows/native/sun/windows/awt_Component.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp @@ -1969,7 +1969,9 @@ MsgRouting AwtComponent::WmDestroy() { // fix for 6259348: we should enter the SyncCall critical section before // disposing the native object, that is value 1 of lParam is intended for - AwtToolkit::GetInstance().SendMessage(WM_AWT_DISPOSE, (WPARAM)this, (LPARAM)1); + if(m_peerObject != NULL) { // is not being terminating + AwtToolkit::GetInstance().SendMessage(WM_AWT_DISPOSE, (WPARAM)m_peerObject, (LPARAM)1); + } return mrConsume; } @@ -6534,8 +6536,7 @@ Java_sun_awt_windows_WComponentPeer__1dispose(JNIEnv *env, jobject self) { TRY_NO_HANG; - PDATA pData = JNI_GET_PDATA(self); - AwtObject::_Dispose(pData); + AwtObject::_Dispose(self); CATCH_BAD_ALLOC; } diff --git a/jdk/src/windows/native/sun/windows/awt_MenuItem.cpp b/jdk/src/windows/native/sun/windows/awt_MenuItem.cpp index aeb1021262a..97f3e2a7a21 100644 --- a/jdk/src/windows/native/sun/windows/awt_MenuItem.cpp +++ b/jdk/src/windows/native/sun/windows/awt_MenuItem.cpp @@ -974,8 +974,7 @@ Java_sun_awt_windows_WMenuItemPeer__1dispose(JNIEnv *env, jobject self) { TRY_NO_HANG; - PDATA pData = JNI_GET_PDATA(self); - AwtObject::_Dispose(pData); + AwtObject::_Dispose(self); CATCH_BAD_ALLOC; } diff --git a/jdk/src/windows/native/sun/windows/awt_Object.cpp b/jdk/src/windows/native/sun/windows/awt_Object.cpp index b7afe1aa510..54ec69a9a19 100644 --- a/jdk/src/windows/native/sun/windows/awt_Object.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Object.cpp @@ -60,11 +60,20 @@ AwtObject::~AwtObject() void AwtObject::Dispose() { - theAwtObjectList.Remove(this); + AwtToolkit::GetInstance().PostMessage(WM_AWT_DELETEOBJECT, (WPARAM)this, (LPARAM)0); +} + +void AwtObject::_Dispose(jobject self) +{ + TRY_NO_VERIFY; + + CriticalSection::Lock l(AwtToolkit::GetInstance().GetSyncCS()); // value 0 of lParam means that we should not attempt to enter the // SyncCall critical section, as it was entered someshere earlier - AwtToolkit::GetInstance().PostMessage(WM_AWT_DELETEOBJECT, (WPARAM)this, (LPARAM)0); + AwtToolkit::GetInstance().SendMessage(WM_AWT_DISPOSE, (WPARAM)self, (LPARAM)0); + + CATCH_BAD_ALLOC; } void AwtObject::_Dispose(PDATA pData) @@ -73,14 +82,10 @@ void AwtObject::_Dispose(PDATA pData) CriticalSection::Lock l(AwtToolkit::GetInstance().GetSyncCS()); - if (pData != NULL) { - AwtObject *o = (AwtObject *)pData; - AwtToolkit::GetInstance().SendMessage(WM_AWT_DISPOSE, (WPARAM)o, (LPARAM)0); - } + AwtToolkit::GetInstance().SendMessage(WM_AWT_DISPOSEPDATA, (WPARAM)pData, (LPARAM)0); CATCH_BAD_ALLOC; } - /* * Return the peer associated with some target. This information is * maintained in a hashtable at the java level. diff --git a/jdk/src/windows/native/sun/windows/awt_Object.h b/jdk/src/windows/native/sun/windows/awt_Object.h index 6cfb83ebcc5..918e95d1c18 100644 --- a/jdk/src/windows/native/sun/windows/awt_Object.h +++ b/jdk/src/windows/native/sun/windows/awt_Object.h @@ -66,6 +66,10 @@ public: // After this method has been called, this object must not be used in any way. virtual void Dispose(); + // Static method to be called from JNI methods to dispose AwtObject + // specified by jobject + static void _Dispose(jobject self); + // Static method to be called from JNI methods to dispose AwtObject // specified by pData static void _Dispose(PDATA pData); diff --git a/jdk/src/windows/native/sun/windows/awt_Robot.cpp b/jdk/src/windows/native/sun/windows/awt_Robot.cpp index cdee9cf6001..09e12debf38 100644 --- a/jdk/src/windows/native/sun/windows/awt_Robot.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Robot.cpp @@ -353,8 +353,7 @@ JNIEXPORT void JNICALL Java_sun_awt_windows_WRobotPeer__1dispose( { TRY_NO_VERIFY; - PDATA pData = JNI_GET_PDATA(self); - AwtObject::_Dispose(pData); + AwtObject::_Dispose(self); CATCH_BAD_ALLOC; } diff --git a/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp b/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp index ca2bae8325a..d010d6b130c 100644 --- a/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Toolkit.cpp @@ -740,18 +740,34 @@ LRESULT CALLBACK AwtToolkit::WndProc(HWND hWnd, UINT message, canDispose = syncCS.TryEnter(); } if (canDispose) { - AwtObject *o = (AwtObject *)wParam; - o->Dispose(); - if (shouldEnterCriticalSection) { - syncCS.Leave(); + if(wParam != NULL) { + AwtObject *o = (AwtObject *) JNI_GET_PDATA((jobject)wParam); + if(o != NULL && theAwtObjectList.Remove(o)) { + o->Dispose(); + } + if (shouldEnterCriticalSection) { + syncCS.Leave(); + } } } else { AwtToolkit::GetInstance().PostMessage(WM_AWT_DISPOSE, wParam, lParam); } return 0; } + case WM_AWT_DISPOSEPDATA: { + /* + * NOTE: synchronization routine (like in WM_AWT_DISPOSE) was omitted because + * this handler is called ONLY while disposing Cursor and Font objects where + * synchronization takes place. + */ + AwtObject *o = (AwtObject *) wParam; + if(o != NULL && theAwtObjectList.Remove(o)) { + o->Dispose(); + } + return 0; + } case WM_AWT_DELETEOBJECT: { - AwtObject *p = (AwtObject *)wParam; + AwtObject *p = (AwtObject *) wParam; if (p->CanBeDeleted()) { // all the messages for this component are processed, so // it can be deleted diff --git a/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp b/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp index 4156c9cfec1..c2682b3b113 100644 --- a/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp +++ b/jdk/src/windows/native/sun/windows/awt_TrayIcon.cpp @@ -926,8 +926,7 @@ Java_sun_awt_windows_WTrayIconPeer__1dispose(JNIEnv *env, jobject self) { TRY; - PDATA pData = JNI_GET_PDATA(self); - AwtObject::_Dispose(pData); + AwtObject::_Dispose(self); CATCH_BAD_ALLOC; } diff --git a/jdk/src/windows/native/sun/windows/awtmsg.h b/jdk/src/windows/native/sun/windows/awtmsg.h index 898471b4923..05733c7a6f0 100644 --- a/jdk/src/windows/native/sun/windows/awtmsg.h +++ b/jdk/src/windows/native/sun/windows/awtmsg.h @@ -219,6 +219,7 @@ enum { WM_AWT_ENDCOMPOSITION, WM_AWT_DISPOSE, + WM_AWT_DISPOSEPDATA, WM_AWT_DELETEOBJECT, WM_AWT_SETCONVERSIONSTATUS, WM_AWT_GETCONVERSIONSTATUS, From 1f4f92b81d50cfdd03dbfa9263ad55808a547139 Mon Sep 17 00:00:00 2001 From: Andrei Dmitriev Date: Wed, 27 Apr 2011 17:46:59 +0400 Subject: [PATCH 42/80] 6888633: test/closed/javax/swing/JPopupMenu/4786415/bug4786415.java fails Reviewed-by: rupashka, alexp --- jdk/src/share/classes/javax/swing/JPopupMenu.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/classes/javax/swing/JPopupMenu.java b/jdk/src/share/classes/javax/swing/JPopupMenu.java index 24a9d4cf6c5..53926e4a744 100644 --- a/jdk/src/share/classes/javax/swing/JPopupMenu.java +++ b/jdk/src/share/classes/javax/swing/JPopupMenu.java @@ -342,8 +342,8 @@ public class JPopupMenu extends JComponent implements Accessible,MenuElement { // Calculate the screen size that popup should fit Dimension popupSize = JPopupMenu.this.getPreferredSize(); - int popupRightX = popupLocation.x + popupSize.width; - int popupBottomY = popupLocation.y + popupSize.height; + long popupRightX = (long)popupLocation.x + (long)popupSize.width; + long popupBottomY = (long)popupLocation.y + (long)popupSize.height; int scrWidth = scrBounds.width; int scrHeight = scrBounds.height; if (!canPopupOverlapTaskBar()) { @@ -358,13 +358,13 @@ public class JPopupMenu extends JComponent implements Accessible,MenuElement { int scrBottomY = scrBounds.y + scrHeight; // Ensure that popup menu fits the screen - if (popupRightX > scrRightX) { + if (popupRightX > (long)scrRightX) { popupLocation.x = scrRightX - popupSize.width; if( popupLocation.x < scrBounds.x ) { popupLocation.x = scrBounds.x ; } } - if (popupBottomY > scrBottomY) { + if (popupBottomY > (long)scrBottomY) { popupLocation.y = scrBottomY - popupSize.height; if( popupLocation.y < scrBounds.y ) { popupLocation.y = scrBounds.y; From b44f91dc52db004e35fcce686f8c45181220b5cc Mon Sep 17 00:00:00 2001 From: Andrei Dmitriev Date: Wed, 27 Apr 2011 18:15:27 +0400 Subject: [PATCH 43/80] 6979551: closed/javax/swing/plaf/basic/BasicLabelUI/4798542/bug4798542.java fails Reviewed-by: art, yan, alexp --- .../classes/sun/awt/ExtendedKeyCodes.java | 17 +++++- .../keyboard/EqualKeyCode/EqualKeyCode.java | 61 +++++++++++++++++++ 2 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 jdk/test/java/awt/keyboard/EqualKeyCode/EqualKeyCode.java diff --git a/jdk/src/share/classes/sun/awt/ExtendedKeyCodes.java b/jdk/src/share/classes/sun/awt/ExtendedKeyCodes.java index d6d72ac4ad7..fc004ba2a28 100644 --- a/jdk/src/share/classes/sun/awt/ExtendedKeyCodes.java +++ b/jdk/src/share/classes/sun/awt/ExtendedKeyCodes.java @@ -13,7 +13,7 @@ public class ExtendedKeyCodes { */ // Keycodes declared in KeyEvent.java with corresponding Unicode values. private final static HashMap regularKeyCodesMap = - new HashMap(83, 1.0f); + new HashMap(98, 1.0f); // Keycodes derived from Unicode values. Here should be collected codes // for characters appearing on the primary layer of at least one @@ -108,6 +108,21 @@ public class ExtendedKeyCodes { regularKeyCodesMap.put(0x5E, KeyEvent.VK_CIRCUMFLEX); regularKeyCodesMap.put(0x5F, KeyEvent.VK_UNDERSCORE); regularKeyCodesMap.put(0x60, KeyEvent.VK_BACK_QUOTE); + regularKeyCodesMap.put(0x61, KeyEvent.VK_A); + regularKeyCodesMap.put(0x62, KeyEvent.VK_B); + regularKeyCodesMap.put(0x63, KeyEvent.VK_C); + regularKeyCodesMap.put(0x64, KeyEvent.VK_D); + regularKeyCodesMap.put(0x65, KeyEvent.VK_E); + regularKeyCodesMap.put(0x66, KeyEvent.VK_F); + regularKeyCodesMap.put(0x67, KeyEvent.VK_G); + regularKeyCodesMap.put(0x68, KeyEvent.VK_H); + regularKeyCodesMap.put(0x69, KeyEvent.VK_I); + regularKeyCodesMap.put(0x6A, KeyEvent.VK_J); + regularKeyCodesMap.put(0x6B, KeyEvent.VK_K); + regularKeyCodesMap.put(0x6C, KeyEvent.VK_L); + regularKeyCodesMap.put(0x6D, KeyEvent.VK_M); + regularKeyCodesMap.put(0x6E, KeyEvent.VK_N); + regularKeyCodesMap.put(0x6F, KeyEvent.VK_O); regularKeyCodesMap.put(0x70, KeyEvent.VK_P); regularKeyCodesMap.put(0x71, KeyEvent.VK_Q); regularKeyCodesMap.put(0x72, KeyEvent.VK_R); diff --git a/jdk/test/java/awt/keyboard/EqualKeyCode/EqualKeyCode.java b/jdk/test/java/awt/keyboard/EqualKeyCode/EqualKeyCode.java new file mode 100644 index 00000000000..d4acc95ef2b --- /dev/null +++ b/jdk/test/java/awt/keyboard/EqualKeyCode/EqualKeyCode.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 6799551 + @library ../../regtesthelpers + @build Util Sysout + @summary Extended key codes for small letters undefined + @author Andrei Dmitriev: area=awt.keyboard + @run main EqualKeyCode +*/ + + +import sun.awt.*; +import java.awt.*; +import test.java.awt.regtesthelpers.Util; +import test.java.awt.regtesthelpers.Sysout; + +public class EqualKeyCode { + + final static String LETTERS = "abcdefghijklmnopqrstuvwxyz"; + + public static void main(String []s) { + for (int i = 0; i < LETTERS.length(); i++){ + char cSmall = LETTERS.charAt(i); + char cLarge = Character.toUpperCase(cSmall); + + int iSmall = ExtendedKeyCodes.getExtendedKeyCodeForChar(cSmall); + int iLarge = ExtendedKeyCodes.getExtendedKeyCodeForChar(cLarge); + + System.out.print(" " + cSmall + ":" + iSmall + " ---- "); + System.out.println(" " + cLarge + " : " + iLarge); + if (ExtendedKeyCodes.getExtendedKeyCodeForChar(cSmall) != + ExtendedKeyCodes.getExtendedKeyCodeForChar(cLarge)) + { + throw new RuntimeException("ExtendedKeyCode doesn't exist or doesn't match between capital and small letters."); + } + } + } +} From b777d36af8690ab82115c32091c22a04fe61af4e Mon Sep 17 00:00:00 2001 From: John Cuthbertson Date: Wed, 27 Apr 2011 14:40:41 -0700 Subject: [PATCH 44/80] 7037756: Deadlock in compiler thread similiar to 6789220 Avoid blocking in CompileBroker::compile_method_base() if the current thread holds the pending list lock. Reviewed-by: never, brutisso, ysr --- .../src/share/vm/compiler/compileBroker.cpp | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/hotspot/src/share/vm/compiler/compileBroker.cpp b/hotspot/src/share/vm/compiler/compileBroker.cpp index 6c2a9683d5c..9626d444645 100644 --- a/hotspot/src/share/vm/compiler/compileBroker.cpp +++ b/hotspot/src/share/vm/compiler/compileBroker.cpp @@ -976,6 +976,15 @@ void CompileBroker::compile_method_base(methodHandle method, return; } + // If the requesting thread is holding the pending list lock + // then we just return. We can't risk blocking while holding + // the pending list lock or a 3-way deadlock may occur + // between the reference handler thread, a GC (instigated + // by a compiler thread), and compiled method registration. + if (instanceRefKlass::owns_pending_list_lock(JavaThread::current())) { + return; + } + // Outputs from the following MutexLocker block: CompileTask* task = NULL; bool blocking = false; @@ -1304,17 +1313,8 @@ uint CompileBroker::assign_compile_id(methodHandle method, int osr_bci) { // Should the current thread be blocked until this compilation request // has been fulfilled? bool CompileBroker::is_compile_blocking(methodHandle method, int osr_bci) { - if (!BackgroundCompilation) { - Symbol* class_name = method->method_holder()->klass_part()->name(); - if (class_name->starts_with("java/lang/ref/Reference", 23)) { - // The reference handler thread can dead lock with the GC if compilation is blocking, - // so we avoid blocking compiles for anything in the java.lang.ref.Reference class, - // including inner classes such as ReferenceHandler. - return false; - } - return true; - } - return false; + assert(!instanceRefKlass::owns_pending_list_lock(JavaThread::current()), "possible deadlock"); + return !BackgroundCompilation; } From 2126589fd09161d68dcb2b6946f8a4349e47ddd3 Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Wed, 27 Apr 2011 15:40:36 -0700 Subject: [PATCH 45/80] 7029167: add support for conditional card marks Reviewed-by: iveresov, kvn --- hotspot/src/share/vm/opto/graphKit.cpp | 21 +++++++++++++++++++-- hotspot/src/share/vm/opto/macro.cpp | 13 ++++++++++--- hotspot/src/share/vm/runtime/globals.hpp | 3 +++ 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/hotspot/src/share/vm/opto/graphKit.cpp b/hotspot/src/share/vm/opto/graphKit.cpp index e1612b843dc..4df08199075 100644 --- a/hotspot/src/share/vm/opto/graphKit.cpp +++ b/hotspot/src/share/vm/opto/graphKit.cpp @@ -3447,9 +3447,22 @@ void GraphKit::write_barrier_post(Node* oop_store, // Get the alias_index for raw card-mark memory int adr_type = Compile::AliasIdxRaw; - // Smash zero into card - Node* zero = __ ConI(0); + Node* zero = __ ConI(0); // Dirty card value BasicType bt = T_BYTE; + + if (UseCondCardMark) { + // The classic GC reference write barrier is typically implemented + // as a store into the global card mark table. Unfortunately + // unconditional stores can result in false sharing and excessive + // coherence traffic as well as false transactional aborts. + // UseCondCardMark enables MP "polite" conditional card mark + // stores. In theory we could relax the load from ctrl() to + // no_ctrl, but that doesn't buy much latitude. + Node* card_val = __ load( __ ctrl(), card_adr, TypeInt::BYTE, bt, adr_type); + __ if_then(card_val, BoolTest::ne, zero); + } + + // Smash zero into card if( !UseConcMarkSweepGC ) { __ store(__ ctrl(), card_adr, zero, bt, adr_type); } else { @@ -3457,6 +3470,10 @@ void GraphKit::write_barrier_post(Node* oop_store, __ storeCM(__ ctrl(), card_adr, zero, oop_store, adr_idx, bt, adr_type); } + if (UseCondCardMark) { + __ end_if(); + } + // Final sync IdealKit and GraphKit. final_sync(ideal); } diff --git a/hotspot/src/share/vm/opto/macro.cpp b/hotspot/src/share/vm/opto/macro.cpp index 465c8babdd5..a35f3342ba4 100644 --- a/hotspot/src/share/vm/opto/macro.cpp +++ b/hotspot/src/share/vm/opto/macro.cpp @@ -221,9 +221,16 @@ void PhaseMacroExpand::eliminate_card_mark(Node* p2x) { Node *shift = p2x->unique_out(); Node *addp = shift->unique_out(); for (DUIterator_Last jmin, j = addp->last_outs(jmin); j >= jmin; --j) { - Node *st = addp->last_out(j); - assert(st->is_Store(), "store required"); - _igvn.replace_node(st, st->in(MemNode::Memory)); + Node *mem = addp->last_out(j); + if (UseCondCardMark && mem->is_Load()) { + assert(mem->Opcode() == Op_LoadB, "unexpected code shape"); + // The load is checking if the card has been written so + // replace it with zero to fold the test. + _igvn.replace_node(mem, intcon(0)); + continue; + } + assert(mem->is_Store(), "store required"); + _igvn.replace_node(mem, mem->in(MemNode::Memory)); } } else { // G1 pre/post barriers diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index 96f0abbb061..eb5bec20015 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -620,6 +620,9 @@ class CommandLineFlags { product(bool, UseSSE42Intrinsics, false, \ "SSE4.2 versions of intrinsics") \ \ + product(bool, UseCondCardMark, false, \ + "Check for already marked card before updating card table") \ + \ develop(bool, TraceCallFixup, false, \ "traces all call fixups") \ \ From 00ac2f30b88a8376835135beae6bf1d9ab6ce46d Mon Sep 17 00:00:00 2001 From: Michael Fang Date: Wed, 27 Apr 2011 23:11:48 -0700 Subject: [PATCH 46/80] 6501385: ColorChooser demo - two elemets have same mnemonic in it locale, GTK L&F Reviewed-by: yhuang --- .../com/sun/java/swing/plaf/gtk/resources/gtk_de.properties | 2 +- .../com/sun/java/swing/plaf/gtk/resources/gtk_es.properties | 2 +- .../com/sun/java/swing/plaf/gtk/resources/gtk_fr.properties | 2 +- .../com/sun/java/swing/plaf/gtk/resources/gtk_it.properties | 2 +- .../com/sun/java/swing/plaf/gtk/resources/gtk_pt_BR.properties | 2 +- .../com/sun/java/swing/plaf/gtk/resources/gtk_sv.properties | 2 +- .../sun/swing/internal/plaf/basic/resources/basic_sv.properties | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_de.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_de.properties index 571bc0afae3..3edb256c427 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_de.properties +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_de.properties @@ -24,7 +24,7 @@ GTKColorChooserPanel.hueText=Farbton: GTKColorChooserPanel.hueMnemonic=70 GTKColorChooserPanel.redText=Rot: -GTKColorChooserPanel.redMnemonic=79 +GTKColorChooserPanel.redMnemonic=82 GTKColorChooserPanel.saturationText=S\u00E4ttigung: GTKColorChooserPanel.saturationMnemonic=83 diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_es.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_es.properties index 6daa4d9b441..4766de9167e 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_es.properties +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_es.properties @@ -30,7 +30,7 @@ GTKColorChooserPanel.saturationText=Saturaci\u00F3n: GTKColorChooserPanel.saturationMnemonic=83 GTKColorChooserPanel.greenText=Verde: -GTKColorChooserPanel.greenMnemonic=86 +GTKColorChooserPanel.greenMnemonic=69 GTKColorChooserPanel.valueText=Valor: GTKColorChooserPanel.valueMnemonic=86 diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_fr.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_fr.properties index 9f4e0e559f7..68f07d2e469 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_fr.properties +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_fr.properties @@ -30,7 +30,7 @@ GTKColorChooserPanel.saturationText=Saturation : GTKColorChooserPanel.saturationMnemonic=83 GTKColorChooserPanel.greenText=Vert : -GTKColorChooserPanel.greenMnemonic=86 +GTKColorChooserPanel.greenMnemonic=69 GTKColorChooserPanel.valueText=Valeur : GTKColorChooserPanel.valueMnemonic=86 diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_it.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_it.properties index 21cd8f77826..70146898dac 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_it.properties +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_it.properties @@ -30,7 +30,7 @@ GTKColorChooserPanel.saturationText=Saturazione: GTKColorChooserPanel.saturationMnemonic=83 GTKColorChooserPanel.greenText=Verde: -GTKColorChooserPanel.greenMnemonic=86 +GTKColorChooserPanel.greenMnemonic=69 GTKColorChooserPanel.valueText=Valore: GTKColorChooserPanel.valueMnemonic=86 diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_pt_BR.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_pt_BR.properties index 6fb63b6764f..35a510d9947 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_pt_BR.properties +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_pt_BR.properties @@ -30,7 +30,7 @@ GTKColorChooserPanel.saturationText=Satura\u00E7\u00E3o: GTKColorChooserPanel.saturationMnemonic=83 GTKColorChooserPanel.greenText=Verde: -GTKColorChooserPanel.greenMnemonic=86 +GTKColorChooserPanel.greenMnemonic=68 GTKColorChooserPanel.valueText=Valor: GTKColorChooserPanel.valueMnemonic=86 diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_sv.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_sv.properties index cfde4686b9b..9dda1e0a50f 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_sv.properties +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_sv.properties @@ -39,7 +39,7 @@ GTKColorChooserPanel.blueText=Bl\u00E5: GTKColorChooserPanel.blueMnemonic=66 GTKColorChooserPanel.colorNameText=F\u00E4rgnamn: -GTKColorChooserPanel.colorNameMnemonic=78 +GTKColorChooserPanel.colorNameMnemonic=70 diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_sv.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_sv.properties index fef16139cf4..c28dfbd7ca8 100644 --- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_sv.properties +++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_sv.properties @@ -96,7 +96,7 @@ ColorChooser.okText=OK ColorChooser.cancelText=Avbryt ColorChooser.resetText=\u00C5terst\u00E4ll # VK_XXX constant for 'ColorChooser.resetText' button to make mnemonic -ColorChooser.resetMnemonic=82 +ColorChooser.resetMnemonic=84 ColorChooser.sampleText=Exempeltext Exempeltext ColorChooser.swatchesNameText=Prov ColorChooser.swatchesMnemonic=80 From 7d2260eaa5bd1b081046617687ad4a56ed218dd7 Mon Sep 17 00:00:00 2001 From: Michael Fang Date: Wed, 27 Apr 2011 23:18:20 -0700 Subject: [PATCH 47/80] 7038803: [CCJK] Incorrect mnemonic key (0) is displayed on cancel button on messagedialog of JOptionPane Reviewed-by: yhuang --- .../sun/swing/internal/plaf/basic/resources/basic.properties | 4 ++-- .../swing/internal/plaf/basic/resources/basic_ja.properties | 2 +- .../swing/internal/plaf/basic/resources/basic_ko.properties | 2 +- .../internal/plaf/basic/resources/basic_zh_CN.properties | 2 +- .../internal/plaf/basic/resources/basic_zh_TW.properties | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic.properties index 87e3bde708e..549e5cfc853 100644 --- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic.properties +++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic.properties @@ -146,9 +146,9 @@ OptionPane.yesButtonMnemonic=89 OptionPane.noButtonText=No OptionPane.noButtonMnemonic=78 OptionPane.okButtonText=OK -OptionPane.okButtonMnemonic=0 +#OptionPane.okButtonMnemonic=0 OptionPane.cancelButtonText=Cancel -OptionPane.cancelButtonMnemonic=0 +#OptionPane.cancelButtonMnemonic=0 OptionPane.titleText=Select an Option # Title for the dialog for the showInputDialog methods. Only used if # the developer uses one of the variants that doesn't take a title. diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ja.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ja.properties index 9382e0abc04..6a01a4ae528 100644 --- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ja.properties +++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ja.properties @@ -146,7 +146,7 @@ OptionPane.noButtonText=\u3044\u3044\u3048(N) OptionPane.noButtonMnemonic=78 OptionPane.okButtonText=OK OptionPane.okButtonMnemonic=O -OptionPane.cancelButtonText=\u53D6\u6D88(0) +OptionPane.cancelButtonText=\u53D6\u6D88 OptionPane.cancelButtonMnemonic=0 OptionPane.titleText=\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u9078\u629E # Title for the dialog for the showInputDialog methods. Only used if diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties index b8f70de37ff..970e57bf375 100644 --- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties +++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties @@ -146,7 +146,7 @@ OptionPane.noButtonText=\uC544\uB2C8\uC624(N) OptionPane.noButtonMnemonic=78 OptionPane.okButtonText=OK OptionPane.okButtonMnemonic=O -OptionPane.cancelButtonText=\uCDE8\uC18C(0) +OptionPane.cancelButtonText=\uCDE8\uC18C OptionPane.cancelButtonMnemonic=0 OptionPane.titleText=\uC635\uC158 \uC120\uD0DD # Title for the dialog for the showInputDialog methods. Only used if diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_CN.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_CN.properties index 212b1753539..0714ac53c35 100644 --- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_CN.properties +++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_CN.properties @@ -146,7 +146,7 @@ OptionPane.noButtonText=\u5426(N) OptionPane.noButtonMnemonic=78 OptionPane.okButtonText=OK OptionPane.okButtonMnemonic=O -OptionPane.cancelButtonText=\u53D6\u6D88(0) +OptionPane.cancelButtonText=\u53D6\u6D88 OptionPane.cancelButtonMnemonic=0 OptionPane.titleText=\u9009\u62E9\u4E00\u4E2A\u9009\u9879 # Title for the dialog for the showInputDialog methods. Only used if diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_TW.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_TW.properties index ef267aaf8c5..141938565c9 100644 --- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_TW.properties +++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_TW.properties @@ -146,7 +146,7 @@ OptionPane.noButtonText=\u5426(N) OptionPane.noButtonMnemonic=78 OptionPane.okButtonText=OK OptionPane.okButtonMnemonic=O -OptionPane.cancelButtonText=\u53D6\u6D88(0) +OptionPane.cancelButtonText=\u53D6\u6D88 OptionPane.cancelButtonMnemonic=0 OptionPane.titleText=\u9078\u53D6\u4E00\u500B\u9078\u9805 # Title for the dialog for the showInputDialog methods. Only used if From 88ddcf5e65d080f143e57965f8171241db96624d Mon Sep 17 00:00:00 2001 From: Dmitry Cherepanov Date: Thu, 28 Apr 2011 13:26:18 +0400 Subject: [PATCH 48/80] 7032830: GraphicsDevice.setFullScreenWindow() works strange for decorated windows on OEL 7016382: GraphicsDevice.setFullScreenWindow() - spec clarification for exclusive mode for dec/undec Frames Reviewed-by: art --- jdk/src/share/classes/java/awt/GraphicsDevice.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/jdk/src/share/classes/java/awt/GraphicsDevice.java b/jdk/src/share/classes/java/awt/GraphicsDevice.java index f3b7cd390a6..b99d7ef8def 100644 --- a/jdk/src/share/classes/java/awt/GraphicsDevice.java +++ b/jdk/src/share/classes/java/awt/GraphicsDevice.java @@ -257,6 +257,11 @@ public abstract class GraphicsDevice { * 1.0f, and the background color alpha is set to 255 (completely opaque). * These values are not restored when returning to windowed mode. *

+ * It is unspecified and platform-dependent how decorated windows operate + * in full-screen mode. For this reason, it is recommended to turn off + * the decorations in a {@code Frame} or {@code Dialog} object by using the + * {@code setUndecorated} method. + *

* When returning to windowed mode from an exclusive full-screen window, * any display changes made by calling {@code setDisplayMode} are * automatically restored to their original state. @@ -272,6 +277,8 @@ public abstract class GraphicsDevice { * @see #setDisplayMode * @see Component#enableInputMethods * @see Component#setVisible + * @see Frame#setUndecorated + * @see Dialog#setUndecorated * * @since 1.4 */ From cf97b67aa29b33791b466ba7bbdce81cb14d512d Mon Sep 17 00:00:00 2001 From: Denis Lila Date: Thu, 28 Apr 2011 08:55:19 -0400 Subject: [PATCH 49/80] 7036754: NaNs in stroked quadratics Check for them and remove them. Reviewed-by: flar --- .../classes/sun/java2d/pisces/Stroker.java | 252 +++++++++--------- jdk/test/sun/java2d/pisces/Test7036754.java | 58 ++++ 2 files changed, 185 insertions(+), 125 deletions(-) create mode 100644 jdk/test/sun/java2d/pisces/Test7036754.java diff --git a/jdk/src/share/classes/sun/java2d/pisces/Stroker.java b/jdk/src/share/classes/sun/java2d/pisces/Stroker.java index dc270c194c8..6d4a4c75ac5 100644 --- a/jdk/src/share/classes/sun/java2d/pisces/Stroker.java +++ b/jdk/src/share/classes/sun/java2d/pisces/Stroker.java @@ -27,6 +27,8 @@ package sun.java2d.pisces; import java.util.Arrays; import java.util.Iterator; +import static java.lang.Math.ulp; +import static java.lang.Math.sqrt; import sun.awt.geom.PathConsumer2D; @@ -130,7 +132,7 @@ final class Stroker implements PathConsumer2D { private static void computeOffset(final float lx, final float ly, final float w, final float[] m) { - final float len = (float)Math.sqrt(lx*lx + ly*ly); + final float len = (float) sqrt(lx*lx + ly*ly); if (len == 0) { m[0] = m[1] = 0; } else { @@ -217,7 +219,7 @@ final class Stroker implements PathConsumer2D { // this normal's length is at least 0.5 and at most sqrt(2)/2 (because // we know the angle of the arc is > 90 degrees). float nx = my - omy, ny = omx - mx; - float nlen = (float)Math.sqrt(nx*nx + ny*ny); + float nlen = (float) sqrt(nx*nx + ny*ny); float scale = lineWidth2/nlen; float mmx = nx * scale, mmy = ny * scale; @@ -246,8 +248,8 @@ final class Stroker implements PathConsumer2D { // define the bezier curve we're computing. // It is computed using the constraints that P1-P0 and P3-P2 are parallel // to the arc tangents at the endpoints, and that |P1-P0|=|P3-P2|. - float cv = (float)((4.0 / 3.0) * Math.sqrt(0.5-cosext2) / - (1.0 + Math.sqrt(cosext2+0.5))); + float cv = (float) ((4.0 / 3.0) * sqrt(0.5-cosext2) / + (1.0 + sqrt(cosext2+0.5))); // if clockwise, we need to negate cv. if (rev) { // rev is equivalent to isCW(omx, omy, mx, my) cv = -cv; @@ -284,28 +286,20 @@ final class Stroker implements PathConsumer2D { false); } - // Return the intersection point of the lines (x0, y0) -> (x1, y1) - // and (x0p, y0p) -> (x1p, y1p) in m[0] and m[1] - private void computeMiter(final float x0, final float y0, - final float x1, final float y1, - final float x0p, final float y0p, - final float x1p, final float y1p, - final float[] m, int off) + // Put the intersection point of the lines (x0, y0) -> (x1, y1) + // and (x0p, y0p) -> (x1p, y1p) in m[off] and m[off+1]. + // If the lines are parallel, it will put a non finite number in m. + private void computeIntersection(final float x0, final float y0, + final float x1, final float y1, + final float x0p, final float y0p, + final float x1p, final float y1p, + final float[] m, int off) { float x10 = x1 - x0; float y10 = y1 - y0; float x10p = x1p - x0p; float y10p = y1p - y0p; - // if this is 0, the lines are parallel. If they go in the - // same direction, there is no intersection so m[off] and - // m[off+1] will contain infinity, so no miter will be drawn. - // If they go in the same direction that means that the start of the - // current segment and the end of the previous segment have the same - // tangent, in which case this method won't even be involved in - // miter drawing because it won't be called by drawMiter (because - // (mx == omx && my == omy) will be true, and drawMiter will return - // immediately). float den = x10*y10p - x10p*y10; float t = x10p*(y0-y0p) - y10p*(x0-x0p); t /= den; @@ -321,7 +315,8 @@ final class Stroker implements PathConsumer2D { { if ((mx == omx && my == omy) || (pdx == 0 && pdy == 0) || - (dx == 0 && dy == 0)) { + (dx == 0 && dy == 0)) + { return; } @@ -332,12 +327,17 @@ final class Stroker implements PathConsumer2D { my = -my; } - computeMiter((x0 - pdx) + omx, (y0 - pdy) + omy, x0 + omx, y0 + omy, - (dx + x0) + mx, (dy + y0) + my, x0 + mx, y0 + my, - miter, 0); + computeIntersection((x0 - pdx) + omx, (y0 - pdy) + omy, x0 + omx, y0 + omy, + (dx + x0) + mx, (dy + y0) + my, x0 + mx, y0 + my, + miter, 0); float lenSq = (miter[0]-x0)*(miter[0]-x0) + (miter[1]-y0)*(miter[1]-y0); + // If the lines are parallel, lenSq will be either NaN or +inf + // (actually, I'm not sure if the latter is possible. The important + // thing is that -inf is not possible, because lenSq is a square). + // For both of those values, the comparison below will fail and + // no miter will be drawn, which is correct. if (lenSq < miterLimitSq) { emitLineTo(miter[0], miter[1], rev); } @@ -566,8 +566,8 @@ final class Stroker implements PathConsumer2D { // if p1 == p2 && p3 == p4: draw line from p1->p4, unless p1 == p4, // in which case ignore if p1 == p2 - final boolean p1eqp2 = within(x1,y1,x2,y2, 6 * Math.ulp(y2)); - final boolean p3eqp4 = within(x3,y3,x4,y4, 6 * Math.ulp(y4)); + final boolean p1eqp2 = within(x1,y1,x2,y2, 6 * ulp(y2)); + final boolean p3eqp4 = within(x3,y3,x4,y4, 6 * ulp(y4)); if (p1eqp2 && p3eqp4) { getLineOffsets(x1, y1, x4, y4, leftOff, rightOff); return 4; @@ -583,7 +583,7 @@ final class Stroker implements PathConsumer2D { float dotsq = (dx1 * dx4 + dy1 * dy4); dotsq = dotsq * dotsq; float l1sq = dx1 * dx1 + dy1 * dy1, l4sq = dx4 * dx4 + dy4 * dy4; - if (Helpers.within(dotsq, l1sq * l4sq, 4 * Math.ulp(dotsq))) { + if (Helpers.within(dotsq, l1sq * l4sq, 4 * ulp(dotsq))) { getLineOffsets(x1, y1, x4, y4, leftOff, rightOff); return 4; } @@ -693,8 +693,6 @@ final class Stroker implements PathConsumer2D { return 8; } - // compute offset curves using bezier spline through t=0.5 (i.e. - // ComputedCurve(0.5) == IdealParallelCurve(0.5)) // return the kind of curve in the right and left arrays. private int computeOffsetQuad(float[] pts, final int off, float[] leftOff, float[] rightOff) @@ -703,58 +701,69 @@ final class Stroker implements PathConsumer2D { final float x2 = pts[off + 2], y2 = pts[off + 3]; final float x3 = pts[off + 4], y3 = pts[off + 5]; - float dx3 = x3 - x2; - float dy3 = y3 - y2; - float dx1 = x2 - x1; - float dy1 = y2 - y1; + final float dx3 = x3 - x2; + final float dy3 = y3 - y2; + final float dx1 = x2 - x1; + final float dy1 = y2 - y1; - // if p1=p2 or p3=p4 it means that the derivative at the endpoint - // vanishes, which creates problems with computeOffset. Usually - // this happens when this stroker object is trying to winden - // a curve with a cusp. What happens is that curveTo splits - // the input curve at the cusp, and passes it to this function. - // because of inaccuracies in the splitting, we consider points - // equal if they're very close to each other. - - // if p1 == p2 && p3 == p4: draw line from p1->p4, unless p1 == p4, - // in which case ignore. - final boolean p1eqp2 = within(x1,y1,x2,y2, 6 * Math.ulp(y2)); - final boolean p2eqp3 = within(x2,y2,x3,y3, 6 * Math.ulp(y3)); - if (p1eqp2 || p2eqp3) { - getLineOffsets(x1, y1, x3, y3, leftOff, rightOff); - return 4; - } - - // if p2-p1 and p4-p3 are parallel, that must mean this curve is a line - float dotsq = (dx1 * dx3 + dy1 * dy3); - dotsq = dotsq * dotsq; - float l1sq = dx1 * dx1 + dy1 * dy1, l3sq = dx3 * dx3 + dy3 * dy3; - if (Helpers.within(dotsq, l1sq * l3sq, 4 * Math.ulp(dotsq))) { - getLineOffsets(x1, y1, x3, y3, leftOff, rightOff); - return 4; - } - - // this computes the offsets at t=0, 0.5, 1, using the property that - // for any bezier curve the vectors p2-p1 and p4-p3 are parallel to - // the (dx/dt, dy/dt) vectors at the endpoints. + // this computes the offsets at t = 0, 1 computeOffset(dx1, dy1, lineWidth2, offset[0]); computeOffset(dx3, dy3, lineWidth2, offset[1]); - float x1p = x1 + offset[0][0]; // start - float y1p = y1 + offset[0][1]; // point - float x3p = x3 + offset[1][0]; // end - float y3p = y3 + offset[1][1]; // point - computeMiter(x1p, y1p, x1p+dx1, y1p+dy1, x3p, y3p, x3p-dx3, y3p-dy3, leftOff, 2); - leftOff[0] = x1p; leftOff[1] = y1p; - leftOff[4] = x3p; leftOff[5] = y3p; - x1p = x1 - offset[0][0]; y1p = y1 - offset[0][1]; - x3p = x3 - offset[1][0]; y3p = y3 - offset[1][1]; - computeMiter(x1p, y1p, x1p+dx1, y1p+dy1, x3p, y3p, x3p-dx3, y3p-dy3, rightOff, 2); - rightOff[0] = x1p; rightOff[1] = y1p; - rightOff[4] = x3p; rightOff[5] = y3p; + leftOff[0] = x1 + offset[0][0]; leftOff[1] = y1 + offset[0][1]; + leftOff[4] = x3 + offset[1][0]; leftOff[5] = y3 + offset[1][1]; + rightOff[0] = x1 - offset[0][0]; rightOff[1] = y1 - offset[0][1]; + rightOff[4] = x3 - offset[1][0]; rightOff[5] = y3 - offset[1][1]; + + float x1p = leftOff[0]; // start + float y1p = leftOff[1]; // point + float x3p = leftOff[4]; // end + float y3p = leftOff[5]; // point + + // Corner cases: + // 1. If the two control vectors are parallel, we'll end up with NaN's + // in leftOff (and rightOff in the body of the if below), so we'll + // do getLineOffsets, which is right. + // 2. If the first or second two points are equal, then (dx1,dy1)==(0,0) + // or (dx3,dy3)==(0,0), so (x1p, y1p)==(x1p+dx1, y1p+dy1) + // or (x3p, y3p)==(x3p-dx3, y3p-dy3), which means that + // computeIntersection will put NaN's in leftOff and right off, and + // we will do getLineOffsets, which is right. + computeIntersection(x1p, y1p, x1p+dx1, y1p+dy1, x3p, y3p, x3p-dx3, y3p-dy3, leftOff, 2); + float cx = leftOff[2]; + float cy = leftOff[3]; + + if (!(isFinite(cx) && isFinite(cy))) { + // maybe the right path is not degenerate. + x1p = rightOff[0]; + y1p = rightOff[1]; + x3p = rightOff[4]; + y3p = rightOff[5]; + computeIntersection(x1p, y1p, x1p+dx1, y1p+dy1, x3p, y3p, x3p-dx3, y3p-dy3, rightOff, 2); + cx = rightOff[2]; + cy = rightOff[3]; + if (!(isFinite(cx) && isFinite(cy))) { + // both are degenerate. This curve is a line. + getLineOffsets(x1, y1, x3, y3, leftOff, rightOff); + return 4; + } + // {left,right}Off[0,1,4,5] are already set to the correct values. + leftOff[2] = 2*x2 - cx; + leftOff[3] = 2*y2 - cy; + return 6; + } + + // rightOff[2,3] = (x2,y2) - ((left_x2, left_y2) - (x2, y2)) + // == 2*(x2, y2) - (left_x2, left_y2) + rightOff[2] = 2*x2 - cx; + rightOff[3] = 2*y2 - cy; return 6; } + private static boolean isFinite(float x) { + return (Float.NEGATIVE_INFINITY < x && x < Float.POSITIVE_INFINITY); + } + // This is where the curve to be processed is put. We give it // enough room to store 2 curves: one for the current subdivision, the // other for the rest of the curve. @@ -812,12 +821,12 @@ final class Stroker implements PathConsumer2D { // if these vectors are too small, normalize them, to avoid future // precision problems. if (Math.abs(dxs) < 0.1f && Math.abs(dys) < 0.1f) { - float len = (float)Math.sqrt(dxs*dxs + dys*dys); + float len = (float) sqrt(dxs*dxs + dys*dys); dxs /= len; dys /= len; } if (Math.abs(dxf) < 0.1f && Math.abs(dyf) < 0.1f) { - float len = (float)Math.sqrt(dxf*dxf + dyf*dyf); + float len = (float) sqrt(dxf*dxf + dyf*dyf); dxf /= len; dyf /= len; } @@ -834,7 +843,6 @@ final class Stroker implements PathConsumer2D { while(it.hasNext()) { int curCurveOff = it.next(); - kind = 0; switch (type) { case 8: kind = computeOffsetCubic(middle, curCurveOff, lp, rp); @@ -843,24 +851,22 @@ final class Stroker implements PathConsumer2D { kind = computeOffsetQuad(middle, curCurveOff, lp, rp); break; } - if (kind != 0) { - emitLineTo(lp[0], lp[1]); - switch(kind) { - case 8: - emitCurveTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], lp[6], lp[7], false); - emitCurveTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], rp[6], rp[7], true); - break; - case 6: - emitQuadTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], false); - emitQuadTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], true); - break; - case 4: - emitLineTo(lp[2], lp[3]); - emitLineTo(rp[0], rp[1], true); - break; - } - emitLineTo(rp[kind - 2], rp[kind - 1], true); + emitLineTo(lp[0], lp[1]); + switch(kind) { + case 8: + emitCurveTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], lp[6], lp[7], false); + emitCurveTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], rp[6], rp[7], true); + break; + case 6: + emitQuadTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], false); + emitQuadTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], true); + break; + case 4: + emitLineTo(lp[2], lp[3]); + emitLineTo(rp[0], rp[1], true); + break; } + emitLineTo(rp[kind - 2], rp[kind - 1], true); } this.cmx = (lp[kind - 2] - rp[kind - 2]) / 2; @@ -887,7 +893,7 @@ final class Stroker implements PathConsumer2D { // we rotate it so that the first vector in the control polygon is // parallel to the x-axis. This will ensure that rotated quarter // circles won't be subdivided. - final float hypot = (float)Math.sqrt(x12 * x12 + y12 * y12); + final float hypot = (float) sqrt(x12 * x12 + y12 * y12); final float cos = x12 / hypot; final float sin = y12 / hypot; final float x1 = cos * pts[0] + sin * pts[1]; @@ -976,12 +982,12 @@ final class Stroker implements PathConsumer2D { // if these vectors are too small, normalize them, to avoid future // precision problems. if (Math.abs(dxs) < 0.1f && Math.abs(dys) < 0.1f) { - float len = (float)Math.sqrt(dxs*dxs + dys*dys); + float len = (float) sqrt(dxs*dxs + dys*dys); dxs /= len; dys /= len; } if (Math.abs(dxf) < 0.1f && Math.abs(dyf) < 0.1f) { - float len = (float)Math.sqrt(dxf*dxf + dyf*dyf); + float len = (float) sqrt(dxf*dxf + dyf*dyf); dxf /= len; dyf /= len; } @@ -999,20 +1005,18 @@ final class Stroker implements PathConsumer2D { int curCurveOff = it.next(); kind = computeOffsetCubic(middle, curCurveOff, lp, rp); - if (kind != 0) { - emitLineTo(lp[0], lp[1]); - switch(kind) { - case 8: - emitCurveTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], lp[6], lp[7], false); - emitCurveTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], rp[6], rp[7], true); - break; - case 4: - emitLineTo(lp[2], lp[3]); - emitLineTo(rp[0], rp[1], true); - break; - } - emitLineTo(rp[kind - 2], rp[kind - 1], true); + emitLineTo(lp[0], lp[1]); + switch(kind) { + case 8: + emitCurveTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], lp[6], lp[7], false); + emitCurveTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], rp[6], rp[7], true); + break; + case 4: + emitLineTo(lp[2], lp[3]); + emitLineTo(rp[0], rp[1], true); + break; } + emitLineTo(rp[kind - 2], rp[kind - 1], true); } this.cmx = (lp[kind - 2] - rp[kind - 2]) / 2; @@ -1050,12 +1054,12 @@ final class Stroker implements PathConsumer2D { // if these vectors are too small, normalize them, to avoid future // precision problems. if (Math.abs(dxs) < 0.1f && Math.abs(dys) < 0.1f) { - float len = (float)Math.sqrt(dxs*dxs + dys*dys); + float len = (float) sqrt(dxs*dxs + dys*dys); dxs /= len; dys /= len; } if (Math.abs(dxf) < 0.1f && Math.abs(dyf) < 0.1f) { - float len = (float)Math.sqrt(dxf*dxf + dyf*dyf); + float len = (float) sqrt(dxf*dxf + dyf*dyf); dxf /= len; dyf /= len; } @@ -1073,20 +1077,18 @@ final class Stroker implements PathConsumer2D { int curCurveOff = it.next(); kind = computeOffsetQuad(middle, curCurveOff, lp, rp); - if (kind != 0) { - emitLineTo(lp[0], lp[1]); - switch(kind) { - case 6: - emitQuadTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], false); - emitQuadTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], true); - break; - case 4: - emitLineTo(lp[2], lp[3]); - emitLineTo(rp[0], rp[1], true); - break; - } - emitLineTo(rp[kind - 2], rp[kind - 1], true); + emitLineTo(lp[0], lp[1]); + switch(kind) { + case 6: + emitQuadTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], false); + emitQuadTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], true); + break; + case 4: + emitLineTo(lp[2], lp[3]); + emitLineTo(rp[0], rp[1], true); + break; } + emitLineTo(rp[kind - 2], rp[kind - 1], true); } this.cmx = (lp[kind - 2] - rp[kind - 2]) / 2; diff --git a/jdk/test/sun/java2d/pisces/Test7036754.java b/jdk/test/sun/java2d/pisces/Test7036754.java new file mode 100644 index 00000000000..1dd39ddc8b9 --- /dev/null +++ b/jdk/test/sun/java2d/pisces/Test7036754.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 7036754 + * + * @summary Verifies that there are no non-finite numbers when stroking + * certain quadratic curves. + * + * @author Jim Graham + * @run main Test7036754 + */ + +import java.awt.*; +import java.awt.geom.*; + +public class Test7036754 { + public static void main(String argv[]) { + Shape s = new QuadCurve2D.Float(839.24677f, 508.97888f, + 839.2953f, 508.97122f, + 839.3438f, 508.96353f); + s = new BasicStroke(10f).createStrokedShape(s); + float nsegs[] = {2, 2, 4, 6, 0}; + float coords[] = new float[6]; + PathIterator pi = s.getPathIterator(null); + while (!pi.isDone()) { + int type = pi.currentSegment(coords); + for (int i = 0; i < nsegs[type]; i++) { + float c = coords[i]; + if (Float.isNaN(c) || Float.isInfinite(c)) { + throw new RuntimeException("bad value in stroke"); + } + } + pi.next(); + } + } +} From c9f3d958ec3d62c02f19ec1e34c601c276fe7f25 Mon Sep 17 00:00:00 2001 From: Andrei Dmitriev Date: Thu, 28 Apr 2011 20:14:30 +0400 Subject: [PATCH 50/80] 6956646: Test: MouseWheelEvent/InfiniteRecursion test receives more MouseWheelEvents than expected Reviewed-by: serb, dcherepanov --- .../InfiniteRecursion/InfiniteRecursion.java | 13 ++++++++++--- .../InfiniteRecursion/InfiniteRecursion_1.java | 11 ++++++++--- .../InfiniteRecursion/InfiniteRecursion_2.java | 11 ++++++++--- .../InfiniteRecursion/InfiniteRecursion_3.java | 11 ++++++++--- .../InfiniteRecursion/InfiniteRecursion_4.java | 10 +++++++--- 5 files changed, 41 insertions(+), 15 deletions(-) diff --git a/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion.java b/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion.java index 6ec02ffbf45..e5533b41891 100644 --- a/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion.java +++ b/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2011 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 @@ -50,6 +50,11 @@ import test.java.awt.regtesthelpers.Sysout; public class InfiniteRecursion { final static Robot robot = Util.createRobot(); final static int MOVE_COUNT = 5; + + //*2 for both rotation directions, + //*2 as Java sends the wheel event to every for nested component in hierarchy under cursor + final static int EXPECTED_COUNT = MOVE_COUNT * 2 * 2; + static int actualEvents = 0; public static void main(String []s) @@ -96,8 +101,10 @@ public class InfiniteRecursion { Util.waitForIdle(robot); - if (actualEvents != MOVE_COUNT * 2) { - AbstractTest.fail("Expected events count: "+ MOVE_COUNT+" Actual events count: "+ actualEvents); + //Not fair to check for multiplier 4 as it's not specified actual number of WheelEvents + //result in a single wheel rotation. + if (actualEvents != EXPECTED_COUNT) { + AbstractTest.fail("Expected events count: "+ EXPECTED_COUNT+" Actual events count: "+ actualEvents); } } } diff --git a/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_1.java b/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_1.java index 3ed18f0e4a2..733af38731d 100644 --- a/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_1.java +++ b/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_1.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2011 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 @@ -50,6 +50,9 @@ import test.java.awt.regtesthelpers.Sysout; public class InfiniteRecursion_1 { final static Robot robot = Util.createRobot(); final static int MOVE_COUNT = 5; + //*2 for both rotation directions, + //*2 as Java sends the wheel event to every for nested component in hierarchy under cursor + final static int EXPECTED_COUNT = MOVE_COUNT * 2 * 2; static int actualEvents = 0; public static void main(String []s) @@ -95,8 +98,10 @@ public class InfiniteRecursion_1 { } Util.waitForIdle(robot); - if (actualEvents != MOVE_COUNT * 2) { - AbstractTest.fail("Expected events count: "+ MOVE_COUNT+" Actual events count: "+ actualEvents); + //Not fair to check for multiplier 4 as it's not specified actual number of WheelEvents + //result in a single wheel rotation. + if (actualEvents != EXPECTED_COUNT) { + AbstractTest.fail("Expected events count: "+ EXPECTED_COUNT+" Actual events count: "+ actualEvents); } } } diff --git a/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_2.java b/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_2.java index 4aecedeb833..94444088671 100644 --- a/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_2.java +++ b/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_2.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2011 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 @@ -56,6 +56,9 @@ import java.applet.Applet; public class InfiniteRecursion_2 extends Applet { final static Robot robot = Util.createRobot(); final static int MOVE_COUNT = 5; + //*2 for both rotation directions, + //*2 as Java sends the wheel event to every for nested component in hierarchy under cursor + final static int EXPECTED_COUNT = MOVE_COUNT * 2 * 2; static int actualEvents = 0; public void init() @@ -107,8 +110,10 @@ public class InfiniteRecursion_2 extends Applet { } Util.waitForIdle(robot); - if (actualEvents != MOVE_COUNT * 2) { - AbstractTest.fail("Expected events count: "+ MOVE_COUNT+" Actual events count: "+ actualEvents); + //Not fair to check for multiplier 4 as it's not specified actual number of WheelEvents + //result in a single wheel rotation. + if (actualEvents != EXPECTED_COUNT) { + AbstractTest.fail("Expected events count: "+ EXPECTED_COUNT+" Actual events count: "+ actualEvents); } }// start() } diff --git a/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_3.java b/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_3.java index 2804b14ce7e..c12636acdc5 100644 --- a/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_3.java +++ b/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_3.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2011 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 @@ -50,6 +50,9 @@ import java.applet.Applet; public class InfiniteRecursion_3 extends Applet { final static Robot robot = Util.createRobot(); final static int MOVE_COUNT = 5; + //*2 for both rotation directions, + //*2 as Java sends the wheel event to every for nested component in hierarchy under cursor + final static int EXPECTED_COUNT = MOVE_COUNT * 2 * 2; static int actualEvents = 0; public void init() @@ -91,8 +94,10 @@ public class InfiniteRecursion_3 extends Applet { } Util.waitForIdle(robot); - if (actualEvents != MOVE_COUNT * 2) { - AbstractTest.fail("Expected events count: "+ MOVE_COUNT+" Actual events count: "+ actualEvents); + //Not fair to check for multiplier 4 as it's not specified actual number of WheelEvents + //result in a single wheel rotation. + if (actualEvents != EXPECTED_COUNT) { + AbstractTest.fail("Expected events count: "+ EXPECTED_COUNT+" Actual events count: "+ actualEvents); } }// start() } diff --git a/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_4.java b/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_4.java index 600e0fa5af3..2fbb3d2e2b0 100644 --- a/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_4.java +++ b/jdk/test/java/awt/event/MouseWheelEvent/InfiniteRecursion/InfiniteRecursion_4.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2011 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 @@ -47,6 +47,8 @@ import test.java.awt.regtesthelpers.Sysout; public class InfiniteRecursion_4 { final static Robot robot = Util.createRobot(); final static int MOVE_COUNT = 5; + //*2 for both rotation directions over a single frame without any siblings + final static int EXPECTED_COUNT = MOVE_COUNT * 2; static int actualEvents = 0; public static void main(String []s) @@ -80,8 +82,10 @@ public class InfiniteRecursion_4 { } Util.waitForIdle(robot); - if (actualEvents != MOVE_COUNT * 2) { - AbstractTest.fail("Expected events count: "+ MOVE_COUNT+" Actual events count: "+ actualEvents); + //Not fair to check for multiplier 4 as it's not specified actual number of WheelEvents + //result in a single wheel rotation. + if (actualEvents != EXPECTED_COUNT) { + AbstractTest.fail("Expected events count: "+ EXPECTED_COUNT+" Actual events count: "+ actualEvents); } } } From 1e3fce0242fc651d74d060f0817f2761a862aae9 Mon Sep 17 00:00:00 2001 From: Dmitry Cherepanov Date: Thu, 28 Apr 2011 19:23:44 +0400 Subject: [PATCH 51/80] 6853146: Regression: on-the-spot input is broken in AWT Peered components Reviewed-by: art, ant, naoto --- jdk/src/windows/native/sun/windows/awt_TextComponent.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/jdk/src/windows/native/sun/windows/awt_TextComponent.cpp b/jdk/src/windows/native/sun/windows/awt_TextComponent.cpp index c1fc17826b0..5e9a08f46ee 100644 --- a/jdk/src/windows/native/sun/windows/awt_TextComponent.cpp +++ b/jdk/src/windows/native/sun/windows/awt_TextComponent.cpp @@ -191,8 +191,11 @@ void AwtTextComponent::SetCompositionWindow(RECT& rc) { HIMC hIMC = ImmGetContext(); // rc is not used for text component. - COMPOSITIONFORM cf = { CFS_POINT, {0,0}, {0,0,0,0} }; + COMPOSITIONFORM cf = { CFS_FORCE_POSITION, {0,0}, {0,0,0,0} }; GetCaretPos(&(cf.ptCurrentPos)); + // the proxy is the native focus owner and it contains the composition window + // let's convert the position to a coordinate space relative to proxy + ::MapWindowPoints(GetHWnd(), GetProxyFocusOwner(), (LPPOINT)&cf.ptCurrentPos, 1); ImmSetCompositionWindow(hIMC, &cf); LOGFONT lf; From ac156aab263ec8a9597dcc20807b27776ad18ccd Mon Sep 17 00:00:00 2001 From: Dmitry Cherepanov Date: Thu, 28 Apr 2011 19:39:47 +0400 Subject: [PATCH 52/80] 7034766: closed/java/awt/EmbeddedFrame/EmbeddedFrameGrabTest/EmbeddedFrameGrabTest.java failed on jdk7 b134 Reviewed-by: art, ant --- jdk/src/windows/native/sun/windows/awt_Frame.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/jdk/src/windows/native/sun/windows/awt_Frame.cpp b/jdk/src/windows/native/sun/windows/awt_Frame.cpp index 4d3374e5734..398aea6db67 100644 --- a/jdk/src/windows/native/sun/windows/awt_Frame.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Frame.cpp @@ -340,12 +340,16 @@ LRESULT AwtFrame::ProxyWindowProc(UINT message, WPARAM wParam, LPARAM lParam, Ms } break; case WM_SETFOCUS: + if (sm_inSynthesizeFocus) break; // pass it up the WindowProc chain + if (!sm_suppressFocusAndActivation && IsEmbeddedFrame()) { AwtSetActiveWindow(); } mr = mrConsume; break; case WM_KILLFOCUS: + if (sm_inSynthesizeFocus) break; // pass it up the WindowProc chain + if (!sm_suppressFocusAndActivation && IsEmbeddedFrame()) { AwtWindow::SynthesizeWmActivate(FALSE, GetHWnd(), NULL); From eb8db400924b6a83a98b395aa3ecf58c834b39cc Mon Sep 17 00:00:00 2001 From: Tom Rodriguez Date: Thu, 28 Apr 2011 14:00:13 -0700 Subject: [PATCH 53/80] 7032162: assert(flat != TypePtr::BOTTOM) failed: cannot alias-analyze an untyped ptr Reviewed-by: kvn --- hotspot/src/share/vm/ci/ciObject.cpp | 10 ++++++++++ hotspot/src/share/vm/opto/stringopts.cpp | 8 ++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/hotspot/src/share/vm/ci/ciObject.cpp b/hotspot/src/share/vm/ci/ciObject.cpp index a4eb9439e1f..031f584d22c 100644 --- a/hotspot/src/share/vm/ci/ciObject.cpp +++ b/hotspot/src/share/vm/ci/ciObject.cpp @@ -194,6 +194,16 @@ bool ciObject::can_be_constant() { // ciObject::should_be_constant() bool ciObject::should_be_constant() { if (ScavengeRootsInCode >= 2) return true; // force everybody to be a constant + if (!JavaObjectsInPerm && !is_null_object()) { + // We want Strings and Classes to be embeddable by default since + // they used to be in the perm world. Not all Strings used to be + // embeddable but there's no easy way to distinguish the interned + // from the regulars ones so just treat them all that way. + ciEnv* env = CURRENT_ENV; + if (klass() == env->String_klass() || klass() == env->Class_klass()) { + return true; + } + } return handle() == NULL || !is_scavengable(); } diff --git a/hotspot/src/share/vm/opto/stringopts.cpp b/hotspot/src/share/vm/opto/stringopts.cpp index 7f5f318dbf7..e85ba982c75 100644 --- a/hotspot/src/share/vm/opto/stringopts.cpp +++ b/hotspot/src/share/vm/opto/stringopts.cpp @@ -1172,16 +1172,16 @@ void PhaseStringOpts::int_getChars(GraphKit& kit, Node* arg, Node* char_array, N Node* PhaseStringOpts::copy_string(GraphKit& kit, Node* str, Node* char_array, Node* start) { Node* string = str; - Node* offset = kit.make_load(NULL, + Node* offset = kit.make_load(kit.control(), kit.basic_plus_adr(string, string, java_lang_String::offset_offset_in_bytes()), TypeInt::INT, T_INT, offset_field_idx); - Node* count = kit.make_load(NULL, + Node* count = kit.make_load(kit.control(), kit.basic_plus_adr(string, string, java_lang_String::count_offset_in_bytes()), TypeInt::INT, T_INT, count_field_idx); const TypeAryPtr* value_type = TypeAryPtr::make(TypePtr::NotNull, TypeAry::make(TypeInt::CHAR,TypeInt::POS), ciTypeArrayKlass::make(T_CHAR), true, 0); - Node* value = kit.make_load(NULL, + Node* value = kit.make_load(kit.control(), kit.basic_plus_adr(string, string, java_lang_String::value_offset_in_bytes()), value_type, T_OBJECT, value_field_idx); @@ -1342,7 +1342,7 @@ void PhaseStringOpts::replace_string_concat(StringConcat* sc) { } // Node* offset = kit.make_load(NULL, kit.basic_plus_adr(arg, arg, offset_offset), // TypeInt::INT, T_INT, offset_field_idx); - Node* count = kit.make_load(NULL, kit.basic_plus_adr(arg, arg, java_lang_String::count_offset_in_bytes()), + Node* count = kit.make_load(kit.control(), kit.basic_plus_adr(arg, arg, java_lang_String::count_offset_in_bytes()), TypeInt::INT, T_INT, count_field_idx); length = __ AddI(length, count); string_sizes->init_req(argi, NULL); From 13cf1a72777057c4043efa4c8ab714e7432db3af Mon Sep 17 00:00:00 2001 From: Suchen Chien Date: Thu, 28 Apr 2011 17:44:13 -0700 Subject: [PATCH 54/80] Added tag jdk7-b140 for changeset 90e228752038 --- .hgtags-top-repo | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 0c499488b3e..3bdb4f112e3 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -114,3 +114,4 @@ ddc2fcb3682ffd27f44354db666128827be7e3c3 jdk7-b134 7654afc6a29e43cb0a1343ce7f1287bf690d5e5f jdk7-b137 fc47c97bbbd91b1f774d855c48a7e285eb1a351a jdk7-b138 7ed6d0b9aaa12320832a7ddadb88d6d8d0dda4c1 jdk7-b139 +dcfe74f1c6553c556e7d361c30b0b614eb5e40f6 jdk7-b140 From 6ae3e039ab0336fffae8501fabbc44954a4d6a81 Mon Sep 17 00:00:00 2001 From: Suchen Chien Date: Thu, 28 Apr 2011 17:44:18 -0700 Subject: [PATCH 55/80] Added tag jdk7-b140 for changeset 837037533544 --- corba/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/corba/.hgtags b/corba/.hgtags index 4e2aad7b7fe..0cc360827c3 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -114,3 +114,4 @@ e0b72ae5dc5e824b342801c8d1d336a55eb54e2c jdk7-b135 a66c01d8bf895261715955df0b95545c000ed6a8 jdk7-b137 78d8cf04697e9df54f7f11e195b7da29b8e345a2 jdk7-b138 60b074ec6fcf5cdf9efce22fdfb02326ed8fa2d3 jdk7-b139 +cdf5d19ec142424489549025e9c42e51f32cf688 jdk7-b140 From 874944e5bc5615b73ce05869589a60daa3e17a20 Mon Sep 17 00:00:00 2001 From: Suchen Chien Date: Thu, 28 Apr 2011 17:44:24 -0700 Subject: [PATCH 56/80] Added tag jdk7-b140 for changeset 33e592b5ff17 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 145ab668bff..5478ecfeaf9 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -166,3 +166,4 @@ bd586e392d93b7ed7a1636dcc8da2b6a4203a102 hs21-b06 0930dc920c185afbf40fed9a655290b8e5b16783 hs21-b08 611e19a16519d6fb5deea9ab565336e6e6ee475d jdk7-b139 611e19a16519d6fb5deea9ab565336e6e6ee475d hs21-b09 +d283b82966712b353fa307845a1316da42a355f4 jdk7-b140 From 36230d8a9031d03e9233f41a19f0f9852db1a5ce Mon Sep 17 00:00:00 2001 From: Suchen Chien Date: Thu, 28 Apr 2011 17:44:28 -0700 Subject: [PATCH 57/80] Added tag jdk7-b140 for changeset 2c31217f748a --- jaxp/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxp/.hgtags b/jaxp/.hgtags index b8136de0b51..78d0d9f5a94 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -114,3 +114,4 @@ d56b326ae0544fc16c3e0d0285876f3c82054db2 jdk7-b134 1d87f7460cde7f8f30af668490f82b52b879bfd8 jdk7-b137 be3758943770a0a3dd4be6a1cb4063507c4d7062 jdk7-b138 28c7c0ed2444607829ba11ad827f8d52197a2830 jdk7-b139 +c8136fd161c83917f87e93b14fa2ba3483f9be83 jdk7-b140 From 12324e11fb1e0c0dec6746877b486bda31ad54e1 Mon Sep 17 00:00:00 2001 From: Suchen Chien Date: Thu, 28 Apr 2011 17:44:29 -0700 Subject: [PATCH 58/80] Added tag jdk7-b140 for changeset 3202e475f9d9 --- jaxws/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jaxws/.hgtags b/jaxws/.hgtags index 0ef77285c96..2cfc85038bf 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -114,3 +114,4 @@ c81d289c9a532d6e94af3c09d856a2a20529040f jdk7-b136 ccea3282991ce8b678e188cf32a8239f76ff3bfa jdk7-b137 cc956c8a8255583535597e9a63db23c510e9a063 jdk7-b138 c025078c8362076503bb83b8e4da14ba7b347940 jdk7-b139 +82a9022c4f21b1313023c8303b557a17c4106701 jdk7-b140 From bf38109be47b9acb0eb7ec1006c9a6a655958b7d Mon Sep 17 00:00:00 2001 From: Suchen Chien Date: Thu, 28 Apr 2011 17:44:34 -0700 Subject: [PATCH 59/80] Added tag jdk7-b140 for changeset adbb12180d75 --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index c3032b54af6..68e25fecbb6 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -114,3 +114,4 @@ aa13e7702cd9d8aca9aa38f1227f966990866944 jdk7-b136 29296ea6529a418037ccce95903249665ef31c11 jdk7-b137 60d3d55dcc9c31a30ced9caa6ef5c0dcd7db031d jdk7-b138 d80954a89b49fda47c0c5cace65a17f5a758b8bd jdk7-b139 +9315c733fb17ddfb9fb44be7e0ffea37bf3c727d jdk7-b140 From a4dd2f32d7913230248862ba031d798bbbeb7ce9 Mon Sep 17 00:00:00 2001 From: Suchen Chien Date: Thu, 28 Apr 2011 17:44:47 -0700 Subject: [PATCH 60/80] Added tag jdk7-b140 for changeset c0c0f0374f67 --- langtools/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/.hgtags b/langtools/.hgtags index 8ea0912e659..2ce033497a0 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -114,3 +114,4 @@ ed0f7f1f9511db4f9615b1426d22f8b961629275 jdk7-b136 a15c9b058ae007d4ccb7e35ce44e4dfa977f090b jdk7-b137 53f212bed4f4304dce7f0bf0fa01c998c65bacd6 jdk7-b138 853b6bb99f9b58eb7cf8211c67d3b6e4f1228a3e jdk7-b139 +258e6654aba25aab91c9ba3b4c53d05bc895a86c jdk7-b140 From ce5fc02a16957194b2658206746c922990bb2859 Mon Sep 17 00:00:00 2001 From: Michael Fang Date: Thu, 28 Apr 2011 20:15:11 -0700 Subject: [PATCH 61/80] 7040228: [zh_TW] extra (C) on cancel button on File Chooser dialog Reviewed-by: yhuang --- .../java/swing/plaf/gtk/resources/gtk.properties | 12 ++++-------- .../swing/plaf/gtk/resources/gtk_ja.properties | 14 +++++--------- .../swing/plaf/gtk/resources/gtk_ko.properties | 14 +++++--------- .../swing/plaf/gtk/resources/gtk_zh_CN.properties | 14 +++++--------- .../swing/plaf/gtk/resources/gtk_zh_TW.properties | 14 +++++--------- .../internal/plaf/basic/resources/basic.properties | 2 +- .../plaf/basic/resources/basic_ja.properties | 2 +- .../plaf/basic/resources/basic_ko.properties | 2 +- .../plaf/basic/resources/basic_zh_CN.properties | 2 +- .../plaf/basic/resources/basic_zh_TW.properties | 2 +- 10 files changed, 29 insertions(+), 49 deletions(-) diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk.properties index 904a49352eb..45f4a4dc7a6 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk.properties +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk.properties @@ -56,9 +56,9 @@ FileChooser.deleteFileButtonMnemonic=76 FileChooser.renameFileButtonText=Rename File FileChooser.renameFileButtonMnemonic=82 FileChooser.cancelButtonText=Cancel -FileChooser.cancelButtonMnemonic=67 +#FileChooser.cancelButtonMnemonic=67 FileChooser.saveButtonText=OK -FileChooser.saveButtonMnemonic=79 +#FileChooser.saveButtonMnemonic=79 FileChooser.openButtonText=OK FileChooser.openButtonMnemonic=79 FileChooser.saveDialogTitleText=Save @@ -79,9 +79,5 @@ FileChooser.renameFileDialogText=Rename file "{0}" to FileChooser.renameFileErrorTitle=Error FileChooser.renameFileErrorText=Error renaming file "{0}" to "{1}" -# dummy resource added for translation automation -OptionPane.okButtonText=OK -OptionPane.okButtonMnemonic=79 -# dummy resource added for translation automation -OptionPane.cancelButtonText=Cancel -OptionPane.cancelButtonMnemonic=67 +#OptionPane.okButtonMnemonic=79 +#OptionPane.cancelButtonMnemonic=67 diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_ja.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_ja.properties index c7ff0bb97a2..30560e91620 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_ja.properties +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_ja.properties @@ -55,11 +55,11 @@ FileChooser.deleteFileButtonText=\u30D5\u30A1\u30A4\u30EB\u306E\u524A\u9664(L) FileChooser.deleteFileButtonMnemonic=76 FileChooser.renameFileButtonText=\u30D5\u30A1\u30A4\u30EB\u306E\u540D\u524D\u5909\u66F4(R) FileChooser.renameFileButtonMnemonic=82 -FileChooser.cancelButtonText=\u53D6\u6D88(C) +FileChooser.cancelButtonText=\u53D6\u6D88 FileChooser.cancelButtonMnemonic=67 -FileChooser.saveButtonText=OK(O) +FileChooser.saveButtonText=OK FileChooser.saveButtonMnemonic=79 -FileChooser.openButtonText=OK(O) +FileChooser.openButtonText=OK FileChooser.openButtonMnemonic=79 FileChooser.saveDialogTitleText=\u4FDD\u5B58 FileChooser.openDialogTitleText=\u958B\u304F @@ -79,10 +79,6 @@ FileChooser.renameFileDialogText=\u30D5\u30A1\u30A4\u30EB"{0}"\u3092\u6B21\u306E FileChooser.renameFileErrorTitle=\u30A8\u30E9\u30FC FileChooser.renameFileErrorText=\u30D5\u30A1\u30A4\u30EB"{0}"\u306E"{1}"\u3078\u306E\u5909\u66F4\u4E2D\u306B\u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F -# dummy resource added for translation automation -OptionPane.okButtonText=OK(O) -OptionPane.okButtonMnemonic=79 -# dummy resource added for translation automation -OptionPane.cancelButtonText=\u53D6\u6D88(C) -OptionPane.cancelButtonMnemonic=67 +#OptionPane.okButtonMnemonic=79 +#OptionPane.cancelButtonMnemonic=67 diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_ko.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_ko.properties index cb029e7b025..27802636b7c 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_ko.properties +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_ko.properties @@ -55,11 +55,11 @@ FileChooser.deleteFileButtonText=\uD30C\uC77C \uC0AD\uC81C(L) FileChooser.deleteFileButtonMnemonic=76 FileChooser.renameFileButtonText=\uD30C\uC77C \uC774\uB984 \uBC14\uAFB8\uAE30(R) FileChooser.renameFileButtonMnemonic=82 -FileChooser.cancelButtonText=\uCDE8\uC18C(C) +FileChooser.cancelButtonText=\uCDE8\uC18C FileChooser.cancelButtonMnemonic=67 -FileChooser.saveButtonText=\uD655\uC778(O) +FileChooser.saveButtonText=\uD655\uC778 FileChooser.saveButtonMnemonic=79 -FileChooser.openButtonText=\uD655\uC778(O) +FileChooser.openButtonText=\uD655\uC778 FileChooser.openButtonMnemonic=79 FileChooser.saveDialogTitleText=\uC800\uC7A5 FileChooser.openDialogTitleText=\uC5F4\uAE30 @@ -79,10 +79,6 @@ FileChooser.renameFileDialogText="{0}" \uD30C\uC77C\uC758 \uC774\uB984 \uBC14\uA FileChooser.renameFileErrorTitle=\uC624\uB958 FileChooser.renameFileErrorText="{0}" \uD30C\uC77C\uC758 \uC774\uB984\uC744 "{1}"(\uC73C)\uB85C \uBC14\uAFB8\uB294 \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4. -# dummy resource added for translation automation -OptionPane.okButtonText=\uD655\uC778(O) -OptionPane.okButtonMnemonic=79 -# dummy resource added for translation automation -OptionPane.cancelButtonText=\uCDE8\uC18C(C) -OptionPane.cancelButtonMnemonic=67 +#OptionPane.okButtonMnemonic=79 +#OptionPane.cancelButtonMnemonic=67 diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_zh_CN.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_zh_CN.properties index 58506b0107d..9c7793c62ff 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_zh_CN.properties +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_zh_CN.properties @@ -55,11 +55,11 @@ FileChooser.deleteFileButtonText=\u5220\u9664\u6587\u4EF6(L) FileChooser.deleteFileButtonMnemonic=76 FileChooser.renameFileButtonText=\u91CD\u547D\u540D\u6587\u4EF6(R) FileChooser.renameFileButtonMnemonic=82 -FileChooser.cancelButtonText=\u53D6\u6D88(C) +FileChooser.cancelButtonText=\u53D6\u6D88 FileChooser.cancelButtonMnemonic=67 -FileChooser.saveButtonText=\u786E\u5B9A(O) +FileChooser.saveButtonText=\u786E\u5B9A FileChooser.saveButtonMnemonic=79 -FileChooser.openButtonText=\u786E\u5B9A(O) +FileChooser.openButtonText=\u786E\u5B9A FileChooser.openButtonMnemonic=79 FileChooser.saveDialogTitleText=\u4FDD\u5B58 FileChooser.openDialogTitleText=\u6253\u5F00 @@ -79,10 +79,6 @@ FileChooser.renameFileDialogText=\u5C06\u6587\u4EF6 "{0}" \u91CD\u547D\u540D\u4E FileChooser.renameFileErrorTitle=\u9519\u8BEF FileChooser.renameFileErrorText=\u5C06\u6587\u4EF6 "{0}" \u91CD\u547D\u540D\u4E3A "{1}" \u65F6\u51FA\u9519 -# dummy resource added for translation automation -OptionPane.okButtonText=\u786E\u5B9A(O) -OptionPane.okButtonMnemonic=79 -# dummy resource added for translation automation -OptionPane.cancelButtonText=\u53D6\u6D88(C) -OptionPane.cancelButtonMnemonic=67 +#OptionPane.okButtonMnemonic=79 +#OptionPane.cancelButtonMnemonic=67 diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_zh_TW.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_zh_TW.properties index ac8c732dc6d..68fdd917034 100644 --- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_zh_TW.properties +++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/resources/gtk_zh_TW.properties @@ -55,11 +55,11 @@ FileChooser.deleteFileButtonText=\u522A\u9664\u6A94\u6848(L) FileChooser.deleteFileButtonMnemonic=76 FileChooser.renameFileButtonText=\u91CD\u65B0\u547D\u540D\u6A94\u6848(R) FileChooser.renameFileButtonMnemonic=82 -FileChooser.cancelButtonText=\u53D6\u6D88(C) +FileChooser.cancelButtonText=\u53D6\u6D88 FileChooser.cancelButtonMnemonic=67 -FileChooser.saveButtonText=\u78BA\u5B9A(O) +FileChooser.saveButtonText=\u78BA\u5B9A FileChooser.saveButtonMnemonic=79 -FileChooser.openButtonText=\u78BA\u5B9A(O) +FileChooser.openButtonText=\u78BA\u5B9A FileChooser.openButtonMnemonic=79 FileChooser.saveDialogTitleText=\u5132\u5B58 FileChooser.openDialogTitleText=\u958B\u555F @@ -79,10 +79,6 @@ FileChooser.renameFileDialogText=\u5C07\u6A94\u6848 "{0}" \u91CD\u65B0\u547D\u54 FileChooser.renameFileErrorTitle=\u932F\u8AA4 FileChooser.renameFileErrorText=\u5C07\u6A94\u6848 "{0}" \u91CD\u65B0\u547D\u540D\u70BA "{1}" \u6642\u51FA\u73FE\u932F\u8AA4 -# dummy resource added for translation automation -OptionPane.okButtonText=\u78BA\u5B9A(O) -OptionPane.okButtonMnemonic=79 -# dummy resource added for translation automation -OptionPane.cancelButtonText=\u53D6\u6D88(C) -OptionPane.cancelButtonMnemonic=67 +#OptionPane.okButtonMnemonic=79 +#OptionPane.cancelButtonMnemonic=67 diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic.properties index 549e5cfc853..109538ac90e 100644 --- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic.properties +++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic.properties @@ -57,7 +57,7 @@ FileChooser.renameErrorFileExistsText=Cannot rename {0}: A file with the name yo Specify a different file name. FileChooser.acceptAllFileFilterText=All Files FileChooser.cancelButtonText=Cancel -FileChooser.cancelButtonMnemonic=67 +#FileChooser.cancelButtonMnemonic=67 // not needed? FileChooser.saveButtonText=Save FileChooser.saveButtonMnemonic=83 // not needed? FileChooser.openButtonText=Open diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ja.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ja.properties index 6a01a4ae528..7b946411855 100644 --- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ja.properties +++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ja.properties @@ -55,7 +55,7 @@ FileChooser.renameErrorTitleText=\u30D5\u30A1\u30A4\u30EB\u307E\u305F\u306F\u30D FileChooser.renameErrorText={0}\u306E\u540D\u524D\u3092\u5909\u66F4\u3067\u304D\u307E\u305B\u3093 FileChooser.renameErrorFileExistsText={0}\u306E\u540D\u524D\u3092\u5909\u66F4\u3067\u304D\u307E\u305B\u3093: \u6307\u5B9A\u3057\u305F\u540D\u524D\u306E\u30D5\u30A1\u30A4\u30EB\u306F\u3059\u3067\u306B\u5B58\u5728\u3057\u307E\u3059\u3002\u5225\u306E\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002 FileChooser.acceptAllFileFilterText=\u3059\u3079\u3066\u306E\u30D5\u30A1\u30A4\u30EB -FileChooser.cancelButtonText=\u53D6\u6D88(C) +FileChooser.cancelButtonText=\u53D6\u6D88 FileChooser.cancelButtonMnemonic=67 FileChooser.saveButtonText=\u4FDD\u5B58 FileChooser.saveButtonMnemonic=83 diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties index 970e57bf375..592d4672442 100644 --- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties +++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties @@ -55,7 +55,7 @@ FileChooser.renameErrorTitleText=\uD30C\uC77C \uB610\uB294 \uD3F4\uB354 \uC774\u FileChooser.renameErrorText={0}\uC758 \uC774\uB984\uC744 \uBC14\uAFC0 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. FileChooser.renameErrorFileExistsText={0}\uC758 \uC774\uB984\uC744 \uBC14\uAFC0 \uC218 \uC5C6\uC74C: \uC9C0\uC815\uD55C \uC774\uB984\uC744 \uC0AC\uC6A9\uD558\uB294 \uD30C\uC77C\uC774 \uC874\uC7AC\uD569\uB2C8\uB2E4. \uB2E4\uB978 \uD30C\uC77C \uC774\uB984\uC744 \uC9C0\uC815\uD558\uC2ED\uC2DC\uC624. FileChooser.acceptAllFileFilterText=\uBAA8\uB4E0 \uD30C\uC77C -FileChooser.cancelButtonText=\uCDE8\uC18C(C) +FileChooser.cancelButtonText=\uCDE8\uC18C FileChooser.cancelButtonMnemonic=67 FileChooser.saveButtonText=\uC800\uC7A5 FileChooser.saveButtonMnemonic=83 diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_CN.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_CN.properties index 0714ac53c35..10cecd846d9 100644 --- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_CN.properties +++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_CN.properties @@ -55,7 +55,7 @@ FileChooser.renameErrorTitleText=\u91CD\u547D\u540D\u6587\u4EF6\u6216\u6587\u4EF FileChooser.renameErrorText=\u65E0\u6CD5\u91CD\u547D\u540D{0} FileChooser.renameErrorFileExistsText=\u65E0\u6CD5\u91CD\u547D\u540D{0}: \u5DF2\u5B58\u5728\u5177\u6709\u6240\u6307\u5B9A\u540D\u79F0\u7684\u6587\u4EF6\u3002\u8BF7\u6307\u5B9A\u5176\u4ED6\u6587\u4EF6\u540D\u3002 FileChooser.acceptAllFileFilterText=\u6240\u6709\u6587\u4EF6 -FileChooser.cancelButtonText=\u53D6\u6D88(C) +FileChooser.cancelButtonText=\u53D6\u6D88 FileChooser.cancelButtonMnemonic=67 FileChooser.saveButtonText=\u4FDD\u5B58 FileChooser.saveButtonMnemonic=83 diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_TW.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_TW.properties index 141938565c9..53a4bfb989b 100644 --- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_TW.properties +++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_TW.properties @@ -55,7 +55,7 @@ FileChooser.renameErrorTitleText=\u91CD\u65B0\u547D\u540D\u6A94\u6848\u6216\u8CC FileChooser.renameErrorText=\u7121\u6CD5\u91CD\u65B0\u547D\u540D {0} FileChooser.renameErrorFileExistsText=\u7121\u6CD5\u91CD\u65B0\u547D\u540D {0}: \u5DF2\u7D93\u5B58\u5728\u60A8\u6240\u6307\u5B9A\u540D\u7A31\u7684\u6A94\u6848\u3002\u8ACB\u6307\u5B9A\u4E0D\u540C\u7684\u540D\u7A31\u3002 FileChooser.acceptAllFileFilterText=\u6240\u6709\u6A94\u6848 -FileChooser.cancelButtonText=\u53D6\u6D88(C) +FileChooser.cancelButtonText=\u53D6\u6D88 FileChooser.cancelButtonMnemonic=67 FileChooser.saveButtonText=\u5132\u5B58 FileChooser.saveButtonMnemonic=83 From 8b55d3b5017730974b7c47ec4d98487713fc8cd8 Mon Sep 17 00:00:00 2001 From: Michael Fang Date: Thu, 28 Apr 2011 21:43:40 -0700 Subject: [PATCH 62/80] 7040257: [pt_BR,fr] Print dialog has duplicate mnemonic key Reviewed-by: psun --- .../sun/print/resources/serviceui_fr.properties | 6 +++--- .../print/resources/serviceui_pt_BR.properties | 16 ++++++++-------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/jdk/src/share/classes/sun/print/resources/serviceui_fr.properties b/jdk/src/share/classes/sun/print/resources/serviceui_fr.properties index 7c64e8a4138..a74d5677454 100644 --- a/jdk/src/share/classes/sun/print/resources/serviceui_fr.properties +++ b/jdk/src/share/classes/sun/print/resources/serviceui_fr.properties @@ -49,7 +49,7 @@ label.source=Source : label.source.mnemonic=C label.status=Statut : label.username=Nom utilisateur : -label.username.mnemonic=U +label.username.mnemonic=O label.millimetres=(mm) label.inches=(po) label.topmargin=haut @@ -62,7 +62,7 @@ label.rightmargin=droite label.rightmargin.mnemonic=D # radiobutton.color=Couleur -radiobutton.color.mnemonic=U +radiobutton.color.mnemonic=C radiobutton.draftq=Brouillon radiobutton.draftq.mnemonic=L radiobutton.duplex=Duplex @@ -70,7 +70,7 @@ radiobutton.duplex.mnemonic=D radiobutton.highq=Max. radiobutton.highq.mnemonic=X radiobutton.landscape=Paysage -radiobutton.landscape.mnemonic=S +radiobutton.landscape.mnemonic=Y radiobutton.monochrome=Monochrome radiobutton.monochrome.mnemonic=M radiobutton.normalq=Normal diff --git a/jdk/src/share/classes/sun/print/resources/serviceui_pt_BR.properties b/jdk/src/share/classes/sun/print/resources/serviceui_pt_BR.properties index 7797a2a9c06..d82178f3a4e 100644 --- a/jdk/src/share/classes/sun/print/resources/serviceui_pt_BR.properties +++ b/jdk/src/share/classes/sun/print/resources/serviceui_pt_BR.properties @@ -15,10 +15,10 @@ button.cancel=Cancelar button.ok=OK button.print=Imprimir button.properties=Propriedades... -button.properties.mnemonic=R +button.properties.mnemonic=D # checkbox.collate=Agrupar -checkbox.collate.mnemonic=A +checkbox.collate.mnemonic=R checkbox.jobsheets=P\u00E1gina com Banner checkbox.jobsheets.mnemonic=B checkbox.printtofile=Imprimir em Arquivo @@ -38,7 +38,7 @@ label.jobname.mnemonic=J label.numcopies=N\u00FAmero de c\u00F3pias: label.numcopies.mnemonic=O label.priority=Prioridade: -label.priority.mnemonic=R +label.priority.mnemonic=P label.psname=Nome: label.psname.mnemonic=N label.pstype=Tipo: @@ -59,7 +59,7 @@ label.bottommargin.mnemonic=I label.leftmargin=esquerda: label.leftmargin.mnemonic=Q label.rightmargin=direita -label.rightmargin.mnemonic=R +label.rightmargin.mnemonic=D # radiobutton.color=Cor radiobutton.color.mnemonic=O @@ -68,7 +68,7 @@ radiobutton.draftq.mnemonic=R radiobutton.duplex=Duplex radiobutton.duplex.mnemonic=D radiobutton.highq=Alta -radiobutton.highq.mnemonic=A +radiobutton.highq.mnemonic=T radiobutton.landscape=Paisagem radiobutton.landscape.mnemonic=P radiobutton.monochrome=Monocrom\u00E1tico @@ -76,7 +76,7 @@ radiobutton.monochrome.mnemonic=M radiobutton.normalq=Normal radiobutton.normalq.mnemonic=N radiobutton.oneside=Um Lado -radiobutton.oneside.mnemonic=O +radiobutton.oneside.mnemonic=L radiobutton.portrait=Retrato radiobutton.portrait.mnemonic=R radiobutton.rangeall=Tudo @@ -86,7 +86,7 @@ radiobutton.rangepages.mnemonic=P radiobutton.revlandscape=Paisagem Invertida radiobutton.revlandscape.mnemonic=N radiobutton.revportrait=Retrato Invertido -radiobutton.revportrait.mnemonic=I +radiobutton.revportrait.mnemonic=E radiobutton.tumble=Virar radiobutton.tumble.mnemonic=V # The vkMnemonics correspond with the constants defined in KeyEvent, eg @@ -96,7 +96,7 @@ tab.appearance.vkMnemonic=65 tab.general=Geral tab.general.vkMnemonic=71 tab.pagesetup=Configura\u00E7\u00E3o de P\u00E1gina -tab.pagesetup.vkMnemonic=80 +tab.pagesetup.vkMnemonic=67 # error.pagerange=Faixa de p\u00E1ginas inv\u00E1lida; insira novamente os valores (por exemplo, 1-3,5,7-10) error.destination=Nome de arquivo inv\u00E1lido; tente novamente From e8ad64314e5b39588ffdcb613a4b421aca2d4841 Mon Sep 17 00:00:00 2001 From: Jim Graham Date: Fri, 29 Apr 2011 01:40:11 -0700 Subject: [PATCH 63/80] 7020955: No focus point adjustment for RadialGradientPaint Reviewed-by: prr --- .../share/classes/java/awt/RadialGradientPaint.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/jdk/src/share/classes/java/awt/RadialGradientPaint.java b/jdk/src/share/classes/java/awt/RadialGradientPaint.java index d2ba4be3ece..c9cc43a8e32 100644 --- a/jdk/src/share/classes/java/awt/RadialGradientPaint.java +++ b/jdk/src/share/classes/java/awt/RadialGradientPaint.java @@ -49,9 +49,11 @@ import java.beans.ConstructorProperties; * from the focus point to the circumference will thus span all the gradient * colors. *

- * Specifying a focus point outside of the circle's radius will result in the - * focus being set to the intersection point of the focus-center line and the - * perimeter of the circle. + * Specifying a focus point outside of the radius of the circle will cause + * the rings of the gradient pattern to be centered on the point just inside + * the edge of the circle in the direction of the focus point. + * The rendering will internally use this modified location as if it were + * the specified focus point. *

* The user must provide an array of floats specifying how to distribute the * colors along the gradient. These values should range from 0.0 to 1.0 and @@ -621,6 +623,11 @@ public final class RadialGradientPaint extends MultipleGradientPaint { /** * Returns a copy of the focus point of the radial gradient. + * Note that if the focus point specified when the radial gradient + * was constructed lies outside of the radius of the circle, this + * method will still return the original focus point even though + * the rendering may center the rings of color on a different + * point that lies inside the radius. * * @return a {@code Point2D} object that is a copy of the focus point */ From 2ab6e13a2190b421760e1571bb8c396fc561e562 Mon Sep 17 00:00:00 2001 From: Dmitry Cherepanov Date: Fri, 29 Apr 2011 16:02:05 +0400 Subject: [PATCH 64/80] 7034291: Regression : Preedit String on active client is committed into unexpected component Reviewed-by: art, naoto --- .../native/sun/windows/awt_Component.cpp | 8 ++----- .../windows/native/sun/windows/awt_Frame.cpp | 22 ++++++++++++++++--- .../windows/native/sun/windows/awt_Frame.h | 9 ++++---- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/jdk/src/windows/native/sun/windows/awt_Component.cpp b/jdk/src/windows/native/sun/windows/awt_Component.cpp index 592a9b434b2..45236e6ffcd 100644 --- a/jdk/src/windows/native/sun/windows/awt_Component.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp @@ -1203,7 +1203,7 @@ void SpyWinMessage(HWND hwnd, UINT message, LPCTSTR szComment) { WIN_MSG(WM_IME_COMPOSITIONFULL) WIN_MSG(WM_IME_SELECT) WIN_MSG(WM_IME_CHAR) - FMT_MSG(0x0288, "WM_IME_REQUEST") + FMT_MSG(WM_IME_REQUEST) WIN_MSG(WM_IME_KEYDOWN) WIN_MSG(WM_IME_KEYUP) FMT_MSG(0x02A1, "WM_MOUSEHOVER") @@ -1733,7 +1733,7 @@ LRESULT AwtComponent::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) case WM_IME_SELECT: case WM_IME_KEYUP: case WM_IME_KEYDOWN: - case 0x0288: // WM_IME_REQUEST + case WM_IME_REQUEST: CallProxyDefWindowProc(message, wParam, lParam, retValue, mr); break; case WM_CHAR: @@ -4657,10 +4657,6 @@ void* AwtComponent::SetNativeFocusOwner(void *self) { ret: if (c && ::IsWindow(c->GetHWnd())) { sm_focusOwner = c->GetHWnd(); - AwtFrame *owner = (AwtFrame*)GetComponent(c->GetProxyToplevelContainer()); - if (owner) { - owner->SetLastProxiedFocusOwner(sm_focusOwner); - } } else { sm_focusOwner = NULL; } diff --git a/jdk/src/windows/native/sun/windows/awt_Frame.cpp b/jdk/src/windows/native/sun/windows/awt_Frame.cpp index 398aea6db67..6662d6d54c2 100644 --- a/jdk/src/windows/native/sun/windows/awt_Frame.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Frame.cpp @@ -109,7 +109,7 @@ AwtFrame::AwtFrame() { m_isMenuDropped = FALSE; m_isInputMethodWindow = FALSE; m_isUndecorated = FALSE; - m_lastProxiedFocusOwner = NULL; + m_imeTargetComponent = NULL; m_actualFocusedWindow = NULL; m_iconic = FALSE; m_zoomed = FALSE; @@ -311,6 +311,8 @@ LRESULT AwtFrame::ProxyWindowProc(UINT message, WPARAM wParam, LPARAM lParam, Ms LRESULT retValue = 0L; AwtComponent *focusOwner = NULL; + AwtComponent *imeTargetComponent = NULL; + // IME and input language related messages need to be sent to a window // which has the Java input focus switch (message) { @@ -323,15 +325,29 @@ LRESULT AwtFrame::ProxyWindowProc(UINT message, WPARAM wParam, LPARAM lParam, Ms case WM_IME_COMPOSITIONFULL: case WM_IME_SELECT: case WM_IME_CHAR: - case 0x0288: // WM_IME_REQUEST + case WM_IME_REQUEST: case WM_IME_KEYDOWN: case WM_IME_KEYUP: case WM_INPUTLANGCHANGEREQUEST: case WM_INPUTLANGCHANGE: + if (message == WM_IME_STARTCOMPOSITION) { + SetImeTargetComponent(sm_focusOwner); + } + imeTargetComponent = AwtComponent::GetComponent(GetImeTargetComponent()); + if (imeTargetComponent != NULL && + imeTargetComponent != this) // avoid recursive calls + { + retValue = imeTargetComponent->WindowProc(message, wParam, lParam); + mr = mrConsume; + } + if (message == WM_IME_ENDCOMPOSITION) { + SetImeTargetComponent(NULL); + } + break; // TODO: when a Choice's list is dropped down and we're scrolling in // the list WM_MOUSEWHEEL messages come to the poxy, not to the list. Why? case WM_MOUSEWHEEL: - focusOwner = AwtComponent::GetComponent(GetLastProxiedFocusOwner()); + focusOwner = AwtComponent::GetComponent(sm_focusOwner); if (focusOwner != NULL && focusOwner != this) // avoid recursive calls { diff --git a/jdk/src/windows/native/sun/windows/awt_Frame.h b/jdk/src/windows/native/sun/windows/awt_Frame.h index 1adca139bf9..f6d692b87eb 100644 --- a/jdk/src/windows/native/sun/windows/awt_Frame.h +++ b/jdk/src/windows/native/sun/windows/awt_Frame.h @@ -150,8 +150,8 @@ public: void CheckRetainActualFocusedWindow(HWND activatedOpositeHWnd); BOOL CheckActivateActualFocusedWindow(HWND deactivatedOpositeHWnd); - INLINE HWND GetLastProxiedFocusOwner() { return m_lastProxiedFocusOwner; } - INLINE void SetLastProxiedFocusOwner(HWND hwnd) { m_lastProxiedFocusOwner = hwnd; } + INLINE HWND GetImeTargetComponent() { return m_imeTargetComponent; } + INLINE void SetImeTargetComponent(HWND hwnd) { m_imeTargetComponent = hwnd; } protected: /* The frame is undecorated. */ @@ -179,9 +179,8 @@ private: /* The frame is an InputMethodWindow */ BOOL m_isInputMethodWindow; - /* Retains the last/current sm_focusOwner proxied. Actually, it should be - * a component of an owned window last/currently active. */ - HWND m_lastProxiedFocusOwner; + // retains the target component for the IME messages + HWND m_imeTargetComponent; /* * Fix for 4823903. From 202b18b4f568e73a1eef78094f9ff5ce7d6e2c3c Mon Sep 17 00:00:00 2001 From: Dmitry Cherepanov Date: Fri, 29 Apr 2011 16:16:25 +0400 Subject: [PATCH 65/80] 7026055: Regression : Cannot use IME on JComboBox Japanese Reviewed-by: art, ant, naoto --- .../native/sun/windows/awt_Component.cpp | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/jdk/src/windows/native/sun/windows/awt_Component.cpp b/jdk/src/windows/native/sun/windows/awt_Component.cpp index 45236e6ffcd..024915fcffc 100644 --- a/jdk/src/windows/native/sun/windows/awt_Component.cpp +++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp @@ -549,8 +549,6 @@ AwtComponent::CreateHWnd(JNIEnv *env, LPCWSTR title, m_hwnd = hwnd; - ImmAssociateContext(NULL); - SetDrawState((jint)JAWT_LOCK_SURFACE_CHANGED | (jint)JAWT_LOCK_BOUNDS_CHANGED | (jint)JAWT_LOCK_CLIP_CHANGED); @@ -2022,25 +2020,6 @@ MsgRouting AwtComponent::WmExitMenuLoop(BOOL isTrackPopupMenu) MsgRouting AwtComponent::WmShowWindow(BOOL show, UINT status) { - // NULL-InputContext is associated to all window just after they created. - // ( see CreateHWnd() ) - // But to TextField and TextArea on Win95, valid InputContext is associated - // by system after that. This is not happen on NT4.0 - // For workaround, force context to NULL here. - - // Fix for 4730228 - // Check if we already have Java-associated input method - HIMC context = 0; - if (m_InputMethod != NULL) { - // If so get the appropriate context from it and use it instead of empty context - JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); - context = (HIMC)(UINT_PTR)(JNU_GetFieldByName(env, NULL, m_InputMethod, "context", "I").i); - } - - if (ImmGetContext() != 0 && ImmGetContext() != context) { - ImmAssociateContext(context); - } - return mrDoDefault; } From 6b348af4c0a33f84fd73253bfa4efcaa78942816 Mon Sep 17 00:00:00 2001 From: Jim Graham Date: Fri, 29 Apr 2011 10:58:33 -0700 Subject: [PATCH 66/80] 6522514: Extending Arc2D.Double and serializing the object causes InvalidClassException Reviewed-by: prr --- jdk/src/share/classes/java/awt/geom/Arc2D.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/share/classes/java/awt/geom/Arc2D.java b/jdk/src/share/classes/java/awt/geom/Arc2D.java index 86653be120c..802ec5a5297 100644 --- a/jdk/src/share/classes/java/awt/geom/Arc2D.java +++ b/jdk/src/share/classes/java/awt/geom/Arc2D.java @@ -681,7 +681,7 @@ public abstract class Arc2D extends RectangularShape { * @see java.awt.geom.Arc2D.Float * @see java.awt.geom.Arc2D.Double */ - Arc2D() { + protected Arc2D() { this(OPEN); } From 589a17bd790d360f3b15edcd5ed24845a22dcebb Mon Sep 17 00:00:00 2001 From: Jim Graham Date: Fri, 29 Apr 2011 16:27:34 -0700 Subject: [PATCH 67/80] 6982632: closed/java/awt/Graphics2D/MTGraphicsAccessTest/MTGraphicsAccessTest.java fails Reviewed-by: prr --- .../MTGraphicsAccessTest.java | 361 ++++++++++++++++++ 1 file changed, 361 insertions(+) create mode 100644 jdk/test/java/awt/Graphics2D/MTGraphicsAccessTest/MTGraphicsAccessTest.java diff --git a/jdk/test/java/awt/Graphics2D/MTGraphicsAccessTest/MTGraphicsAccessTest.java b/jdk/test/java/awt/Graphics2D/MTGraphicsAccessTest/MTGraphicsAccessTest.java new file mode 100644 index 00000000000..569af1f3aaf --- /dev/null +++ b/jdk/test/java/awt/Graphics2D/MTGraphicsAccessTest/MTGraphicsAccessTest.java @@ -0,0 +1,361 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 5089429 6982632 + @summary Checks that we don't crash if rendering operations and state + changes are performed on a graphics context from different threads. + + @author Dmitri.Trembovetski@sun.com area=Graphics + @run main MTGraphicsAccessTest + */ + +import java.awt.*; +import java.awt.image.*; +import java.awt.geom.*; + +public class MTGraphicsAccessTest { + + // in seconds + static final long STANDALONE_RUN_TIME = 20; + static final long JTREG_RUN_TIME = 7; + + static boolean standaloneMode; + static boolean allowExceptions = true; + static long testRunTime; + + volatile boolean done; + volatile int stillRunning; + volatile int numexceptions; + + Graphics2D sharedGraphics; + BufferedImage sharedBI = + new BufferedImage(50, 50, BufferedImage.TYPE_INT_RGB); + + static final Paint colors[] = { + Color.red, + new Color(0x7f, 0xff, 0x00, 0x7f), + new GradientPaint(0, 0, Color.red, + 50, 50, new Color(0x7f, 0xff, 0x00, 0x7f)), + }; + static final Font fonts[] = { + new Font("Dialog", Font.PLAIN, 12), + new Font("Dialog", Font.BOLD, 16), + new Font("Dialog", Font.ITALIC, 18), + }; + static final AlphaComposite comps[] = { + AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f), + AlphaComposite.Src, + AlphaComposite.Xor, + AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f), + null, + }; + static final Stroke strokes[] = { + new BasicStroke(), + new BasicStroke(0.0f), + new BasicStroke(2.0f), + new BasicStroke(2.0f, BasicStroke.CAP_ROUND, + BasicStroke.JOIN_BEVEL), + new BasicStroke(5.0f, BasicStroke.CAP_SQUARE, + BasicStroke.JOIN_ROUND), + new BasicStroke(0.0f, BasicStroke.CAP_ROUND, + BasicStroke.JOIN_ROUND, 0, + new float[]{0,6,0,6}, 0), + }; + static final AffineTransform transforms[] = { + new AffineTransform(), + AffineTransform.getRotateInstance(10.0), + AffineTransform.getShearInstance(10.0, 4.0), + AffineTransform.getScaleInstance(1.1, 1.2), + AffineTransform.getScaleInstance(3.0, 2.0), + }; + + public MTGraphicsAccessTest() { + BufferedImage bi = + new BufferedImage(50, 50, BufferedImage.TYPE_INT_RGB); + sharedGraphics = (Graphics2D)bi.getGraphics(); + + done = false; + numexceptions = 0; + + for (int i = 0; i < (standaloneMode ? stateChangers.length : 3); i++) { + (new TesterThread(stateChangers[i])).start(); + } + for (int i = 0; i < (standaloneMode ? renderTests.length : 5); i++) { + (new TesterThread(renderTests[i])).start(); + } + + mysleep(testRunTime); + done = true; + while (stillRunning > 0) { mysleep(500); } + + if (numexceptions == 0) { + System.err.println("Test passed"); + } else if (!allowExceptions) { + throw new RuntimeException("Test failed with "+ + numexceptions+" exceptions"); + } else { + System.err.println("Test finished with "+ + numexceptions+" exceptions"); + } + } + + private void mysleep(long time) { + try { + // add +/-5ms variance to increase randomness + Thread.sleep(time + (long)(5 - Math.random()*10)); + } catch (InterruptedException e) {}; + } + + public static void usage(String message) { + if (message != null) { + System.err.println(message); + } + System.err.println("Usage: MTGraphicsAccessTest [-full] "+ + "[-time N/forever] [-help]"); + System.err.println(" -full: run full suite of tests "+ + "(default: limited number of tests is run)"); + System.err.println(" -time N: test duration in seconds/forever"+ + " (default: "+JTREG_RUN_TIME+"s for the short suite, "+ + STANDALONE_RUN_TIME+"s for the full suite)"); + System.err.println(" -help: print this help page"); + System.exit(1); + } + + public static void main(String[] args) { + boolean testRunSet = false; + for (int i = 0; i < args.length; i++) { + if ("-full".equals(args[i])) { + standaloneMode = true; + System.err.println("Running complete list of tests"); + } else if ("-noexc".equals(args[i])) { + allowExceptions = false; + } else if ("-time".equals(args[i])) { + try { + String time = args[++i]; + if ("forever".equals(time)) { + testRunTime = (Long.MAX_VALUE - 20)/1000; + } else { + testRunTime = 1000*Integer.parseInt(time); + } + testRunSet = true; + } catch (NumberFormatException e) { + usage("Can't parse number of seconds: " + args[i]); + } catch (ArrayIndexOutOfBoundsException e1) { + usage("Missing the 'seconds' argument for -time parameter"); + } + } else if ("-help".equals(args[i])) { + usage(null); + } else { + usage("Unknown argument:" + args[i]); + } + } + + if (!testRunSet) { + testRunTime = 1000 * + (standaloneMode ? STANDALONE_RUN_TIME : JTREG_RUN_TIME); + } + + System.err.println("Approximate test run time: "+ + testRunTime/1000+" seconds"); + + new MTGraphicsAccessTest(); + } + + class TesterThread extends Thread { + Runnable testRunnable; + + public TesterThread(Runnable testRunnable) { + stillRunning++; + this.testRunnable = testRunnable; + } + + public void run() { + try { + while (!done) { + try { + testRunnable.run(); + yield(); + } catch (Throwable t) { + numexceptions++; + t.printStackTrace(); + } + } + } finally { + stillRunning--; + } + } + } + + final Runnable stateChangers[] = { + new Runnable() { + public void run() { + sharedGraphics.setClip(10, 10, 30, 30); + mysleep(10); + } + }, + new Runnable() { + public void run() { + sharedGraphics.setClip(10, 10, 30, 30); + mysleep(10); + } + }, + new Runnable() { + int c = 0; + public void run() { + sharedGraphics.setPaint(colors[c++ % colors.length]); + mysleep(10); + } + }, + new Runnable() { + boolean AA = false; + public void run() { + if (AA) { + sharedGraphics.setRenderingHint( + RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + } else { + sharedGraphics.setRenderingHint( + RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_OFF); + } + AA = !AA; + mysleep(10); + } + }, + new Runnable() { + int t = 0; + public void run() { + sharedGraphics.setTransform( + transforms[t++ % transforms.length]); + mysleep(10); + } + }, + new Runnable() { + int c = 0; + public void run() { + AlphaComposite comp = comps[c++ % comps.length]; + if (comp == null) { + sharedGraphics.setXORMode(Color.green); + } else { + sharedGraphics.setComposite(comp); + } + mysleep(10); + } + }, + new Runnable() { + int s = 0; + public void run() { + sharedGraphics.setStroke(strokes[s++ % strokes.length]); + mysleep(10); + } + }, + new Runnable() { + int f = 0; + public void run() { + sharedGraphics.setFont(fonts[f++ % fonts.length]); + mysleep(10); + } + }, + }; + + final Runnable renderTests[] = { + new Runnable() { + public void run() { + sharedGraphics.drawLine(10, 10, 30, 30); + } + }, + new Runnable() { + public void run() { + sharedGraphics.drawLine(10, 10, 30, 30); + } + }, + new Runnable() { + public void run() { + sharedGraphics.drawRect(10, 10, 30, 30); + } + }, + new Runnable() { + public void run() { + sharedGraphics.fillRect(10, 10, 30, 30); + } + }, + new Runnable() { + public void run() { + sharedGraphics.drawString("Stuff", 10, 10); + } + }, + new Runnable() { + public void run() { + sharedGraphics.draw3DRect(10, 10, 30, 30, true); + } + }, + new Runnable() { + public void run() { + sharedGraphics.drawImage(sharedBI, 10, 10, null); + } + }, + new Runnable() { + public void run() { + sharedGraphics.fill3DRect(10, 10, 30, 30, false); + } + }, + // REMIND: copyArea doesn't work when transform is set.. + // new Runnable() { + // public void run() { + // sharedGraphics.copyArea(10, 10, 30, 30, 20, 20); + // } + // }, + new Runnable() { + public void run() { + sharedGraphics.drawRoundRect(10, 10, 30, 30, 20, 20); + } + }, + new Runnable() { + public void run() { + sharedGraphics.fillRoundRect(10, 10, 30, 30, 20, 20); + } + }, + new Runnable() { + public void run() { + sharedGraphics.drawArc(10, 10, 30, 30, 0, 90); + } + }, + new Runnable() { + public void run() { + sharedGraphics.fillArc(10, 10, 30, 30, 0, 90); + } + }, + new Runnable() { + public void run() { + sharedGraphics.drawOval(10, 10, 30, 30); + } + }, + new Runnable() { + public void run() { + sharedGraphics.fillOval(10, 10, 30, 30); + } + } + }; +} From caba73d1dd4f32c5ae8d3d667e7ccba8e9421275 Mon Sep 17 00:00:00 2001 From: Erik Trimble Date: Fri, 29 Apr 2011 17:00:19 -0700 Subject: [PATCH 68/80] 7040777: Bump the HS21 build number to 11 Update the HS21 build number to 11 Reviewed-by: jcoomes --- hotspot/make/hotspot_version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/make/hotspot_version b/hotspot/make/hotspot_version index eaaf6afe6df..50085e1081c 100644 --- a/hotspot/make/hotspot_version +++ b/hotspot/make/hotspot_version @@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2011 HS_MAJOR_VER=21 HS_MINOR_VER=0 -HS_BUILD_NUMBER=10 +HS_BUILD_NUMBER=11 JDK_MAJOR_VER=1 JDK_MINOR_VER=7 From 2b924057aae6e39dcf586f2e14c0b88a14963b30 Mon Sep 17 00:00:00 2001 From: Igor Nekrestyanov Date: Sun, 1 May 2011 09:14:36 -0700 Subject: [PATCH 69/80] 7040803: regression: bugster fail to start Reviewed-by: mullan, weijun, ngthomas --- .../share/classes/java/util/jar/JarFile.java | 22 +- .../classes/java/util/jar/JarInputStream.java | 2 +- .../classes/java/util/jar/JarVerifier.java | 224 ++++++++++++---- .../classes/sun/security/pkcs/PKCS7.java | 176 +----------- .../classes/sun/security/pkcs/SignerInfo.java | 136 +++++++++- .../security/util/ManifestEntryVerifier.java | 4 +- .../security/util/SignatureFileManifest.java | 251 ------------------ .../security/util/SignatureFileVerifier.java | 172 ++++-------- .../jar/JarInputStream/ScanSignedJar.java | 7 +- .../TestIndexedJarWithBadSignature.java | 4 +- 10 files changed, 377 insertions(+), 621 deletions(-) delete mode 100644 jdk/src/share/classes/sun/security/util/SignatureFileManifest.java diff --git a/jdk/src/share/classes/java/util/jar/JarFile.java b/jdk/src/share/classes/java/util/jar/JarFile.java index 20d0363f57a..79d0f84b7e1 100644 --- a/jdk/src/share/classes/java/util/jar/JarFile.java +++ b/jdk/src/share/classes/java/util/jar/JarFile.java @@ -37,7 +37,6 @@ import java.security.CodeSource; import sun.security.action.GetPropertyAction; import sun.security.util.ManifestEntryVerifier; import sun.misc.SharedSecrets; -import sun.security.util.SignatureFileVerifier; /** * The JarFile class is used to read the contents of a jar file @@ -179,7 +178,7 @@ class JarFile extends ZipFile { byte[] b = getBytes(manEntry); man = new Manifest(new ByteArrayInputStream(b)); if (!jvInitialized) { - jv = new JarVerifier(b, man); + jv = new JarVerifier(b); } } else { man = new Manifest(super.getInputStream(manEntry)); @@ -298,7 +297,10 @@ class JarFile extends ZipFile { if (names != null) { for (int i = 0; i < names.length; i++) { String name = names[i].toUpperCase(Locale.ENGLISH); - if (SignatureFileVerifier.isBlockOrSF(name)) { + if (name.endsWith(".DSA") || + name.endsWith(".RSA") || + name.endsWith(".EC") || + name.endsWith(".SF")) { // Assume since we found a signature-related file // that the jar is signed and that we therefore // need a JarVerifier and Manifest @@ -327,17 +329,17 @@ class JarFile extends ZipFile { if (names != null) { for (int i = 0; i < names.length; i++) { JarEntry e = getJarEntry(names[i]); - if (!e.isDirectory() && - SignatureFileVerifier.isBlock(names[i])) { + if (!e.isDirectory()) { if (mev == null) { mev = new ManifestEntryVerifier (getManifestFromReference()); } - String key = names[i].substring( - 0, names[i].lastIndexOf(".")); - jv.verifyBlock(names[i], - getBytes(e), - super.getInputStream(getJarEntry(key + ".SF"))); + byte[] b = getBytes(e); + if (b != null && b.length > 0) { + jv.beginEntry(e, mev); + jv.update(b.length, b, 0, b.length, mev); + jv.update(-1, null, 0, 0, mev); + } } } } diff --git a/jdk/src/share/classes/java/util/jar/JarInputStream.java b/jdk/src/share/classes/java/util/jar/JarInputStream.java index b84219ea87a..67f27be2975 100644 --- a/jdk/src/share/classes/java/util/jar/JarInputStream.java +++ b/jdk/src/share/classes/java/util/jar/JarInputStream.java @@ -95,7 +95,7 @@ class JarInputStream extends ZipInputStream { man.read(new ByteArrayInputStream(bytes)); closeEntry(); if (doVerify) { - jv = new JarVerifier(bytes, man); + jv = new JarVerifier(bytes); mev = new ManifestEntryVerifier(man); } return (JarEntry)super.getNextEntry(); diff --git a/jdk/src/share/classes/java/util/jar/JarVerifier.java b/jdk/src/share/classes/java/util/jar/JarVerifier.java index 8c69ff5c583..4f84ac28eff 100644 --- a/jdk/src/share/classes/java/util/jar/JarVerifier.java +++ b/jdk/src/share/classes/java/util/jar/JarVerifier.java @@ -48,18 +48,35 @@ class JarVerifier { /* a table mapping names to code signers, for jar entries that have had their actual hashes verified */ - private Map verifiedSigners; + private Hashtable verifiedSigners; /* a table mapping names to code signers, for jar entries that have passed the .SF/.DSA/.EC -> MANIFEST check */ - private Map sigFileSigners; + private Hashtable sigFileSigners; + + /* a hash table to hold .SF bytes */ + private Hashtable sigFileData; + + /** "queue" of pending PKCS7 blocks that we couldn't parse + * until we parsed the .SF file */ + private ArrayList pendingBlocks; /* cache of CodeSigner objects */ private ArrayList signerCache; + /* Are we parsing a block? */ + private boolean parsingBlockOrSF = false; + + /* Are we done parsing META-INF entries? */ + private boolean parsingMeta = true; + /* Are there are files to verify? */ private boolean anyToVerify = true; + /* The output stream to use when keeping track of files we are interested + in */ + private ByteArrayOutputStream baos; + /** The ManifestDigester object */ private volatile ManifestDigester manDig; @@ -75,20 +92,20 @@ class JarVerifier { /** collect -DIGEST-MANIFEST values for blacklist */ private List manifestDigests; - /** The manifest object */ - Manifest man = null; - - public JarVerifier(byte rawBytes[], Manifest man) { - this.man = man; + public JarVerifier(byte rawBytes[]) { manifestRawBytes = rawBytes; - sigFileSigners = new HashMap(); - verifiedSigners = new HashMap(); + sigFileSigners = new Hashtable(); + verifiedSigners = new Hashtable(); + sigFileData = new Hashtable(11); + pendingBlocks = new ArrayList(); + baos = new ByteArrayOutputStream(); manifestDigests = new ArrayList(); } /** - * This method scans to see which entry we're parsing and keeps - * various state information depending on the file being parsed. + * This method scans to see which entry we're parsing and + * keeps various state information depending on what type of + * file is being parsed. */ public void beginEntry(JarEntry je, ManifestEntryVerifier mev) throws IOException @@ -112,6 +129,30 @@ class JarVerifier { * b. digest mismatch between the actual jar entry and the manifest */ + if (parsingMeta) { + String uname = name.toUpperCase(Locale.ENGLISH); + if ((uname.startsWith("META-INF/") || + uname.startsWith("/META-INF/"))) { + + if (je.isDirectory()) { + mev.setEntry(null, je); + return; + } + + if (SignatureFileVerifier.isBlockOrSF(uname)) { + /* We parse only DSA, RSA or EC PKCS7 blocks. */ + parsingBlockOrSF = true; + baos.reset(); + mev.setEntry(null, je); + } + return; + } + } + + if (parsingMeta) { + doneWithMeta(); + } + if (je.isDirectory()) { mev.setEntry(null, je); return; @@ -147,7 +188,11 @@ class JarVerifier { throws IOException { if (b != -1) { - mev.update((byte)b); + if (parsingBlockOrSF) { + baos.write(b); + } else { + mev.update((byte)b); + } } else { processEntry(mev); } @@ -162,7 +207,11 @@ class JarVerifier { throws IOException { if (n != -1) { - mev.update(b, off, n); + if (parsingBlockOrSF) { + baos.write(b, off, n); + } else { + mev.update(b, off, n); + } } else { processEntry(mev); } @@ -174,10 +223,101 @@ class JarVerifier { private void processEntry(ManifestEntryVerifier mev) throws IOException { - JarEntry je = mev.getEntry(); - if ((je != null) && (je.signers == null)) { - je.signers = mev.verify(verifiedSigners, sigFileSigners); - je.certs = mapSignersToCertArray(je.signers); + if (!parsingBlockOrSF) { + JarEntry je = mev.getEntry(); + if ((je != null) && (je.signers == null)) { + je.signers = mev.verify(verifiedSigners, sigFileSigners); + je.certs = mapSignersToCertArray(je.signers); + } + } else { + + try { + parsingBlockOrSF = false; + + if (debug != null) { + debug.println("processEntry: processing block"); + } + + String uname = mev.getEntry().getName() + .toUpperCase(Locale.ENGLISH); + + if (uname.endsWith(".SF")) { + String key = uname.substring(0, uname.length()-3); + byte bytes[] = baos.toByteArray(); + // add to sigFileData in case future blocks need it + sigFileData.put(key, bytes); + // check pending blocks, we can now process + // anyone waiting for this .SF file + Iterator it = pendingBlocks.iterator(); + while (it.hasNext()) { + SignatureFileVerifier sfv = + (SignatureFileVerifier) it.next(); + if (sfv.needSignatureFile(key)) { + if (debug != null) { + debug.println( + "processEntry: processing pending block"); + } + + sfv.setSignatureFile(bytes); + sfv.process(sigFileSigners, manifestDigests); + } + } + return; + } + + // now we are parsing a signature block file + + String key = uname.substring(0, uname.lastIndexOf(".")); + + if (signerCache == null) + signerCache = new ArrayList(); + + if (manDig == null) { + synchronized(manifestRawBytes) { + if (manDig == null) { + manDig = new ManifestDigester(manifestRawBytes); + manifestRawBytes = null; + } + } + } + + SignatureFileVerifier sfv = + new SignatureFileVerifier(signerCache, + manDig, uname, baos.toByteArray()); + + if (sfv.needSignatureFileBytes()) { + // see if we have already parsed an external .SF file + byte[] bytes = (byte[]) sigFileData.get(key); + + if (bytes == null) { + // put this block on queue for later processing + // since we don't have the .SF bytes yet + // (uname, block); + if (debug != null) { + debug.println("adding pending block"); + } + pendingBlocks.add(sfv); + return; + } else { + sfv.setSignatureFile(bytes); + } + } + sfv.process(sigFileSigners, manifestDigests); + + } catch (IOException ioe) { + // e.g. sun.security.pkcs.ParsingException + if (debug != null) debug.println("processEntry caught: "+ioe); + // ignore and treat as unsigned + } catch (SignatureException se) { + if (debug != null) debug.println("processEntry caught: "+se); + // ignore and treat as unsigned + } catch (NoSuchAlgorithmException nsae) { + if (debug != null) debug.println("processEntry caught: "+nsae); + // ignore and treat as unsigned + } catch (CertificateException ce) { + if (debug != null) debug.println("processEntry caught: "+ce); + // ignore and treat as unsigned + } } } @@ -214,15 +354,15 @@ class JarVerifier { * Force a read of the entry data to generate the * verification hash. */ - try (InputStream s = jar.getInputStream(entry)) { + try { + InputStream s = jar.getInputStream(entry); byte[] buffer = new byte[1024]; int n = buffer.length; while (n != -1) { n = s.read(buffer, 0, buffer.length); } + s.close(); } catch (IOException e) { - // Ignore. When an exception is thrown, code signer - // will not be assigned. } } return getCodeSigners(name); @@ -268,7 +408,11 @@ class JarVerifier { */ void doneWithMeta() { + parsingMeta = false; anyToVerify = !sigFileSigners.isEmpty(); + baos = null; + sigFileData = null; + pendingBlocks = null; signerCache = null; manDig = null; // MANIFEST.MF is always treated as signed and verified, @@ -279,41 +423,6 @@ class JarVerifier { } } - /** - * Verifies a PKCS7 SignedData block - * @param key name of block - * @param block the pkcs7 file - * @param ins the clear data - */ - void verifyBlock(String key, byte[] block, InputStream ins) { - try { - if (signerCache == null) - signerCache = new ArrayList(); - - if (manDig == null) { - synchronized(manifestRawBytes) { - if (manDig == null) { - manDig = new ManifestDigester(manifestRawBytes); - manifestRawBytes = null; - } - } - } - SignatureFileVerifier sfv = - new SignatureFileVerifier(signerCache, man, - manDig, key, block); - - if (sfv.needSignatureFile()) { - // see if we have already parsed an external .SF file - sfv.setSignatureFile(ins); - } - sfv.process(sigFileSigners, manifestDigests); - } catch (Exception e) { - if (debug != null) { - e.printStackTrace(); - } - } - } - static class VerifierStream extends java.io.InputStream { private InputStream is; @@ -444,7 +553,10 @@ class JarVerifier { * but this handles a CodeSource of any type, just in case. */ CodeSource[] sources = mapSignersToCodeSources(cs.getLocation(), getJarCodeSigners(), true); - List sourceList = Arrays.asList(sources); + List sourceList = new ArrayList(); + for (int i = 0; i < sources.length; i++) { + sourceList.add(sources[i]); + } int j = sourceList.indexOf(cs); if (j != -1) { CodeSigner[] match; diff --git a/jdk/src/share/classes/sun/security/pkcs/PKCS7.java b/jdk/src/share/classes/sun/security/pkcs/PKCS7.java index 72a2e5f9f3e..54e52151256 100644 --- a/jdk/src/share/classes/sun/security/pkcs/PKCS7.java +++ b/jdk/src/share/classes/sun/security/pkcs/PKCS7.java @@ -38,7 +38,6 @@ import java.security.*; import sun.security.util.*; import sun.security.x509.AlgorithmId; import sun.security.x509.CertificateIssuerName; -import sun.security.x509.KeyUsageExtension; import sun.security.x509.X509CertImpl; import sun.security.x509.X509CertInfo; import sun.security.x509.X509CRLImpl; @@ -493,7 +492,7 @@ public class PKCS7 { // CRLs (optional) if (crls != null && crls.length != 0) { // cast to X509CRLImpl[] since X509CRLImpl implements DerEncoder - Set implCRLs = new HashSet<>(crls.length); + Set implCRLs = new HashSet(crls.length); for (X509CRL crl: crls) { if (crl instanceof X509CRLImpl) implCRLs.add((X509CRLImpl) crl); @@ -530,168 +529,6 @@ public class PKCS7 { block.encode(out); } - /** - * Verifying signed data using an external chunked data source. - */ - public static class PKCS7Verifier { - - private final SignerInfo si; // Signer to verify - private final MessageDigest md; // MessageDigest object for chunks - private final Signature sig; // Signature object for chunks - - private PKCS7Verifier(SignerInfo si, MessageDigest md, Signature sig) { - this.si = si; - this.md = md; - this.sig = sig; - } - - public static PKCS7Verifier from(PKCS7 block, SignerInfo si) throws - SignatureException, NoSuchAlgorithmException { - - try { - MessageDigest md = null; - Signature sig; - - ContentInfo content = block.getContentInfo(); - String digestAlgname = si.getDigestAlgorithmId().getName(); - - // if there are authenticate attributes, feed data chunks to - // the message digest. In this case, pv.md is not null - if (si.authenticatedAttributes != null) { - // first, check content type - ObjectIdentifier contentType = (ObjectIdentifier) - si.authenticatedAttributes.getAttributeValue( - PKCS9Attribute.CONTENT_TYPE_OID); - if (contentType == null || - !contentType.equals(content.contentType)) - return null; // contentType does not match, bad SignerInfo - - // now, check message digest - byte[] messageDigest = (byte[]) - si.authenticatedAttributes.getAttributeValue( - PKCS9Attribute.MESSAGE_DIGEST_OID); - - if (messageDigest == null) // fail if there is no message digest - return null; - - md = MessageDigest.getInstance(digestAlgname); - } - - // put together digest algorithm and encryption algorithm - // to form signing algorithm - String encryptionAlgname = - si.getDigestEncryptionAlgorithmId().getName(); - - // Workaround: sometimes the encryptionAlgname is actually - // a signature name - String tmp = AlgorithmId.getEncAlgFromSigAlg(encryptionAlgname); - if (tmp != null) encryptionAlgname = tmp; - String algname = AlgorithmId.makeSigAlg( - digestAlgname, encryptionAlgname); - - sig = Signature.getInstance(algname); - X509Certificate cert = si.getCertificate(block); - - if (cert == null) { - return null; - } - if (cert.hasUnsupportedCriticalExtension()) { - throw new SignatureException("Certificate has unsupported " - + "critical extension(s)"); - } - - // Make sure that if the usage of the key in the certificate is - // restricted, it can be used for digital signatures. - // XXX We may want to check for additional extensions in the - // future. - boolean[] keyUsageBits = cert.getKeyUsage(); - if (keyUsageBits != null) { - KeyUsageExtension keyUsage; - try { - // We don't care whether or not this extension was marked - // critical in the certificate. - // We're interested only in its value (i.e., the bits set) - // and treat the extension as critical. - keyUsage = new KeyUsageExtension(keyUsageBits); - } catch (IOException ioe) { - throw new SignatureException("Failed to parse keyUsage " - + "extension"); - } - - boolean digSigAllowed = ((Boolean)keyUsage.get( - KeyUsageExtension.DIGITAL_SIGNATURE)).booleanValue(); - - boolean nonRepuAllowed = ((Boolean)keyUsage.get( - KeyUsageExtension.NON_REPUDIATION)).booleanValue(); - - if (!digSigAllowed && !nonRepuAllowed) { - throw new SignatureException("Key usage restricted: " - + "cannot be used for " - + "digital signatures"); - } - } - - PublicKey key = cert.getPublicKey(); - sig.initVerify(key); - return new PKCS7Verifier(si, md, sig); - } catch (IOException e) { - throw new SignatureException("IO error verifying signature:\n" + - e.getMessage()); - - } catch (InvalidKeyException e) { - throw new SignatureException("InvalidKey: " + e.getMessage()); - - } - } - - public void update(byte[] data, int off, int end) - throws SignatureException { - if (md != null) { - md.update(data, off, end-off); - } else { - sig.update(data, off, end-off); - } - } - - public SignerInfo verify() throws SignatureException { - try { - // if there are authenticate attributes, get the message - // digest and compare it with the digest of data - if (md != null) { - // now, check message digest - byte[] messageDigest = (byte[]) - si.authenticatedAttributes.getAttributeValue( - PKCS9Attribute.MESSAGE_DIGEST_OID); - - byte[] computedMessageDigest = md.digest(); - - if (!MessageDigest.isEqual( - messageDigest, computedMessageDigest)) { - return null; - } - - // message digest attribute matched - // digest of original data - - // the data actually signed is the DER encoding of - // the authenticated attributes (tagged with - // the "SET OF" tag, not 0xA0). - byte[] dataSigned = si.authenticatedAttributes.getDerEncoding(); - sig.update(dataSigned); - } - - if (sig.verify(si.getEncryptedDigest())) { - return si; - } - - } catch (IOException e) { - throw new SignatureException("IO error verifying signature:\n" + - e.getMessage()); - } - return null; - } - } - /** * This verifies a given SignerInfo. * @@ -717,16 +554,19 @@ public class PKCS7 { public SignerInfo[] verify(byte[] bytes) throws NoSuchAlgorithmException, SignatureException { - List intResult = new ArrayList<>(); + Vector intResult = new Vector(); for (int i = 0; i < signerInfos.length; i++) { SignerInfo signerInfo = verify(signerInfos[i], bytes); if (signerInfo != null) { - intResult.add(signerInfo); + intResult.addElement(signerInfo); } } - if (!intResult.isEmpty()) { - return intResult.toArray(new SignerInfo[intResult.size()]); + if (intResult.size() != 0) { + + SignerInfo[] result = new SignerInfo[intResult.size()]; + intResult.copyInto(result); + return result; } return null; } diff --git a/jdk/src/share/classes/sun/security/pkcs/SignerInfo.java b/jdk/src/share/classes/sun/security/pkcs/SignerInfo.java index 6addf69e416..93fab9df4e0 100644 --- a/jdk/src/share/classes/sun/security/pkcs/SignerInfo.java +++ b/jdk/src/share/classes/sun/security/pkcs/SignerInfo.java @@ -230,7 +230,7 @@ public class SignerInfo implements DerEncoder { if (userCert == null) return null; - ArrayList certList = new ArrayList<>(); + ArrayList certList = new ArrayList(); certList.add(userCert); X509Certificate[] pkcsCerts = block.getCertificates(); @@ -276,20 +276,132 @@ public class SignerInfo implements DerEncoder { /* Returns null if verify fails, this signerInfo if verify succeeds. */ SignerInfo verify(PKCS7 block, byte[] data) - throws NoSuchAlgorithmException, SignatureException { + throws NoSuchAlgorithmException, SignatureException { - PKCS7.PKCS7Verifier p7v = PKCS7.PKCS7Verifier.from(block, this); - if (p7v == null) return null; - if (data == null) { - try { - data = block.getContentInfo().getContentBytes(); - } catch (IOException e) { - throw new SignatureException("IO error verifying signature:\n" + - e.getMessage()); + try { + + ContentInfo content = block.getContentInfo(); + if (data == null) { + data = content.getContentBytes(); } + + String digestAlgname = getDigestAlgorithmId().getName(); + + byte[] dataSigned; + + // if there are authenticate attributes, get the message + // digest and compare it with the digest of data + if (authenticatedAttributes == null) { + dataSigned = data; + } else { + + // first, check content type + ObjectIdentifier contentType = (ObjectIdentifier) + authenticatedAttributes.getAttributeValue( + PKCS9Attribute.CONTENT_TYPE_OID); + if (contentType == null || + !contentType.equals(content.contentType)) + return null; // contentType does not match, bad SignerInfo + + // now, check message digest + byte[] messageDigest = (byte[]) + authenticatedAttributes.getAttributeValue( + PKCS9Attribute.MESSAGE_DIGEST_OID); + + if (messageDigest == null) // fail if there is no message digest + return null; + + MessageDigest md = MessageDigest.getInstance(digestAlgname); + byte[] computedMessageDigest = md.digest(data); + + if (messageDigest.length != computedMessageDigest.length) + return null; + for (int i = 0; i < messageDigest.length; i++) { + if (messageDigest[i] != computedMessageDigest[i]) + return null; + } + + // message digest attribute matched + // digest of original data + + // the data actually signed is the DER encoding of + // the authenticated attributes (tagged with + // the "SET OF" tag, not 0xA0). + dataSigned = authenticatedAttributes.getDerEncoding(); + } + + // put together digest algorithm and encryption algorithm + // to form signing algorithm + String encryptionAlgname = + getDigestEncryptionAlgorithmId().getName(); + + // Workaround: sometimes the encryptionAlgname is actually + // a signature name + String tmp = AlgorithmId.getEncAlgFromSigAlg(encryptionAlgname); + if (tmp != null) encryptionAlgname = tmp; + String algname = AlgorithmId.makeSigAlg( + digestAlgname, encryptionAlgname); + + Signature sig = Signature.getInstance(algname); + X509Certificate cert = getCertificate(block); + + if (cert == null) { + return null; + } + if (cert.hasUnsupportedCriticalExtension()) { + throw new SignatureException("Certificate has unsupported " + + "critical extension(s)"); + } + + // Make sure that if the usage of the key in the certificate is + // restricted, it can be used for digital signatures. + // XXX We may want to check for additional extensions in the + // future. + boolean[] keyUsageBits = cert.getKeyUsage(); + if (keyUsageBits != null) { + KeyUsageExtension keyUsage; + try { + // We don't care whether or not this extension was marked + // critical in the certificate. + // We're interested only in its value (i.e., the bits set) + // and treat the extension as critical. + keyUsage = new KeyUsageExtension(keyUsageBits); + } catch (IOException ioe) { + throw new SignatureException("Failed to parse keyUsage " + + "extension"); + } + + boolean digSigAllowed = ((Boolean)keyUsage.get( + KeyUsageExtension.DIGITAL_SIGNATURE)).booleanValue(); + + boolean nonRepuAllowed = ((Boolean)keyUsage.get( + KeyUsageExtension.NON_REPUDIATION)).booleanValue(); + + if (!digSigAllowed && !nonRepuAllowed) { + throw new SignatureException("Key usage restricted: " + + "cannot be used for " + + "digital signatures"); + } + } + + PublicKey key = cert.getPublicKey(); + sig.initVerify(key); + + sig.update(dataSigned); + + if (sig.verify(encryptedDigest)) { + return this; + } + + } catch (IOException e) { + throw new SignatureException("IO error verifying signature:\n" + + e.getMessage()); + + } catch (InvalidKeyException e) { + throw new SignatureException("InvalidKey: " + e.getMessage()); + } - p7v.update(data, 0, data.length); - return p7v.verify(); + return null; } /* Verify the content of the pkcs7 block. */ diff --git a/jdk/src/share/classes/sun/security/util/ManifestEntryVerifier.java b/jdk/src/share/classes/sun/security/util/ManifestEntryVerifier.java index 4fa1826cb37..3d1b4733c30 100644 --- a/jdk/src/share/classes/sun/security/util/ManifestEntryVerifier.java +++ b/jdk/src/share/classes/sun/security/util/ManifestEntryVerifier.java @@ -191,8 +191,8 @@ public class ManifestEntryVerifier { * * */ - public CodeSigner[] verify(Map verifiedSigners, - Map sigFileSigners) + public CodeSigner[] verify(Hashtable verifiedSigners, + Hashtable sigFileSigners) throws JarException { if (skip) { diff --git a/jdk/src/share/classes/sun/security/util/SignatureFileManifest.java b/jdk/src/share/classes/sun/security/util/SignatureFileManifest.java deleted file mode 100644 index fd00c1299a3..00000000000 --- a/jdk/src/share/classes/sun/security/util/SignatureFileManifest.java +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright (c) 2011, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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 sun.security.util; - -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; -import java.util.jar.Attributes; -import java.util.jar.Manifest; - -/** - * This class provides streaming mode reading of manifest files. - * Used by {@link SignatureFileVerifier}. - */ -class SignatureFileManifest extends Manifest { - - /* - * Reading a manifest into this object by calling update(byte[]) on chunks. - * During the reading, the bytes are saved in (@code current} until a line - * is complete and the key-value pair is saved in {@code currentAttr}. When - * a section is complete, {@code consumeAttr} is called to merge - * {@code currentAttr} into main attributes or a named entry. - */ - - // Internal state during update() style reading - // 0. not in update mode - // 1, in update mode but main attributes not completed yet - // 2. main attributes completed, still reading the entries - private int state = 0; - - // The partial line read - private byte[] current; - - // Number of bytes in current - private int currentPos = 0; - - // The current Attribute - private Attributes currentAttr; - - /** - * Reads a manifest in chunks. - *

- * This method must be called in a row, reading chunks from a single - * manifest file by order. After all chunks are read, caller must call - * {@code update(null)} to fully consume the manifest. - *

- * The entry names and attributes read will be merged in with the current - * manifest entries. The {@link #read} method cannot be called inside a - * row of update calls. - *

- * Along with the calls, caller can call {@link #getMainAttributes()}, - * {@link #getAttributes(java.lang.String)} or {@link #getEntries()} - * to get already available contents. However, in order not to return - * partial result, when the main attributes in the new manifest is not - * consumed completely, {@link #getMainAttributes()} throws an - * {@code IllegalStateException}. When a certain named entry is not - * consumed completely, {@link #getAttributes(java.lang.String)} - * returns the old {@code Attributes} for the name (if it exists). - * - * @param data null for last call, otherwise, feeding chunks - * @param offset offset into data to begin read - * @param length length of data after offset to read - * @exception IOException if an I/O error has occurred - * @exception IllegalStateException if {@code update(null)} is called - * without any previous {@code update(non-null)} call - */ - public void update(byte[] data, int offset, int length) throws IOException { - - // The last call - if (data == null) { - if (state == 0) { - throw new IllegalStateException("No data to update"); - } - // We accept manifest not ended with \n or \n\n - if (hasLastByte()) { - consumeCurrent(); - } - // We accept empty lines at the end - if (!currentAttr.isEmpty()) { - consumeAttr(); - } - state = 0; // back to non-update state - current = null; - currentAttr = null; - return; - } - - // The first call - if (state == 0) { - current = new byte[1024]; - currentAttr = super.getMainAttributes(); // the main attribute - state = 1; - } - - int end = offset + length; - - while (offset < end) { - switch (data[offset]) { - case '\r': - break; // always skip - case '\n': - if (hasLastByte() && lastByte() == '\n') { // new section - consumeCurrent(); - consumeAttr(); - if (state == 1) { - state = 2; - } - currentAttr = new Attributes(2); - } else { - if (hasLastByte()) { - // save \n into current but do not parse, - // there might be a continuation later - ensureCapacity(); - current[currentPos++] = data[offset]; - } else if (state == 1) { - // there can be multiple empty lines between - // sections, but cannot be at the beginning - throw new IOException("invalid manifest format"); - } - } - break; - case ' ': - if (!hasLastByte()) { - throw new IOException("invalid manifest format"); - } else if (lastByte() == '\n') { - currentPos--; // continuation, remove last \n - } else { // a very normal ' ' - ensureCapacity(); - current[currentPos++] = data[offset]; - } - break; - default: - if (hasLastByte() && lastByte() == '\n') { - // The start of a new pair, not continuation - consumeCurrent(); // the last line read - } - ensureCapacity(); - current[currentPos++] = data[offset]; - break; - } - offset++; - } - } - - /** - * Returns the main Attributes for the Manifest. - * @exception IllegalStateException the main attributes is being read - * @return the main Attributes for the Manifest - */ - public Attributes getMainAttributes() { - if (state == 1) { - throw new IllegalStateException(); - } - return super.getMainAttributes(); - } - - /** - * Reads the Manifest from the specified InputStream. The entry - * names and attributes read will be merged in with the current - * manifest entries. - * - * @param is the input stream - * @exception IOException if an I/O error has occurred - * @exception IllegalStateException if called between two {@link #update} - * calls - */ - public void read(InputStream is) throws IOException { - if (state != 0) { - throw new IllegalStateException("Cannot call read between updates"); - } - super.read(is); - } - - /* - * ---------- Helper methods ----------------- - */ - - private void ensureCapacity() { - if (currentPos >= current.length-1) { - current = Arrays.copyOf(current, current.length*2); - } - } - - private boolean hasLastByte() { - return currentPos > 0; - } - - private byte lastByte() { - return current[currentPos-1]; - } - - // Parse current as key:value and save into currentAttr. - // There MUST be something inside current. - private void consumeCurrent() throws IOException { - // current normally has a \n end, except for the last line - if (current[currentPos-1] == '\n') currentPos--; - for (int i=0; i createdDigests; @@ -86,7 +83,6 @@ public class SignatureFileVerifier { * @param rawBytes the raw bytes of the signature block file */ public SignatureFileVerifier(ArrayList signerCache, - Manifest man, ManifestDigester md, String name, byte rawBytes[]) @@ -98,18 +94,13 @@ public class SignatureFileVerifier { try { obj = Providers.startJarVerification(); block = new PKCS7(rawBytes); - byte[] contentData = block.getContentInfo().getData(); - if (contentData != null) { - sfStream = new ByteArrayInputStream(contentData); - } + sfBytes = block.getContentInfo().getData(); certificateFactory = CertificateFactory.getInstance("X509"); } finally { Providers.stopJarVerification(obj); } this.name = name.substring(0, name.lastIndexOf(".")) .toUpperCase(Locale.ENGLISH); - - this.man = man; this.md = md; this.signerCache = signerCache; } @@ -117,13 +108,31 @@ public class SignatureFileVerifier { /** * returns true if we need the .SF file */ - public boolean needSignatureFile() + public boolean needSignatureFileBytes() { - return sfStream == null; + + return sfBytes == null; } - public void setSignatureFile(InputStream ins) { - this.sfStream = ins; + + /** + * returns true if we need this .SF file. + * + * @param name the name of the .SF file without the extension + * + */ + public boolean needSignatureFile(String name) + { + return this.name.equalsIgnoreCase(name); + } + + /** + * used to set the raw bytes of the .SF file when it + * is external to the signature block file. + */ + public void setSignatureFile(byte sfBytes[]) + { + this.sfBytes = sfBytes; } /** @@ -136,18 +145,12 @@ public class SignatureFileVerifier { * Signature File or PKCS7 block file name */ public static boolean isBlockOrSF(String s) { - return s.endsWith(".SF") || isBlock(s); - } - - /** - * Utility method used by JarVerifier to determine PKCS7 block - * files names that are supported - * - * @param s file name - * @return true if the input file name is a PKCS7 block file name - */ - public static boolean isBlock(String s) { - return s.endsWith(".DSA") || s.endsWith(".RSA") || s.endsWith(".EC"); + // we currently only support DSA and RSA PKCS7 blocks + if (s.endsWith(".SF") || s.endsWith(".DSA") || + s.endsWith(".RSA") || s.endsWith(".EC")) { + return true; + } + return false; } /** get digest from cache */ @@ -177,7 +180,7 @@ public class SignatureFileVerifier { * * */ - public void process(Map signers, + public void process(Hashtable signers, List manifestDigests) throws IOException, SignatureException, NoSuchAlgorithmException, JarException, CertificateException @@ -194,86 +197,31 @@ public class SignatureFileVerifier { } - private void processImpl(Map signers, + private void processImpl(Hashtable signers, List manifestDigests) throws IOException, SignatureException, NoSuchAlgorithmException, JarException, CertificateException { - SignatureFileManifest sf = new SignatureFileManifest(); - InputStream ins = sfStream; + Manifest sf = new Manifest(); + sf.read(new ByteArrayInputStream(sfBytes)); - byte[] buffer = new byte[4096]; - int sLen = block.getSignerInfos().length; - boolean mainOK = false; // main attributes of SF is available... - boolean manifestSigned = false; // and it matches MANIFEST.MF - BASE64Decoder decoder = new BASE64Decoder(); + String version = + sf.getMainAttributes().getValue(Attributes.Name.SIGNATURE_VERSION); - PKCS7.PKCS7Verifier[] pvs = new PKCS7.PKCS7Verifier[sLen]; - for (int i=0; i intResult = new ArrayList<>(sLen); - for (int i = 0; i < sLen; i++) { - if (pvs[i] != null) { - SignerInfo signerInfo = pvs[i].verify(); - if (signerInfo != null) { - intResult.add(signerInfo); - } - } - } - if (intResult.isEmpty()) { + if (infos == null) { throw new SecurityException("cannot verify signature block file " + name); } - SignerInfo[] infos = - intResult.toArray(new SignerInfo[intResult.size()]); + BASE64Decoder decoder = new BASE64Decoder(); CodeSigner[] newSigners = getSigners(infos, block); @@ -281,37 +229,26 @@ public class SignatureFileVerifier { if (newSigners == null) return; + Iterator> entries = + sf.getEntries().entrySet().iterator(); + + // see if we can verify the whole manifest first + boolean manifestSigned = verifyManifestHash(sf, md, decoder, manifestDigests); + // verify manifest main attributes if (!manifestSigned && !verifyManifestMainAttrs(sf, md, decoder)) { throw new SecurityException ("Invalid signature file digest for Manifest main attributes"); } - Iterator> entries; - - if (manifestSigned) { - if (debug != null) { - debug.println("full manifest signature match, " - + "update signer info from MANIFEST.MF"); - } - entries = man.getEntries().entrySet().iterator(); - } else { - if (debug != null) { - debug.println("full manifest signature unmatch, " - + "update signer info from SF file"); - } - entries = sf.getEntries().entrySet().iterator(); - } - - // go through each section - + // go through each section in the signature file while(entries.hasNext()) { Map.Entry e = entries.next(); String name = e.getKey(); if (manifestSigned || - (verifySection(e.getValue(), name, md, decoder))) { + (verifySection(e.getValue(), name, md, decoder))) { if (name.startsWith("./")) name = name.substring(2); @@ -656,6 +593,7 @@ public class SignatureFileVerifier { if (set == subset) return true; + boolean match; for (int i = 0; i < subset.length; i++) { if (!contains(set, subset[i])) return false; @@ -675,6 +613,8 @@ public class SignatureFileVerifier { if ((oldSigners == null) && (signers == newSigners)) return true; + boolean match; + // make sure all oldSigners are in signers if ((oldSigners != null) && !isSubSet(oldSigners, signers)) return false; @@ -698,7 +638,7 @@ public class SignatureFileVerifier { } void updateSigners(CodeSigner[] newSigners, - Map signers, String name) { + Hashtable signers, String name) { CodeSigner[] oldSigners = signers.get(name); diff --git a/jdk/test/java/util/jar/JarInputStream/ScanSignedJar.java b/jdk/test/java/util/jar/JarInputStream/ScanSignedJar.java index 425e5659715..86dbf793e74 100644 --- a/jdk/test/java/util/jar/JarInputStream/ScanSignedJar.java +++ b/jdk/test/java/util/jar/JarInputStream/ScanSignedJar.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2011, 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 @@ -27,11 +27,9 @@ * @summary Confirm that JarEntry.getCertificates identifies signed entries. */ -import java.io.*; import java.net.URL; import java.security.CodeSigner; import java.security.cert.Certificate; -import java.util.Enumeration; import java.util.jar.*; /* @@ -72,6 +70,9 @@ public class ScanSignedJar { if (signers == null && certificates == null) { System.out.println("[unsigned]\t" + name + "\t(" + size + " bytes)"); + if (name.equals("Count.class")) { + throw new Exception("Count.class should be signed"); + } } else if (signers != null && certificates != null) { System.out.println("[" + signers.length + (signers.length == 1 ? " signer" : " signers") + "]\t" + diff --git a/jdk/test/java/util/jar/JarInputStream/TestIndexedJarWithBadSignature.java b/jdk/test/java/util/jar/JarInputStream/TestIndexedJarWithBadSignature.java index 977c10121da..2e74eb10069 100644 --- a/jdk/test/java/util/jar/JarInputStream/TestIndexedJarWithBadSignature.java +++ b/jdk/test/java/util/jar/JarInputStream/TestIndexedJarWithBadSignature.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2011, 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 @@ -37,7 +37,7 @@ public class TestIndexedJarWithBadSignature { public static void main(String...args) throws Throwable { try (JarInputStream jis = new JarInputStream( - new FileInputStream(System.getProperty("tst.src", ".") + + new FileInputStream(System.getProperty("test.src", ".") + System.getProperty("file.separator") + "BadSignedJar.jar"))) { From 1003e3e74421ba6cd6ae291a4784341316c8fa9e Mon Sep 17 00:00:00 2001 From: Jim Graham Date: Mon, 2 May 2011 14:38:22 -0700 Subject: [PATCH 70/80] 6563734: Path2D.Float and Path2D.Double should have final getPathIterator methods Reviewed-by: prr --- jdk/src/share/classes/java/awt/geom/Path2D.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jdk/src/share/classes/java/awt/geom/Path2D.java b/jdk/src/share/classes/java/awt/geom/Path2D.java index c84948c8ee9..39f7d992b28 100644 --- a/jdk/src/share/classes/java/awt/geom/Path2D.java +++ b/jdk/src/share/classes/java/awt/geom/Path2D.java @@ -732,7 +732,7 @@ public abstract class Path2D implements Shape, Cloneable { * * @since 1.6 */ - public PathIterator getPathIterator(AffineTransform at) { + public final PathIterator getPathIterator(AffineTransform at) { if (at == null) { return new CopyIterator(this); } else { @@ -1461,7 +1461,7 @@ public abstract class Path2D implements Shape, Cloneable { * of this {@code Shape}'s outline * @since 1.6 */ - public PathIterator getPathIterator(AffineTransform at) { + public final PathIterator getPathIterator(AffineTransform at) { if (at == null) { return new CopyIterator(this); } else { @@ -2342,8 +2342,8 @@ public abstract class Path2D implements Shape, Cloneable { * * @since 1.6 */ - public PathIterator getPathIterator(AffineTransform at, - double flatness) + public final PathIterator getPathIterator(AffineTransform at, + double flatness) { return new FlatteningPathIterator(getPathIterator(at), flatness); } From 2b767e1070b9a77798dd9152afba9f0243a0640e Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Tue, 3 May 2011 15:19:04 +0400 Subject: [PATCH 71/80] 7016528: Deadlock during mutual initialization of DataTransferer and DataTransferer$DataFlavorComparator Reviewed-by: dav, art, denis --- .../sun/awt/datatransfer/DataTransferer.java | 47 ++++++++++--------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java b/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java index e8fe5859b2d..82ff8899349 100644 --- a/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java +++ b/jdk/src/share/classes/sun/awt/datatransfer/DataTransferer.java @@ -29,12 +29,10 @@ import java.awt.AWTError; import java.awt.EventQueue; import java.awt.Image; import java.awt.Graphics; -import java.awt.Toolkit; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.FlavorMap; import java.awt.datatransfer.FlavorTable; -import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; @@ -66,8 +64,6 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.security.AccessControlContext; -import java.security.AccessControlException; import java.security.AccessController; import java.security.PrivilegedAction; import java.security.PrivilegedActionException; @@ -171,7 +167,26 @@ public abstract class DataTransferer { */ public static final DataFlavor javaTextEncodingFlavor; - private static SortedSet standardEncodings; + /** + * Lazy initialization of Standard Encodings. + */ + private static class StandardEncodingsHolder { + private static final SortedSet standardEncodings = load(); + + private static SortedSet load() { + final Comparator comparator = + new CharsetComparator(IndexedComparator.SELECT_WORST); + final SortedSet tempSet = new TreeSet(comparator); + tempSet.add("US-ASCII"); + tempSet.add("ISO-8859-1"); + tempSet.add("UTF-8"); + tempSet.add("UTF-16BE"); + tempSet.add("UTF-16LE"); + tempSet.add("UTF-16"); + tempSet.add(getDefaultTextCharset()); + return Collections.unmodifiableSortedSet(tempSet); + } + } /** * Tracks whether a particular text/* MIME type supports the charset @@ -509,18 +524,7 @@ public abstract class DataTransferer { * non-standard, character sets are not included. */ public static Iterator standardEncodings() { - if (standardEncodings == null) { - TreeSet tempSet = new TreeSet(defaultCharsetComparator); - tempSet.add("US-ASCII"); - tempSet.add("ISO-8859-1"); - tempSet.add("UTF-8"); - tempSet.add("UTF-16BE"); - tempSet.add("UTF-16LE"); - tempSet.add("UTF-16"); - tempSet.add(getDefaultTextCharset()); - standardEncodings = Collections.unmodifiableSortedSet(tempSet); - } - return standardEncodings.iterator(); + return StandardEncodingsHolder.standardEncodings.iterator(); } /** @@ -2398,7 +2402,9 @@ search: public static DataFlavor[] setToSortedDataFlavorArray(Set flavorsSet) { DataFlavor[] flavors = new DataFlavor[flavorsSet.size()]; flavorsSet.toArray(flavors); - Arrays.sort(flavors, defaultFlavorComparator); + final Comparator comparator = + new DataFlavorComparator(IndexedComparator.SELECT_WORST); + Arrays.sort(flavors, comparator); return flavors; } @@ -2455,11 +2461,6 @@ search: return new ArrayList(); } - private static CharsetComparator defaultCharsetComparator = - new CharsetComparator(IndexedComparator.SELECT_WORST); - private static DataFlavorComparator defaultFlavorComparator = - new DataFlavorComparator(IndexedComparator.SELECT_WORST); - /** * A Comparator which includes a helper function for comparing two Objects * which are likely to be keys in the specified Map. From 3ad5f6532c42ea871c8aa429ed4acb763086f29c Mon Sep 17 00:00:00 2001 From: Erik Trimble Date: Tue, 3 May 2011 16:00:35 -0700 Subject: [PATCH 72/80] Added tag hs21-b10 for changeset 33e592b5ff17 --- hotspot/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/.hgtags b/hotspot/.hgtags index 5478ecfeaf9..ef89d2b9fec 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -167,3 +167,4 @@ bd586e392d93b7ed7a1636dcc8da2b6a4203a102 hs21-b06 611e19a16519d6fb5deea9ab565336e6e6ee475d jdk7-b139 611e19a16519d6fb5deea9ab565336e6e6ee475d hs21-b09 d283b82966712b353fa307845a1316da42a355f4 jdk7-b140 +d283b82966712b353fa307845a1316da42a355f4 hs21-b10 From 679f58d07c188dd6c784ac36dd65f567a69938d7 Mon Sep 17 00:00:00 2001 From: David Holmes Date: Wed, 4 May 2011 22:16:28 -0400 Subject: [PATCH 73/80] 7041284: arm/ppc Missing launcher mapfiles prevent build Disable use of launcher mapfiles when cross-compiling Reviewed-by: ohair, ksrini --- jdk/make/common/Program.gmk | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/jdk/make/common/Program.gmk b/jdk/make/common/Program.gmk index 9fdde6d9745..38adb13b052 100644 --- a/jdk/make/common/Program.gmk +++ b/jdk/make/common/Program.gmk @@ -55,10 +55,13 @@ program_default_rule: all program: $(ACTUAL_PROGRAM) -# reuse the mapfiles in the launcher's directory, the same should -# be applicable to the tool launchers as well. -FILES_m = $(BUILDDIR)/java/main/java/mapfile-$(ARCH) -include $(BUILDDIR)/common/Mapfile-vers.gmk +# Work-around for missing processor specific mapfiles +ifndef CROSS_COMPILE_ARCH + # reuse the mapfiles in the launcher's directory, the same should + # be applicable to the tool launchers as well. + FILES_m = $(BUILDDIR)/java/main/java/mapfile-$(ARCH) + include $(BUILDDIR)/common/Mapfile-vers.gmk +endif include $(JDK_TOPDIR)/make/common/Rules.gmk From b56aedf465132d12971e0ab92e43e0138977cb1c Mon Sep 17 00:00:00 2001 From: Suchen Chien Date: Thu, 5 May 2011 14:02:17 -0700 Subject: [PATCH 74/80] Added tag jdk7-b141 for changeset 3d44ee873b9c --- jdk/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/jdk/.hgtags b/jdk/.hgtags index 68e25fecbb6..8a7ff58323d 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -115,3 +115,4 @@ aa13e7702cd9d8aca9aa38f1227f966990866944 jdk7-b136 60d3d55dcc9c31a30ced9caa6ef5c0dcd7db031d jdk7-b138 d80954a89b49fda47c0c5cace65a17f5a758b8bd jdk7-b139 9315c733fb17ddfb9fb44be7e0ffea37bf3c727d jdk7-b140 +63eeefe118da18c75ba3d36266768cd1ccaaca6b jdk7-b141 From e15276198f25922790b40e37d0e864bf613ba400 Mon Sep 17 00:00:00 2001 From: "J. Duke" Date: Wed, 5 Jul 2017 17:42:20 +0200 Subject: [PATCH 75/80] Added tag jdk7-b140 for changeset f4298bc3f4b6 --- .hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgtags b/.hgtags index 36c9e8850d1..9bca5c9a122 100644 --- a/.hgtags +++ b/.hgtags @@ -114,3 +114,4 @@ f75a1efb141210901aabe00a834e0fc32bb8b337 jdk7-b135 d1cf7d4ee16c341f5b8c7e7f1d68a8c412b6c693 jdk7-b137 62b8e328f8c8c66c14b0713222116f2add473f3f jdk7-b138 955488f34ca418f6cdab843d61c20d2c615637d9 jdk7-b139 +f4298bc3f4b6baa315643be06966f09684290068 jdk7-b140 From 6e40ce24d5ca3c9e6b6a371a997e74ba83c5b30e Mon Sep 17 00:00:00 2001 From: Andrew John Hughes Date: Fri, 6 May 2011 01:55:29 +0100 Subject: [PATCH 76/80] 7042040: Remove disk space sanity check Remove outdated disk space checks using df Reviewed-by: ohair, omajid --- jdk/make/common/shared/Defs-versions.gmk | 11 ----------- jdk/make/common/shared/Sanity-Settings.gmk | 2 -- jdk/make/common/shared/Sanity.gmk | 18 ------------------ 3 files changed, 31 deletions(-) diff --git a/jdk/make/common/shared/Defs-versions.gmk b/jdk/make/common/shared/Defs-versions.gmk index 05d81efec08..6e00b22f00f 100644 --- a/jdk/make/common/shared/Defs-versions.gmk +++ b/jdk/make/common/shared/Defs-versions.gmk @@ -72,10 +72,6 @@ endif # REQUIRED_DXSDK_VER # Windows only: The version of DirectX SDK expected. # -# REQUIRED_FREE_SPACE -# The minimum disk space needed as determined by running 'du -sk' on a fully -# built workspace. -# # REQUIRED_FREETYPE_VERSION # If we are using freetype, the freetype version expected. # @@ -131,11 +127,6 @@ ifeq ($(PLATFORM), solaris) REQUIRED_OS_VERSION = 5.10 REQUIRED_OS_VARIANT_NAME = Solaris REQUIRED_OS_VARIANT_VERSION = $(REQUIRED_OS_VERSION) - ifeq ($(ARCH_FAMILY), sparc) - REQUIRED_FREE_SPACE = 1300000 - else - REQUIRED_FREE_SPACE = 1040000 - endif REQUIRED_COMPILER_NAME = Sun Studio 12 Update 1 REQUIRED_COMPILER_VERSION = SS12u1 # Cross-compilation compiler versions are target specific @@ -157,7 +148,6 @@ ifeq ($(PLATFORM), linux) REQUIRED_OS_VERSION = 2.6 REQUIRED_OS_VARIANT_NAME = Fedora REQUIRED_OS_VARIANT_VERSION = 9 - REQUIRED_FREE_SPACE = 1460000 REQUIRED_ALSA_VERSION = 0.9.1 REQUIRED_COMPILER_NAME = GCC4 REQUIRED_COMPILER_VERSION = GCC4 @@ -187,7 +177,6 @@ ifeq ($(PLATFORM), windows) REQUIRED_OS_VARIANT_VERSION = $(REQUIRED_OS_VERSION) REQUIRED_CYGWIN_VER = 4.0 REQUIRED_MKS_VER = 6.1 - REQUIRED_FREE_SPACE = 500000 REQUIRED_DXSDK_VER = 0x0900 ifeq ($(CC_VERSION),msvc) REQUIRED_COMPILER_NAME = Visual Studio 10 diff --git a/jdk/make/common/shared/Sanity-Settings.gmk b/jdk/make/common/shared/Sanity-Settings.gmk index 36179fed5fd..ecc39c1a724 100644 --- a/jdk/make/common/shared/Sanity-Settings.gmk +++ b/jdk/make/common/shared/Sanity-Settings.gmk @@ -192,8 +192,6 @@ endif ALL_SETTINGS+=$(call addRequiredVersionSetting,OS_VERSION) ALL_SETTINGS+=$(call addOptionalSetting,OS_VARIANT_NAME) ALL_SETTINGS+=$(call addOptionalSetting,OS_VARIANT_VERSION) -ALL_SETTINGS+=$(call addRequiredSetting,TEMP_FREE_SPACE) -ALL_SETTINGS+=$(call addRequiredSetting,FREE_SPACE) ALL_SETTINGS+=$(call addRequiredSetting,MB_OF_MEMORY) diff --git a/jdk/make/common/shared/Sanity.gmk b/jdk/make/common/shared/Sanity.gmk index 99f64fd3842..1dbedb17a75 100644 --- a/jdk/make/common/shared/Sanity.gmk +++ b/jdk/make/common/shared/Sanity.gmk @@ -69,8 +69,6 @@ endef # Settings and rules to validate the JDK build environment. ifeq ($(PLATFORM), solaris) - FREE_SPACE := $(shell $(DF) -b $(OUTPUTDIR) | $(TAIL) -1 | $(NAWK) '{print $$2;}') - TEMP_FREE_SPACE := $(shell $(DF) -b $(TEMP_DISK) | $(TAIL) -1 | $(NAWK) '{print $$2;}') # What kind of system we are using (Variations are Solaris and OpenSolaris) OS_VERSION := $(shell uname -r) OS_VARIANT_NAME := $(strip $(shell head -1 /etc/release | awk '{print $$1;}') ) @@ -88,8 +86,6 @@ ifeq ($(PLATFORM), solaris) endif ifeq ($(PLATFORM), linux) - FREE_SPACE := $(shell $(DF) --sync -kP $(OUTPUTDIR) | $(TAIL) -1 | $(NAWK) '{print $$4;}') - TEMP_FREE_SPACE := $(shell $(DF) --sync -kP $(TEMP_DISK) | $(TAIL) -1 | $(NAWK) '{print $$4;}') # What kind of system we are using (Variation is the Linux vendor) OS_VERSION := $(shell uname -r) OS_VARIANT_NAME := $(shell \ @@ -118,8 +114,6 @@ ifeq ($(PLATFORM), linux) endif ifeq ($(PLATFORM), windows) - FREE_SPACE := $(shell $(DF) -kP $(OUTPUTDIR) | $(TAIL) -1 | $(NAWK) '{print $$4;}') - TEMP_FREE_SPACE := $(shell $(DF) -kP $(TEMP_DISK) | $(TAIL) -1 | $(NAWK) '{print $$4;}') # Windows 2000 is 5.0, Windows XP is 5.1, Windows 2003 is 5.2 # Assume 5.0 (Windows 2000) if systeminfo does not help WINDOWS_MAPPING-5.0 := Windows2000 @@ -715,18 +709,6 @@ sane-outputdir: " Either obtain these permissions or set ALT_OUTPUTDIR. \n" \ "" >> $(ERROR_FILE) ; \ fi - @# - @# OUTPUTDIR must have enough free space... - @# - @if [ $(FREE_SPACE) -lt $(REQUIRED_FREE_SPACE) ]; then \ - $(ECHO) "WARNING: You may not have enough free space in your OUTPUTDIR. The \n" \ - " current value of OUTPUTDIR is \n" \ - " $(OUTPUTDIR) \n" \ - " You need "$(REQUIRED_FREE_SPACE)" Kbytes free on this device to build \n" \ - " and it appears that only "$(FREE_SPACE)" Kbytes are free. \n" \ - " Either obtain more space or set ALT_OUTPUTDIR to a larger disk. \n" \ - "" >> $(WARNING_FILE) ; \ - fi ###################################################### # if specified, ALT_BOOTDIR must point to non-relative path if set From e20a4c4a39c51aeb64faff5959053bde58976777 Mon Sep 17 00:00:00 2001 From: Christine Lu Date: Thu, 5 May 2011 18:05:24 -0700 Subject: [PATCH 77/80] 7026163: gzip tar files Reviewed-by: katleman --- jdk/make/common/shared/Defs-utils.gmk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/jdk/make/common/shared/Defs-utils.gmk b/jdk/make/common/shared/Defs-utils.gmk index a5b1802c46b..1cebe93ca5b 100644 --- a/jdk/make/common/shared/Defs-utils.gmk +++ b/jdk/make/common/shared/Defs-utils.gmk @@ -109,6 +109,8 @@ FMT = $(UTILS_COMMAND_PATH)fmt GDB = $(UTILS_USR_BIN_PATH)gdb GREP = $(UTILS_COMMAND_PATH)grep GUNZIP = $(UTILS_COMMAND_PATH)gunzip +# GZIP is used for solaris. Linux and windows use tar czf +GZIP = $(UTILS_COMMAND_PATH)gzip HEAD = $(UTILS_USR_BIN_PATH)head HG = hg ID = $(UTILS_COMMAND_PATH)id From d814ae14d1081df314eb5da12774659721603a84 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Fri, 6 May 2011 17:06:25 -0700 Subject: [PATCH 78/80] 7011326: Add informative example to @SafeVarargs type or language discussion Reviewed-by: mcimadamore, mduigou --- .../share/classes/java/lang/SafeVarargs.java | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/jdk/src/share/classes/java/lang/SafeVarargs.java b/jdk/src/share/classes/java/lang/SafeVarargs.java index b0c03a9162b..818ea21bafb 100644 --- a/jdk/src/share/classes/java/lang/SafeVarargs.java +++ b/jdk/src/share/classes/java/lang/SafeVarargs.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2011, 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 @@ -32,7 +32,7 @@ import java.lang.annotation.*; * constructor does not perform potentially unsafe operations on its * varargs parameter. Applying this annotation to a method or * constructor suppresses unchecked warnings about a - * non-reifiable variable-arity (vararg) type and suppresses + * non-reifiable variable arity (vararg) type and suppresses * unchecked warnings about parameterized array creation at call * sites. * @@ -41,11 +41,10 @@ import java.lang.annotation.*; * additional usage restrictions on this annotation type; it is a * compile-time error if a method or constructor declaration is * annotated with a {@code @SafeVarargs} annotation, and either: - *

    - *
  • the declaration is a fixed-arity method or constructor + *
  • the declaration is a fixed arity method or constructor * - *
  • the declaration is a variable-arity method that is neither + *
  • the declaration is a variable arity method that is neither * {@code static} nor {@code final}. * *
@@ -55,15 +54,28 @@ import java.lang.annotation.*; * *
    * - *
  • The variable-arity parameter has a reifiable element type, + *
  • The variable arity parameter has a reifiable element type, * which includes primitive types, {@code Object}, and {@code String}. * (The unchecked warnings this annotation type suppresses already do * not occur for a reifiable element type.) * *
  • The body of the method or constructor declaration performs * potentially unsafe operations, such as an assignment to an element - * of the variable-arity parameter's array that generates an unchecked - * warning. + * of the variable arity parameter's array that generates an unchecked + * warning. Some unsafe operations do not trigger an unchecked + * warning. For example, the aliasing in + * + *
    + * @SafeVarargs // Not actually safe!
    + * static void m(List<String>... stringLists) {
    + *   Object[] array = stringLists;
    + *   List<Integer> tmpList = Arrays.asList(42);
    + *   array[0] = tmpList; // Semantically invalid, but compiles without warnings
    + *   String s = stringLists[0].get(0); // Oh no, ClassCastException at runtime!
    + * }
    + * 
    + * + * leads to a {@code ClassCastException} at runtime. * *

    Future versions of the platform may mandate compiler errors for * such unsafe operations. From 691c55d04af0e212a95a2cab9f72a008b0770d3b Mon Sep 17 00:00:00 2001 From: Vinnie Ryan Date: Mon, 9 May 2011 15:58:25 +0100 Subject: [PATCH 79/80] 6987652: VM crashed in sun.security.mscapi.RSAKeyPairGenerator.generateRSAKeyPair(...) Reviewed-by: alanb --- jdk/src/windows/native/sun/security/mscapi/security.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jdk/src/windows/native/sun/security/mscapi/security.cpp b/jdk/src/windows/native/sun/security/mscapi/security.cpp index 1a489d70eca..49cbe81e418 100644 --- a/jdk/src/windows/native/sun/security/mscapi/security.cpp +++ b/jdk/src/windows/native/sun/security/mscapi/security.cpp @@ -705,7 +705,7 @@ JNIEXPORT jobject JNICALL Java_sun_security_mscapi_RSAKeyPairGenerator_generateR HCRYPTPROV hCryptProv = NULL; HCRYPTKEY hKeyPair; DWORD dwFlags = (keySize << 16) | CRYPT_EXPORTABLE; - jobject keypair; + jobject keypair = NULL; const char* pszKeyContainerName = NULL; // UUID __try From 25ec11dfe6637bb3a0b77029694191e6127c2c29 Mon Sep 17 00:00:00 2001 From: Doug Lea Date: Mon, 9 May 2011 16:36:20 +0100 Subject: [PATCH 80/80] 7042673: LockSupport.getBlocker(null) crashes Reviewed-by: chegar --- .../share/classes/java/util/concurrent/locks/LockSupport.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/jdk/src/share/classes/java/util/concurrent/locks/LockSupport.java b/jdk/src/share/classes/java/util/concurrent/locks/LockSupport.java index f0cd3bc0456..7b829f63a06 100644 --- a/jdk/src/share/classes/java/util/concurrent/locks/LockSupport.java +++ b/jdk/src/share/classes/java/util/concurrent/locks/LockSupport.java @@ -275,10 +275,14 @@ public class LockSupport { * snapshot -- the thread may have since unblocked or blocked on a * different blocker object. * + * @param t the thread * @return the blocker + * @throws NullPointerException if argument is null * @since 1.6 */ public static Object getBlocker(Thread t) { + if (t == null) + throw new NullPointerException(); return unsafe.getObjectVolatile(t, parkBlockerOffset); }