You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

full-jdk7u79-b15-method-handles.patch 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. # HG changeset patch
  2. # Parent 9792762e75f795196a5ff68e8cd5a52380b332d0
  3. diff -r 9792762e75f7 src/share/vm/classfile/javaClasses.cpp
  4. --- a/src/share/vm/classfile/javaClasses.cpp Mon Dec 07 11:59:52 2015 -0800
  5. +++ b/src/share/vm/classfile/javaClasses.cpp Mon Dec 07 13:08:09 2015 -0800
  6. @@ -2409,6 +2409,52 @@
  7. }
  8. }
  9. +// Support for java_lang_invoke_DirectMethodHandle$StaticAccessor
  10. +
  11. +int java_lang_invoke_DirectMethodHandle_StaticAccessor::_static_offset_offset;
  12. +
  13. +long java_lang_invoke_DirectMethodHandle_StaticAccessor::static_offset(oop dmh) {
  14. + assert(_static_offset_offset != 0, "");
  15. + return dmh->long_field(_static_offset_offset);
  16. +}
  17. +
  18. +void java_lang_invoke_DirectMethodHandle_StaticAccessor::set_static_offset(oop dmh, long static_offset) {
  19. + assert(_static_offset_offset != 0, "");
  20. + dmh->long_field_put(_static_offset_offset, static_offset);
  21. +}
  22. +
  23. +
  24. +void java_lang_invoke_DirectMethodHandle_StaticAccessor::compute_offsets() {
  25. + klassOop klass_oop = SystemDictionary::DirectMethodHandle_StaticAccessor_klass();
  26. + if (klass_oop != NULL && EnableInvokeDynamic) {
  27. + compute_offset(_static_offset_offset, klass_oop, vmSymbols::static_offset_name(), vmSymbols::long_signature());
  28. + }
  29. +}
  30. +
  31. +// Support for java_lang_invoke_DirectMethodHandle$Accessor
  32. +
  33. +int java_lang_invoke_DirectMethodHandle_Accessor::_field_offset_offset;
  34. +
  35. +int java_lang_invoke_DirectMethodHandle_Accessor::field_offset(oop dmh) {
  36. + assert(_field_offset_offset != 0, "");
  37. + return dmh->int_field(_field_offset_offset);
  38. +}
  39. +
  40. +void java_lang_invoke_DirectMethodHandle_Accessor::set_field_offset(oop dmh, int field_offset) {
  41. + assert(_field_offset_offset != 0, "");
  42. + dmh->int_field_put(_field_offset_offset, field_offset);
  43. +}
  44. +
  45. +
  46. +void java_lang_invoke_DirectMethodHandle_Accessor::compute_offsets() {
  47. + klassOop klass_oop = SystemDictionary::DirectMethodHandle_Accessor_klass();
  48. + if (klass_oop != NULL && EnableInvokeDynamic) {
  49. + compute_offset(_field_offset_offset, klass_oop, vmSymbols::field_offset_name(), vmSymbols::int_signature());
  50. + }
  51. +}
  52. +
  53. +
  54. +
  55. // Support for java_lang_invoke_MethodHandle
  56. int java_lang_invoke_MethodHandle::_type_offset;
  57. @@ -3028,6 +3074,8 @@
  58. if (EnableInvokeDynamic) {
  59. java_lang_invoke_MethodHandle::compute_offsets();
  60. java_lang_invoke_DirectMethodHandle::compute_offsets();
  61. + java_lang_invoke_DirectMethodHandle_StaticAccessor::compute_offsets();
  62. + java_lang_invoke_DirectMethodHandle_Accessor::compute_offsets();
  63. java_lang_invoke_MemberName::compute_offsets();
  64. java_lang_invoke_LambdaForm::compute_offsets();
  65. java_lang_invoke_MethodType::compute_offsets();
  66. diff -r 9792762e75f7 src/share/vm/classfile/javaClasses.hpp
  67. --- a/src/share/vm/classfile/javaClasses.hpp Mon Dec 07 11:59:52 2015 -0800
  68. +++ b/src/share/vm/classfile/javaClasses.hpp Mon Dec 07 13:08:09 2015 -0800
  69. @@ -940,6 +940,54 @@
  70. static int member_offset_in_bytes() { return _member_offset; }
  71. };
  72. +// Interface to java.lang.invoke.DirectMethodHandle$StaticAccessor objects
  73. +
  74. +class java_lang_invoke_DirectMethodHandle_StaticAccessor: AllStatic {
  75. + friend class JavaClasses;
  76. +
  77. + private:
  78. + static int _static_offset_offset; // offset to static field
  79. +
  80. + static void compute_offsets();
  81. +
  82. + public:
  83. + // Accessors
  84. + static long static_offset(oop dmh);
  85. + static void set_static_offset(oop dmh, long value);
  86. +
  87. + // Testers
  88. + static bool is_subclass(klassOop klass) {
  89. + return Klass::cast(klass)->is_subclass_of(SystemDictionary::DirectMethodHandle_StaticAccessor_klass());
  90. + }
  91. + static bool is_instance(oop obj) {
  92. + return obj != NULL && is_subclass(obj->klass());
  93. + }
  94. +};
  95. +
  96. +// Interface to java.lang.invoke.DirectMethodHandle$Accessor objects
  97. +
  98. +class java_lang_invoke_DirectMethodHandle_Accessor: AllStatic {
  99. + friend class JavaClasses;
  100. +
  101. + private:
  102. + static int _field_offset_offset; // offset to field
  103. +
  104. + static void compute_offsets();
  105. +
  106. + public:
  107. + // Accessors
  108. + static int field_offset(oop dmh);
  109. + static void set_field_offset(oop dmh, int value);
  110. +
  111. + // Testers
  112. + static bool is_subclass(klassOop klass) {
  113. + return Klass::cast(klass)->is_subclass_of(SystemDictionary::DirectMethodHandle_Accessor_klass());
  114. + }
  115. + static bool is_instance(oop obj) {
  116. + return obj != NULL && is_subclass(obj->klass());
  117. + }
  118. +};
  119. +
  120. // Interface to java.lang.invoke.LambdaForm objects
  121. // (These are a private interface for managing adapter code generation.)
  122. diff -r 9792762e75f7 src/share/vm/classfile/systemDictionary.cpp
  123. --- a/src/share/vm/classfile/systemDictionary.cpp Mon Dec 07 11:59:52 2015 -0800
  124. +++ b/src/share/vm/classfile/systemDictionary.cpp Mon Dec 07 13:08:09 2015 -0800
  125. @@ -44,6 +44,7 @@
  126. #include "oops/oop.inline2.hpp"
  127. #include "oops/typeArrayKlass.hpp"
  128. #include "prims/jvmtiEnvBase.hpp"
  129. +#include "prims/jvmtiRedefineClassesTrace.hpp"
  130. #include "prims/methodHandles.hpp"
  131. #include "runtime/biasedLocking.hpp"
  132. #include "runtime/fieldType.hpp"
  133. @@ -2032,9 +2033,11 @@
  134. assert(check->klass_part()->oop_is_instance(), "noninstance in systemdictionary");
  135. if ((defining == true) && ((k() != check) && k->old_version() != check)) {
  136. ResourceMark rm(Thread::current());
  137. - tty->print_cr("(%d / %d) (%s/%s)", k->revision_number(), check->klass_part()->revision_number(), k->name()->as_C_string(), check->klass_part()->name()->as_C_string());
  138. - k()->print();
  139. - check->print();
  140. + if (RC_TRACE_ENABLED(0x00000001)) {
  141. + tty->print_cr("(%d / %d) (%s/%s)", k->revision_number(), check->klass_part()->revision_number(), k->name()->as_C_string(), check->klass_part()->name()->as_C_string());
  142. + k()->print();
  143. + check->print();
  144. + }
  145. linkage_error = "loader (instance of %s): attempted duplicate class "
  146. "definition for name: \"%s\"";
  147. } else {
  148. diff -r 9792762e75f7 src/share/vm/classfile/systemDictionary.hpp
  149. --- a/src/share/vm/classfile/systemDictionary.hpp Mon Dec 07 11:59:52 2015 -0800
  150. +++ b/src/share/vm/classfile/systemDictionary.hpp Mon Dec 07 13:08:09 2015 -0800
  151. @@ -148,6 +148,8 @@
  152. do_klass(reflect_UnsafeStaticFieldAccessorImpl_klass, sun_reflect_UnsafeStaticFieldAccessorImpl, Opt_Only_JDK15 ) \
  153. \
  154. /* support for dynamic typing; it's OK if these are NULL in earlier JDKs */ \
  155. + do_klass(DirectMethodHandle_StaticAccessor_klass, java_lang_invoke_DirectMethodHandle_StaticAccessor, Opt ) \
  156. + do_klass(DirectMethodHandle_Accessor_klass, java_lang_invoke_DirectMethodHandle_Accessor, Opt ) \
  157. do_klass(MethodHandle_klass, java_lang_invoke_MethodHandle, Pre_JSR292 ) \
  158. do_klass(MemberName_klass, java_lang_invoke_MemberName, Pre_JSR292 ) \
  159. do_klass(MethodHandleNatives_klass, java_lang_invoke_MethodHandleNatives, Pre_JSR292 ) \
  160. diff -r 9792762e75f7 src/share/vm/classfile/vmSymbols.hpp
  161. --- a/src/share/vm/classfile/vmSymbols.hpp Mon Dec 07 11:59:52 2015 -0800
  162. +++ b/src/share/vm/classfile/vmSymbols.hpp Mon Dec 07 13:08:09 2015 -0800
  163. @@ -248,6 +248,8 @@
  164. /* Support for JSR 292 & invokedynamic (JDK 1.7 and above) */ \
  165. template(java_lang_invoke_CallSite, "java/lang/invoke/CallSite") \
  166. template(java_lang_invoke_ConstantCallSite, "java/lang/invoke/ConstantCallSite") \
  167. + template(java_lang_invoke_DirectMethodHandle_StaticAccessor, "java/lang/invoke/DirectMethodHandle$StaticAccessor") \
  168. + template(java_lang_invoke_DirectMethodHandle_Accessor, "java/lang/invoke/DirectMethodHandle$Accessor") \
  169. template(java_lang_invoke_DirectMethodHandle, "java/lang/invoke/DirectMethodHandle") \
  170. template(java_lang_invoke_MutableCallSite, "java/lang/invoke/MutableCallSite") \
  171. template(java_lang_invoke_VolatileCallSite, "java/lang/invoke/VolatileCallSite") \
  172. @@ -485,6 +487,10 @@
  173. template(int_StringBuffer_signature, "(I)Ljava/lang/StringBuffer;") \
  174. template(char_StringBuffer_signature, "(C)Ljava/lang/StringBuffer;") \
  175. template(int_String_signature, "(I)Ljava/lang/String;") \
  176. + template(static_offset_name, "staticOffset") \
  177. + template(static_base_name, "staticBase") \
  178. + template(field_offset_name, "fieldOffset") \
  179. + template(field_type_name, "fieldType") \
  180. /* signature symbols needed by intrinsics */ \
  181. VM_INTRINSICS_DO(VM_INTRINSIC_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, template, VM_ALIAS_IGNORE) \
  182. \
  183. diff -r 9792762e75f7 src/share/vm/prims/jvmtiRedefineClasses.cpp
  184. --- a/src/share/vm/prims/jvmtiRedefineClasses.cpp Mon Dec 07 11:59:52 2015 -0800
  185. +++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp Mon Dec 07 13:08:09 2015 -0800
  186. @@ -2110,6 +2110,120 @@
  187. }
  188. +// import java_lang_invoke_MemberName.*
  189. +enum {
  190. + REFERENCE_KIND_SHIFT = java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT,
  191. + REFERENCE_KIND_MASK = java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK,
  192. +};
  193. +
  194. +static oop field_name_or_null(Symbol* s) {
  195. + if (s == NULL) return NULL;
  196. + return StringTable::lookup(s);
  197. +}
  198. +
  199. +static oop object_java_mirror() {
  200. + return Klass::cast(SystemDictionary::Object_klass())->java_mirror();
  201. +}
  202. +
  203. +static oop field_signature_type_or_null(Symbol* s) {
  204. + if (s == NULL) return NULL;
  205. + BasicType bt = FieldType::basic_type(s);
  206. + if (is_java_primitive(bt)) {
  207. + assert(s->utf8_length() == 1, "");
  208. + return java_lang_Class::primitive_mirror(bt);
  209. + }
  210. + // Here are some more short cuts for common types.
  211. + // They are optional, since reference types can be resolved lazily.
  212. + if (bt == T_OBJECT) {
  213. + if (s == vmSymbols::object_signature()) {
  214. + return object_java_mirror();
  215. + } else if (s == vmSymbols::class_signature()) {
  216. + return Klass::cast(SystemDictionary::Class_klass())->java_mirror();
  217. + } else if (s == vmSymbols::string_signature()) {
  218. + return Klass::cast(SystemDictionary::String_klass())->java_mirror();
  219. + }
  220. + }
  221. + return NULL;
  222. +}
  223. +
  224. +bool update_member_name(oop obj) {
  225. + int flags = java_lang_invoke_MemberName::flags(obj);
  226. + int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK;
  227. + if (MethodHandles::ref_kind_is_method(ref_kind)) {
  228. + methodOop m = (methodOop) java_lang_invoke_MemberName::vmtarget(obj);
  229. + if (m != NULL && !instanceKlass::cast(m->method_holder())->is_newest_version()) {
  230. + // Let's try to re-resolve method
  231. + KlassHandle newest = instanceKlass::cast(m->method_holder())->newest_version();
  232. + methodOop new_method = instanceKlass::cast(newest())->find_method(m->name(), m->signature());
  233. +
  234. + // Note: we might set NULL at this point, which should force AbstractMethodError at runtime
  235. + bool do_dispatch = (ref_kind != JVM_REF_invokeSpecial);
  236. + MethodHandles::init_method_MemberName(obj, new_method, do_dispatch, newest);
  237. + }
  238. + } else if (MethodHandles::ref_kind_is_field(ref_kind)) {
  239. + klassOop k = (klassOop) java_lang_invoke_MemberName::vmtarget(obj);
  240. + if (k == NULL) {
  241. + return false; // Was cleared before, this MemberName is invalid.
  242. + }
  243. +
  244. + if (k != NULL && !Klass::cast(k)->is_newest_version()) {
  245. + // Let's try to re-resolve field
  246. + fieldDescriptor fd;
  247. + int offset = java_lang_invoke_MemberName::vmindex(obj);
  248. + bool is_static = MethodHandles::ref_kind_is_static(ref_kind);
  249. + instanceKlass *ik = instanceKlass::cast(k);
  250. + if (ik->find_local_field_from_offset(offset, is_static, &fd)) {
  251. + KlassHandle newest = Klass::cast(k)->newest_version();
  252. + fieldDescriptor fd_new;
  253. + if (instanceKlass::cast(newest())->find_local_field(fd.name(), fd.signature(), &fd_new)) {
  254. + bool is_setter = MethodHandles::ref_kind_is_setter(ref_kind);
  255. + oop type = field_signature_type_or_null(fd_new.signature());
  256. + oop name = field_name_or_null(fd_new.name());
  257. + MethodHandles::init_field_MemberName(obj, newest, fd_new.access_flags(), type, name, fd_new.offset(), is_setter);
  258. + } else {
  259. + // Matching field is not found in new version, not much we can do here.
  260. + // JVM will crash once faulty MH is invoked.
  261. + // However, to avoid that all DMH's using this faulty MH are cleared (set to NULL)
  262. + // Eventually, we probably want to replace them with something more meaningful,
  263. + // like instance throwing NoSuchFieldError or DMH that will resort to dynamic
  264. + // field resolution (with possibility of type conversion)
  265. + java_lang_invoke_MemberName::set_vmtarget(obj, NULL);
  266. + java_lang_invoke_MemberName::set_vmindex(obj, 0);
  267. + return false;
  268. + }
  269. + }
  270. + }
  271. + }
  272. + return true;
  273. +}
  274. +
  275. +bool update_direct_method_handle(oop obj) {
  276. + // Always update member name first.
  277. + oop mem_name = java_lang_invoke_DirectMethodHandle::member(obj);
  278. + if (!update_member_name(mem_name)) {
  279. + return false;
  280. + }
  281. +
  282. + // Here we rely on DirectMethodHandle implementation.
  283. + // The current implementation caches field offset in $StaticAccessor/$Accessor
  284. + int flags = java_lang_invoke_MemberName::flags(mem_name);
  285. + int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK;
  286. + if (MethodHandles::ref_kind_is_field(ref_kind)) {
  287. + // Note: we don't care about staticBase field (which is java.lang.Class)
  288. + // It should be processed during normal object update.
  289. + // Update offset in StaticAccessor
  290. + int offset = java_lang_invoke_MemberName::vmindex(mem_name);
  291. + if (offset != 0) { // index of 0 means that field no longer exist
  292. + if (java_lang_invoke_DirectMethodHandle_StaticAccessor::is_instance(obj)) {
  293. + java_lang_invoke_DirectMethodHandle_StaticAccessor::set_static_offset(obj, offset);
  294. + } else if (java_lang_invoke_DirectMethodHandle_Accessor::is_instance(obj)) {
  295. + java_lang_invoke_DirectMethodHandle_Accessor::set_field_offset(obj, offset);
  296. + }
  297. + }
  298. + }
  299. + return true;
  300. +}
  301. +
  302. template <class T> void VM_RedefineClasses::do_oop_work(T* p) {
  303. T heap_oop = oopDesc::load_heap_oop(p);
  304. if (!oopDesc::is_null(heap_oop)) {
  305. @@ -2148,6 +2262,18 @@
  306. }
  307. }
  308. }
  309. + } else {
  310. + // JSR 292 support, uptade java.lang.invoke.MemberName instances
  311. + if (java_lang_invoke_MemberName::is_instance(obj)) {
  312. + update_member_name(obj);
  313. + } else if (java_lang_invoke_DirectMethodHandle::is_instance(obj)) {
  314. + if (!update_direct_method_handle(obj)) {
  315. + // DMH is no longer valid, replace it with null reference.
  316. + // See note above. We probably want to replace this with something more meaningful.
  317. + oopDesc::encode_store_heap_oop(p, NULL);
  318. + //S::oop_store(p, NULL);
  319. + }
  320. + }
  321. }
  322. }
  323. }
  324. @@ -2245,6 +2371,12 @@
  325. virtual void do_object(oop obj) {
  326. if (!obj->is_instanceKlass()) {
  327. + // JSR 292 support, uptade java.lang.invoke.MemberName instances
  328. + // Update before we update its fields, so if it is a field ref, its vmtarget still points at old klass
  329. + if (java_lang_invoke_MemberName::is_instance(obj)) {
  330. + update_member_name(obj);
  331. + }
  332. +
  333. obj->oop_iterate(_closure);
  334. if (obj->blueprint()->is_redefining()) {
  335. @@ -2822,6 +2954,11 @@
  336. // TODO:
  337. transfer_old_native_function_registrations(the_old_class);
  338. + // Swap method handles
  339. + MemberNameTable* mnt = the_old_class->member_names();
  340. + assert(the_new_class->member_names() == NULL, "");
  341. + the_new_class->set_member_names(mnt);
  342. + the_old_class->set_member_names(NULL);
  343. #ifdef ASSERT
  344. diff -r 9792762e75f7 src/share/vm/runtime/mutexLocker.cpp
  345. --- a/src/share/vm/runtime/mutexLocker.cpp Mon Dec 07 11:59:52 2015 -0800
  346. +++ b/src/share/vm/runtime/mutexLocker.cpp Mon Dec 07 13:08:09 2015 -0800
  347. @@ -267,7 +267,7 @@
  348. def(Heap_lock , Monitor, nonleaf+1, false);
  349. def(JfieldIdCreation_lock , Mutex , nonleaf+1, true ); // jfieldID, Used in VM_Operation
  350. def(JNICachedItableIndex_lock , Mutex , nonleaf+1, false); // Used to cache an itable index during JNI invoke
  351. - def(MemberNameTable_lock , Mutex , nonleaf+1, false); // Used to protect MemberNameTable
  352. + def(MemberNameTable_lock , Mutex , nonleaf+1, true); // Used to protect MemberNameTable
  353. def(CompiledIC_lock , Mutex , nonleaf+2, false); // locks VtableStubs_lock, InlineCacheBuffer_lock
  354. def(CompileTaskAlloc_lock , Mutex , nonleaf+2, true );