Ver código fonte

Fixing fields handling

tags/light-jdk7u79+3
Ivan Dubrov 8 anos atrás
pai
commit
220d2d53e0

+ 154
- 0
dcevm/src/test/java7/com/github/dcevm/test/fields/InstanceFieldHandleTest.java Ver arquivo

@@ -0,0 +1,154 @@
/*
* 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.
*
*/
package com.github.dcevm.test.fields;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;

import static com.github.dcevm.test.util.HotSwapTestHelper.__toVersion__;
import static org.junit.Assert.assertEquals;

/**
* Test for replacing field with MethodHandle pointing to it.
*
* Technically, should work for Java 7, but currently is not supported in Java 7.
*
* @author Ivan Dubrov
*/
public class InstanceFieldHandleTest {

// Version 0
public static class A {
public int fieldA;
public int fieldB;

public int getFieldA() {
return -1;
}
}

// Version 1 (fields swapped and new one is added)
public static class A___1 {
public int fieldB;
public int fieldA;
public String fieldC;

public int getFieldA() {
return fieldA;
}
}

// Version 2 (fields removed)
public static class A___2 {
}

// Version 3 (field type changed)
public static class A___3 {
public String fieldA;
public int fieldB;
}

@Before
@After
public void setUp() throws Exception {
__toVersion__(0);
}

@Test
public void testFieldChangeOrder() throws Throwable {
A a = new A();
MethodHandle getter = MethodHandles.publicLookup().findGetter(A.class, "fieldA", int.class);
MethodHandle setter = MethodHandles.publicLookup().findSetter(A.class, "fieldA", int.class);

a.fieldA = 3;
assertEquals(3, getter.invoke(a));

// Swap fields
__toVersion__(1);

assertEquals(3, getter.invoke(a));
setter.invoke(a, 53);
assertEquals(53, a.getFieldA());
assertEquals(53, getter.invoke(a));
}

@Test
public void testFieldRemoved() throws Throwable {
A a = new A();
MethodHandle getter = MethodHandles.publicLookup().findGetter(A.class, "fieldA", int.class);
MethodHandle setter = MethodHandles.publicLookup().findSetter(A.class, "fieldA", int.class);

a.fieldA = 3;
assertEquals(3, getter.invoke(a));

// Remove fieldA
__toVersion__(2);

try {
getter.invoke(a);
Assert.fail("Handle should have been cleared!");
} catch (NullPointerException e) {
// Handle was cleared!
}

try {
setter.invoke(a, 10);
Assert.fail("Handle should have been cleared!");
} catch (NullPointerException e) {
// Handle was cleared!
}
}

@Test
public void testFieldTypeChange() throws Throwable {
A a = new A();
MethodHandle getter = MethodHandles.publicLookup().findGetter(A.class, "fieldA", int.class);
MethodHandle setter = MethodHandles.publicLookup().findSetter(A.class, "fieldA", int.class);

a.fieldA = 3;
assertEquals(3, getter.invoke(a));

// Remove fieldA
__toVersion__(3);

try {
getter.invoke(a);
Assert.fail("Handle should have been cleared!");
} catch (NullPointerException e) {
// Handle was cleared!
}

try {
setter.invoke(a, 10);
Assert.fail("Handle should have been cleared!");
} catch (NullPointerException e) {
// Handle was cleared!
}
}
}

+ 154
- 0
dcevm/src/test/java7/com/github/dcevm/test/fields/StaticFieldHandleTest.java Ver arquivo

@@ -0,0 +1,154 @@
/*
* 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.
*
*/
package com.github.dcevm.test.fields;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;

import static com.github.dcevm.test.util.HotSwapTestHelper.__toVersion__;
import static org.junit.Assert.assertEquals;

/**
* Test for replacing field with MethodHandle pointing to it.
*
* Technically, should work for Java 7, but currently is not supported in Java 7.
*
* @author Ivan Dubrov
*/
public class StaticFieldHandleTest {

// Version 0
public static class A {
public static int fieldA;
public static int fieldB;

public static int getFieldA() {
return -1;
}
}

// Version 1 (fields swapped)
public static class A___1 {
public static int fieldB;
public static int fieldA;
public static String fieldC;

public static int getFieldA() {
return fieldA;
}
}

// Version 2 (fields removed)
public static class A___2 {
}

// Version 3 (field type changed)
public static class A___3 {
public static String fieldA;
public static int fieldB;
}

@Before
@After
public void setUp() throws Exception {
__toVersion__(0);
}

@Test
public void testStaticFieldChangeOrder() throws Throwable {
MethodHandle getter = MethodHandles.publicLookup().findStaticGetter(A.class, "fieldA", int.class);
MethodHandle setter = MethodHandles.publicLookup().findStaticSetter(A.class, "fieldA", int.class);

A.fieldA = 3;
A.fieldB = 5;
assertEquals(3, getter.invoke());

// Swap fields A and B
__toVersion__(1);

assertEquals(3, getter.invoke());
setter.invoke(12);
assertEquals(12, A.getFieldA());
assertEquals(12, getter.invoke());
}

@Test
public void testStaticFieldRemoved() throws Throwable {
MethodHandle getter = MethodHandles.publicLookup().findStaticGetter(A.class, "fieldA", int.class);
MethodHandle setter = MethodHandles.publicLookup().findStaticSetter(A.class, "fieldA", int.class);

A.fieldA = 3;
A.fieldB = 5;
assertEquals(3, getter.invoke());

// Remove fieldA
__toVersion__(2);

try {
getter.invoke();
Assert.fail("Handle should have been cleared!");
} catch (NullPointerException e) {
// Handle was cleared!
}

try {
setter.invoke(15);
Assert.fail("Handle should have been cleared!");
} catch (NullPointerException e) {
// Handle was cleared!
}
}

@Test
public void testStaticFieldTypeChange() throws Throwable {
MethodHandle getter = MethodHandles.publicLookup().findStaticGetter(A.class, "fieldA", int.class);
MethodHandle setter = MethodHandles.publicLookup().findStaticSetter(A.class, "fieldA", int.class);

A.fieldA = 3;
A.fieldB = 5;
assertEquals(3, getter.invoke());

// Remove fieldA
__toVersion__(3);

try {
getter.invoke();
Assert.fail("Handle should have been cleared!");
} catch (NullPointerException e) {
// Handle was cleared!
}

try {
setter.invoke(15);
Assert.fail("Handle should have been cleared!");
} catch (NullPointerException e) {
// Handle was cleared!
}
}
}

+ 105
- 96
hotspot/.hg/patches/light-jdk7u79-b15-method-handles.patch Ver arquivo

@@ -1,9 +1,9 @@
# HG changeset patch
# Parent 6858a68213bfb26e2a246f0014b921ecab5ac750

diff -r 6858a68213bf -r a416f1b672a4 src/share/vm/classfile/javaClasses.cpp
diff -r 6858a68213bf src/share/vm/classfile/javaClasses.cpp
--- a/src/share/vm/classfile/javaClasses.cpp Fri Jul 10 13:18:18 2015 -0700
+++ b/src/share/vm/classfile/javaClasses.cpp Fri Jul 10 13:59:26 2015 -0700
+++ b/src/share/vm/classfile/javaClasses.cpp Fri Jul 10 14:20:20 2015 -0700
@@ -2414,6 +2414,49 @@
}
}
@@ -63,9 +63,9 @@ diff -r 6858a68213bf -r a416f1b672a4 src/share/vm/classfile/javaClasses.cpp
java_lang_invoke_MemberName::compute_offsets();
java_lang_invoke_LambdaForm::compute_offsets();
java_lang_invoke_MethodType::compute_offsets();
diff -r 6858a68213bf -r a416f1b672a4 src/share/vm/classfile/javaClasses.hpp
diff -r 6858a68213bf src/share/vm/classfile/javaClasses.hpp
--- a/src/share/vm/classfile/javaClasses.hpp Fri Jul 10 13:18:18 2015 -0700
+++ b/src/share/vm/classfile/javaClasses.hpp Fri Jul 10 13:59:26 2015 -0700
+++ b/src/share/vm/classfile/javaClasses.hpp Fri Jul 10 14:20:20 2015 -0700
@@ -942,6 +942,55 @@
static int member_offset_in_bytes() { return _member_offset; }
};
@@ -122,9 +122,9 @@ diff -r 6858a68213bf -r a416f1b672a4 src/share/vm/classfile/javaClasses.hpp
// Interface to java.lang.invoke.LambdaForm objects
// (These are a private interface for managing adapter code generation.)
diff -r 6858a68213bf -r a416f1b672a4 src/share/vm/classfile/systemDictionary.hpp
diff -r 6858a68213bf src/share/vm/classfile/systemDictionary.hpp
--- a/src/share/vm/classfile/systemDictionary.hpp Fri Jul 10 13:18:18 2015 -0700
+++ b/src/share/vm/classfile/systemDictionary.hpp Fri Jul 10 13:59:26 2015 -0700
+++ b/src/share/vm/classfile/systemDictionary.hpp Fri Jul 10 14:20:20 2015 -0700
@@ -148,6 +148,8 @@
do_klass(reflect_UnsafeStaticFieldAccessorImpl_klass, sun_reflect_UnsafeStaticFieldAccessorImpl, Opt_Only_JDK15 ) \
\
@@ -134,9 +134,9 @@ diff -r 6858a68213bf -r a416f1b672a4 src/share/vm/classfile/systemDictionary.hpp
do_klass(MethodHandle_klass, java_lang_invoke_MethodHandle, Pre_JSR292 ) \
do_klass(MemberName_klass, java_lang_invoke_MemberName, Pre_JSR292 ) \
do_klass(MethodHandleNatives_klass, java_lang_invoke_MethodHandleNatives, Pre_JSR292 ) \
diff -r 6858a68213bf -r a416f1b672a4 src/share/vm/classfile/vmSymbols.hpp
diff -r 6858a68213bf src/share/vm/classfile/vmSymbols.hpp
--- a/src/share/vm/classfile/vmSymbols.hpp Fri Jul 10 13:18:18 2015 -0700
+++ b/src/share/vm/classfile/vmSymbols.hpp Fri Jul 10 13:59:26 2015 -0700
+++ b/src/share/vm/classfile/vmSymbols.hpp Fri Jul 10 14:20:20 2015 -0700
@@ -244,6 +244,8 @@
/* Support for JSR 292 & invokedynamic (JDK 1.7 and above) */ \
template(java_lang_invoke_CallSite, "java/lang/invoke/CallSite") \
@@ -157,99 +157,103 @@ diff -r 6858a68213bf -r a416f1b672a4 src/share/vm/classfile/vmSymbols.hpp
/* signature symbols needed by intrinsics */ \
VM_INTRINSICS_DO(VM_INTRINSIC_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, template, VM_ALIAS_IGNORE) \
\
diff -r 6858a68213bf -r a416f1b672a4 src/share/vm/prims/jvmtiRedefineClasses.cpp
diff -r 6858a68213bf src/share/vm/prims/jvmtiRedefineClasses.cpp
--- a/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Jul 10 13:18:18 2015 -0700
+++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Jul 10 13:59:26 2015 -0700
@@ -1400,6 +1400,120 @@
+++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Jul 10 14:20:20 2015 -0700
@@ -1398,8 +1398,124 @@
template <class T> static void oop_store(T* p, oop v) { oopDesc::encode_store_heap_oop_not_null(p, v); }
};
template <class S>
class ChangePointersOopClosure : public OopClosureNoHeader {
+ // import java_lang_invoke_MemberName.*
+ enum {
+ REFERENCE_KIND_SHIFT = java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT,
+ REFERENCE_KIND_MASK = java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK,
+ };
+
+ static oop field_name_or_null(Symbol* s) {
+ if (s == NULL) return NULL;
+ return StringTable::lookup(s);
+ }
+// import java_lang_invoke_MemberName.*
+enum {
+ REFERENCE_KIND_SHIFT = java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT,
+ REFERENCE_KIND_MASK = java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK,
+};
+
+ static oop object_java_mirror() {
+ return Klass::cast(SystemDictionary::Object_klass())->java_mirror();
+ }
+static oop field_name_or_null(Symbol* s) {
+ if (s == NULL) return NULL;
+ return StringTable::lookup(s);
+}
+
+ static oop field_signature_type_or_null(Symbol* s) {
+ if (s == NULL) return NULL;
+ BasicType bt = FieldType::basic_type(s);
+ if (is_java_primitive(bt)) {
+ assert(s->utf8_length() == 1, "");
+ return java_lang_Class::primitive_mirror(bt);
+ }
+ // Here are some more short cuts for common types.
+ // They are optional, since reference types can be resolved lazily.
+ if (bt == T_OBJECT) {
+ if (s == vmSymbols::object_signature()) {
+ return object_java_mirror();
+ } else if (s == vmSymbols::class_signature()) {
+ return Klass::cast(SystemDictionary::Class_klass())->java_mirror();
+ } else if (s == vmSymbols::string_signature()) {
+ return Klass::cast(SystemDictionary::String_klass())->java_mirror();
+ }
+static oop object_java_mirror() {
+ return Klass::cast(SystemDictionary::Object_klass())->java_mirror();
+}
+
+static oop field_signature_type_or_null(Symbol* s) {
+ if (s == NULL) return NULL;
+ BasicType bt = FieldType::basic_type(s);
+ if (is_java_primitive(bt)) {
+ assert(s->utf8_length() == 1, "");
+ return java_lang_Class::primitive_mirror(bt);
+ }
+ // Here are some more short cuts for common types.
+ // They are optional, since reference types can be resolved lazily.
+ if (bt == T_OBJECT) {
+ if (s == vmSymbols::object_signature()) {
+ return object_java_mirror();
+ } else if (s == vmSymbols::class_signature()) {
+ return Klass::cast(SystemDictionary::Class_klass())->java_mirror();
+ } else if (s == vmSymbols::string_signature()) {
+ return Klass::cast(SystemDictionary::String_klass())->java_mirror();
+ }
+ return NULL;
+ }
+ return NULL;
+}
+
+ bool update_member_name(oop obj) {
+ int flags = java_lang_invoke_MemberName::flags(obj);
+ int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK;
+ if (MethodHandles::ref_kind_is_method(ref_kind)) {
+ methodOop m = (methodOop) java_lang_invoke_MemberName::vmtarget(obj);
+ if (m != NULL && !instanceKlass::cast(m->method_holder())->is_newest_version()) {
+ // Let's try to re-resolve method
+ KlassHandle newest = instanceKlass::cast(m->method_holder())->newest_version();
+ methodOop new_method = instanceKlass::cast(newest())->find_method(m->name(), m->signature());
+
+ // Note: we might set NULL at this point, which should force AbstractMethodError at runtime
+ bool do_dispatch = (ref_kind != JVM_REF_invokeSpecial);
+ MethodHandles::init_method_MemberName(obj, new_method, do_dispatch, newest);
+ }
+ } else if (MethodHandles::ref_kind_is_field(ref_kind)) {
+ klassOop k = (klassOop) java_lang_invoke_MemberName::vmtarget(obj);
+ if (k == NULL) {
+ return false; // Was cleared before, this MemberName is invalid.
+ }
+bool update_member_name(oop obj) {
+ int flags = java_lang_invoke_MemberName::flags(obj);
+ int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK;
+ if (MethodHandles::ref_kind_is_method(ref_kind)) {
+ methodOop m = (methodOop) java_lang_invoke_MemberName::vmtarget(obj);
+ if (m != NULL && !instanceKlass::cast(m->method_holder())->is_newest_version()) {
+ // Let's try to re-resolve method
+ KlassHandle newest = instanceKlass::cast(m->method_holder())->newest_version();
+ methodOop new_method = instanceKlass::cast(newest())->find_method(m->name(), m->signature());
+
+ // Note: we might set NULL at this point, which should force AbstractMethodError at runtime
+ bool do_dispatch = (ref_kind != JVM_REF_invokeSpecial);
+ MethodHandles::init_method_MemberName(obj, new_method, do_dispatch, newest);
+ }
+ } else if (MethodHandles::ref_kind_is_field(ref_kind)) {
+ klassOop k = (klassOop) java_lang_invoke_MemberName::vmtarget(obj);
+ if (k == NULL) {
+ return false; // Was cleared before, this MemberName is invalid.
+ }
+
+ if (k != NULL && !Klass::cast(k)->is_newest_version()) {
+ // Let's try to re-resolve field
+ fieldDescriptor fd;
+ int offset = java_lang_invoke_MemberName::vmindex(obj);
+ bool is_static = MethodHandles::ref_kind_is_static(ref_kind);
+ instanceKlass *ik = instanceKlass::cast(k);
+ if (ik->find_local_field_from_offset(offset, is_static, &fd)) {
+ KlassHandle newest = Klass::cast(k)->newest_version();
+ fieldDescriptor fd_new;
+ if (instanceKlass::cast(newest())->find_local_field(fd.name(), fd.signature(), &fd_new)) {
+ bool is_setter = MethodHandles::ref_kind_is_setter(ref_kind);
+ oop type = field_signature_type_or_null(fd_new.signature());
+ oop name = field_name_or_null(fd_new.name());
+ MethodHandles::init_field_MemberName(obj, newest, fd_new.access_flags(), type, name, fd_new.offset(), is_setter);
+ } else {
+ // Matching field is not found in new version, not much we can do here.
+ // JVM will crash once faulty MH is invoked.
+ // However, to avoid that all DMH's using this faulty MH are cleared (set to NULL)
+ // Eventually, we probably want to replace them with something more meaningful,
+ // like instance throwing NoSuchFieldError or DMH that will resort to dynamic
+ // field resolution (with possibility of type conversion)
+ java_lang_invoke_MemberName::set_vmtarget(obj, NULL);
+ java_lang_invoke_MemberName::set_vmindex(obj, 0);
+ return false;
+ }
+ if (k != NULL && !Klass::cast(k)->is_newest_version()) {
+ // Let's try to re-resolve field
+ fieldDescriptor fd;
+ int offset = java_lang_invoke_MemberName::vmindex(obj);
+ bool is_static = MethodHandles::ref_kind_is_static(ref_kind);
+ instanceKlass *ik = instanceKlass::cast(k);
+ if (ik->find_local_field_from_offset(offset, is_static, &fd)) {
+ KlassHandle newest = Klass::cast(k)->newest_version();
+ fieldDescriptor fd_new;
+ if (instanceKlass::cast(newest())->find_local_field(fd.name(), fd.signature(), &fd_new)) {
+ bool is_setter = MethodHandles::ref_kind_is_setter(ref_kind);
+ oop type = field_signature_type_or_null(fd_new.signature());
+ oop name = field_name_or_null(fd_new.name());
+ MethodHandles::init_field_MemberName(obj, newest, fd_new.access_flags(), type, name, fd_new.offset(), is_setter);
+ } else {
+ // Matching field is not found in new version, not much we can do here.
+ // JVM will crash once faulty MH is invoked.
+ // However, to avoid that all DMH's using this faulty MH are cleared (set to NULL)
+ // Eventually, we probably want to replace them with something more meaningful,
+ // like instance throwing NoSuchFieldError or DMH that will resort to dynamic
+ // field resolution (with possibility of type conversion)
+ java_lang_invoke_MemberName::set_vmtarget(obj, NULL);
+ java_lang_invoke_MemberName::set_vmindex(obj, 0);
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+ return true;
+}
+
+
template <class S>
class ChangePointersOopClosure : public OopClosureNoHeader {
+
+ bool update_direct_method_handle(oop obj) {
+ // Always update member name first.
@@ -281,12 +285,10 @@ diff -r 6858a68213bf -r a416f1b672a4 src/share/vm/prims/jvmtiRedefineClasses.cpp
// Forward pointers to instanceKlass and mirror class to new versions
template <class T>
inline void do_oop_work(T* p) {
@@ -1422,6 +1536,14 @@
@@ -1422,6 +1538,12 @@
S::oop_store(p, oop);
}
}
+ } else if (java_lang_invoke_MemberName::is_instance(oop)) {
+ update_member_name(oop);
+ } else if (java_lang_invoke_DirectMethodHandle::is_instance(oop)) {
+ if (!update_direct_method_handle(oop)) {
+ // DMH is no longer valid, replace it with null reference.
@@ -296,7 +298,14 @@ diff -r 6858a68213bf -r a416f1b672a4 src/share/vm/prims/jvmtiRedefineClasses.cpp
}
}
@@ -1504,22 +1626,6 @@
@@ -1501,25 +1623,13 @@
// Causes SIGSEGV?
//instanceMirrorKlass::oop_fields_iterate(obj, _closure);
} else {
+ // Update member name before its klass pointer is updated!
+ if (java_lang_invoke_MemberName::is_instance(obj)) {
+ update_member_name(obj);
+ }
obj->oop_iterate(_closure);
}
@@ -319,7 +328,7 @@ diff -r 6858a68213bf -r a416f1b672a4 src/share/vm/prims/jvmtiRedefineClasses.cpp
if (obj->blueprint()->new_version() != NULL) {
Klass* new_klass = obj->blueprint()->new_version()->klass_part();
if (obj->is_perm()) {
@@ -1989,6 +2095,11 @@
@@ -1989,6 +2099,11 @@
transfer_old_native_function_registrations(the_old_class);
@@ -331,9 +340,9 @@ diff -r 6858a68213bf -r a416f1b672a4 src/share/vm/prims/jvmtiRedefineClasses.cpp
#ifdef ASSERT
diff -r 6858a68213bf -r a416f1b672a4 src/share/vm/runtime/mutexLocker.cpp
diff -r 6858a68213bf src/share/vm/runtime/mutexLocker.cpp
--- a/src/share/vm/runtime/mutexLocker.cpp Fri Jul 10 13:18:18 2015 -0700
+++ b/src/share/vm/runtime/mutexLocker.cpp Fri Jul 10 13:59:26 2015 -0700
+++ b/src/share/vm/runtime/mutexLocker.cpp Fri Jul 10 14:20:20 2015 -0700
@@ -265,7 +265,7 @@
def(Heap_lock , Monitor, nonleaf+1, false);
def(JfieldIdCreation_lock , Mutex , nonleaf+1, true ); // jfieldID, Used in VM_Operation

Carregando…
Cancelar
Salvar