src/share/vm/prims/jvm.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File 8042235_8u40 Cdiff src/share/vm/prims/jvm.cpp

src/share/vm/prims/jvm.cpp

Print this page
rev 6917 : 8042235: redefining method used by multiple MethodHandles crashes VM
Summary: note all MemberNames created on internal list for adjusting method entries.
Reviewed-by: sspitsyn, dcubed, lfoltan

*** 601,645 **** THROW_MSG_0(vmSymbols::java_lang_CloneNotSupportedException(), klass->external_name()); } // Make shallow object copy const int size = obj->size(); ! oop new_obj = NULL; if (obj->is_array()) { const int length = ((arrayOop)obj())->length(); ! new_obj = CollectedHeap::array_allocate(klass, size, length, CHECK_NULL); } else { ! new_obj = CollectedHeap::obj_allocate(klass, size, CHECK_NULL); } // 4839641 (4840070): We must do an oop-atomic copy, because if another thread // is modifying a reference field in the clonee, a non-oop-atomic copy might // be suspended in the middle of copying the pointer and end up with parts // of two different pointers in the field. Subsequent dereferences will crash. // 4846409: an oop-copy of objects with long or double fields or arrays of same // won't copy the longs/doubles atomically in 32-bit vm's, so we copy jlongs instead // of oops. We know objects are aligned on a minimum of an jlong boundary. // The same is true of StubRoutines::object_copy and the various oop_copy // variants, and of the code generated by the inline_native_clone intrinsic. assert(MinObjAlignmentInBytes >= BytesPerLong, "objects misaligned"); ! Copy::conjoint_jlongs_atomic((jlong*)obj(), (jlong*)new_obj, (size_t)align_object_size(size) / HeapWordsPerLong); // Clear the header ! new_obj->init_mark(); // Store check (mark entire object and let gc sort it out) BarrierSet* bs = Universe::heap()->barrier_set(); assert(bs->has_write_region_opt(), "Barrier set does not have write_region"); ! bs->write_region(MemRegion((HeapWord*)new_obj, size)); // Caution: this involves a java upcall, so the clone should be // "gc-robust" by this stage. if (klass->has_finalizer()) { assert(obj->is_instance(), "should be instanceOop"); ! new_obj = InstanceKlass::register_finalizer(instanceOop(new_obj), CHECK_NULL); } ! return JNIHandles::make_local(env, oop(new_obj)); JVM_END // java.lang.Compiler //////////////////////////////////////////////////// // The initial cuts of the HotSpot VM will not support JITs, and all existing --- 601,663 ---- THROW_MSG_0(vmSymbols::java_lang_CloneNotSupportedException(), klass->external_name()); } // Make shallow object copy const int size = obj->size(); ! oop new_obj_oop = NULL; if (obj->is_array()) { const int length = ((arrayOop)obj())->length(); ! new_obj_oop = CollectedHeap::array_allocate(klass, size, length, CHECK_NULL); } else { ! new_obj_oop = CollectedHeap::obj_allocate(klass, size, CHECK_NULL); } + // 4839641 (4840070): We must do an oop-atomic copy, because if another thread // is modifying a reference field in the clonee, a non-oop-atomic copy might // be suspended in the middle of copying the pointer and end up with parts // of two different pointers in the field. Subsequent dereferences will crash. // 4846409: an oop-copy of objects with long or double fields or arrays of same // won't copy the longs/doubles atomically in 32-bit vm's, so we copy jlongs instead // of oops. We know objects are aligned on a minimum of an jlong boundary. // The same is true of StubRoutines::object_copy and the various oop_copy // variants, and of the code generated by the inline_native_clone intrinsic. assert(MinObjAlignmentInBytes >= BytesPerLong, "objects misaligned"); ! Copy::conjoint_jlongs_atomic((jlong*)obj(), (jlong*)new_obj_oop, (size_t)align_object_size(size) / HeapWordsPerLong); // Clear the header ! new_obj_oop->init_mark(); // Store check (mark entire object and let gc sort it out) BarrierSet* bs = Universe::heap()->barrier_set(); assert(bs->has_write_region_opt(), "Barrier set does not have write_region"); ! bs->write_region(MemRegion((HeapWord*)new_obj_oop, size)); ! ! Handle new_obj(THREAD, new_obj_oop); ! // Special handling for MemberNames. Since they contain Method* metadata, they ! // must be registered so that RedefineClasses can fix metadata contained in them. ! if (java_lang_invoke_MemberName::is_instance(new_obj()) && ! java_lang_invoke_MemberName::is_method(new_obj())) { ! Method* method = (Method*)java_lang_invoke_MemberName::vmtarget(new_obj()); ! // MemberName may be unresolved, so doesn't need registration until resolved. ! if (method != NULL) { ! methodHandle m(THREAD, method); ! // This can safepoint and redefine method, so need both new_obj and method ! // in a handle, for two different reasons. new_obj can move, method can be ! // deleted if nothing is using it on the stack. ! m->method_holder()->add_member_name(new_obj()); ! } ! } // Caution: this involves a java upcall, so the clone should be // "gc-robust" by this stage. if (klass->has_finalizer()) { assert(obj->is_instance(), "should be instanceOop"); ! new_obj_oop = InstanceKlass::register_finalizer(instanceOop(new_obj()), CHECK_NULL); ! new_obj = Handle(THREAD, new_obj_oop); } ! return JNIHandles::make_local(env, new_obj()); JVM_END // java.lang.Compiler //////////////////////////////////////////////////// // The initial cuts of the HotSpot VM will not support JITs, and all existing
src/share/vm/prims/jvm.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File