Wed, 07 Nov 2012 16:09:20 -0800
Merge
1.1 --- a/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java Mon Nov 05 19:33:44 2012 -0500 1.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java Wed Nov 07 16:09:20 2012 -0800 1.3 @@ -121,7 +121,7 @@ 1.4 Address addr = cache.getValue(getAddress()); 1.5 return (ConstantPoolCache) VMObjectFactory.newObject(ConstantPoolCache.class, addr); 1.6 } 1.7 - public Klass getPoolHolder() { return (Klass) poolHolder.getValue(this); } 1.8 + public InstanceKlass getPoolHolder() { return (InstanceKlass)poolHolder.getValue(this); } 1.9 public int getLength() { return (int)length.getValue(getAddress()); } 1.10 public Oop getResolvedReferences() { 1.11 Address handle = resolvedReferences.getValue(getAddress());
2.1 --- a/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java Mon Nov 05 19:33:44 2012 -0500 2.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java Wed Nov 07 16:09:20 2012 -0800 2.3 @@ -177,7 +177,7 @@ 2.4 bci. It is required that there is currently a bytecode at this 2.5 bci. */ 2.6 public int getOrigBytecodeAt(int bci) { 2.7 - BreakpointInfo bp = ((InstanceKlass) getMethodHolder()).getBreakpoints(); 2.8 + BreakpointInfo bp = getMethodHolder().getBreakpoints(); 2.9 for (; bp != null; bp = bp.getNext()) { 2.10 if (bp.match(this, bci)) { 2.11 return bp.getOrigBytecode(); 2.12 @@ -238,7 +238,7 @@ 2.13 } 2.14 2.15 // Method holder (the Klass holding this method) 2.16 - public Klass getMethodHolder() { return getConstants().getPoolHolder(); } 2.17 + public InstanceKlass getMethodHolder() { return getConstants().getPoolHolder(); } 2.18 2.19 // Access flags 2.20 public boolean isPublic() { return getAccessFlagsObj().isPublic(); }
3.1 --- a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Mon Nov 05 19:33:44 2012 -0500 3.2 +++ b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp Wed Nov 07 16:09:20 2012 -0800 3.3 @@ -2322,7 +2322,7 @@ 3.4 // Pre-load a static method's oop into O1. Used both by locking code and 3.5 // the normal JNI call code. 3.6 if (method->is_static() && !is_critical_native) { 3.7 - __ set_oop_constant(JNIHandles::make_local(Klass::cast(method->method_holder())->java_mirror()), O1); 3.8 + __ set_oop_constant(JNIHandles::make_local(method->method_holder()->java_mirror()), O1); 3.9 3.10 // Now handlize the static class mirror in O1. It's known not-null. 3.11 __ st_ptr(O1, SP, klass_offset + STACK_BIAS);
4.1 --- a/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Mon Nov 05 19:33:44 2012 -0500 4.2 +++ b/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Wed Nov 07 16:09:20 2012 -0800 4.3 @@ -1936,7 +1936,7 @@ 4.4 if (method->is_static() && !is_critical_native) { 4.5 4.6 // load opp into a register 4.7 - __ movoop(oop_handle_reg, JNIHandles::make_local(Klass::cast(method->method_holder())->java_mirror())); 4.8 + __ movoop(oop_handle_reg, JNIHandles::make_local(method->method_holder()->java_mirror())); 4.9 4.10 // Now handlize the static class mirror it's known not-null. 4.11 __ movptr(Address(rsp, klass_offset), oop_handle_reg);
5.1 --- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Mon Nov 05 19:33:44 2012 -0500 5.2 +++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Wed Nov 07 16:09:20 2012 -0800 5.3 @@ -2179,7 +2179,7 @@ 5.4 if (method->is_static() && !is_critical_native) { 5.5 5.6 // load oop into a register 5.7 - __ movoop(oop_handle_reg, JNIHandles::make_local(Klass::cast(method->method_holder())->java_mirror())); 5.8 + __ movoop(oop_handle_reg, JNIHandles::make_local(method->method_holder()->java_mirror())); 5.9 5.10 // Now handlize the static class mirror it's known not-null. 5.11 __ movptr(Address(rsp, klass_offset), oop_handle_reg);
6.1 --- a/src/share/tools/hsdis/hsdis-demo.c Mon Nov 05 19:33:44 2012 -0500 6.2 +++ b/src/share/tools/hsdis/hsdis-demo.c Wed Nov 07 16:09:20 2012 -0800 6.3 @@ -85,9 +85,11 @@ 6.4 6.5 #include "dlfcn.h" 6.6 6.7 -#define DECODE_INSTRUCTIONS_NAME "decode_instructions_virtual" 6.8 +#define DECODE_INSTRUCTIONS_VIRTUAL_NAME "decode_instructions_virtual" 6.9 +#define DECODE_INSTRUCTIONS_NAME "decode_instructions" 6.10 #define HSDIS_NAME "hsdis" 6.11 static void* decode_instructions_pv = 0; 6.12 +static void* decode_instructions_sv = 0; 6.13 static const char* hsdis_path[] = { 6.14 HSDIS_NAME"-"LIBARCH LIB_EXT, 6.15 "./" HSDIS_NAME"-"LIBARCH LIB_EXT, 6.16 @@ -101,11 +103,12 @@ 6.17 void* dllib = NULL; 6.18 const char* *next_in_path = hsdis_path; 6.19 while (1) { 6.20 - decode_instructions_pv = dlsym(dllib, DECODE_INSTRUCTIONS_NAME); 6.21 - if (decode_instructions_pv != NULL) 6.22 + decode_instructions_pv = dlsym(dllib, DECODE_INSTRUCTIONS_VIRTUAL_NAME); 6.23 + decode_instructions_sv = dlsym(dllib, DECODE_INSTRUCTIONS_NAME); 6.24 + if (decode_instructions_pv != NULL || decode_instructions_sv != NULL) 6.25 return NULL; 6.26 if (dllib != NULL) 6.27 - return "plugin does not defined "DECODE_INSTRUCTIONS_NAME; 6.28 + return "plugin does not defined "DECODE_INSTRUCTIONS_VIRTUAL_NAME" and "DECODE_INSTRUCTIONS_NAME; 6.29 for (dllib = NULL; dllib == NULL; ) { 6.30 const char* next_lib = (*next_in_path++); 6.31 if (next_lib == NULL) 6.32 @@ -213,20 +216,44 @@ 6.33 printf("%s: %s\n", err, dlerror()); 6.34 exit(1); 6.35 } 6.36 - printf("Decoding from %p to %p...\n", from, to); 6.37 - decode_instructions_ftype decode_instructions 6.38 - = (decode_instructions_ftype) decode_instructions_pv; 6.39 + decode_func_vtype decode_instructions_v 6.40 + = (decode_func_vtype) decode_instructions_pv; 6.41 + decode_func_stype decode_instructions_s 6.42 + = (decode_func_stype) decode_instructions_sv; 6.43 void* res; 6.44 - if (raw && xml) { 6.45 - res = (*decode_instructions)(from, to, (unsigned char*)from, to - from, simple_handle_event, stdout, NULL, stdout, options); 6.46 - } else if (raw) { 6.47 - res = (*decode_instructions)(from, to, (unsigned char*)from, to - from, simple_handle_event, stdout, NULL, stdout, options); 6.48 - } else { 6.49 - res = (*decode_instructions)(from, to, (unsigned char*)from, to - from, 6.50 - handle_event, (void*) event_cookie, 6.51 - fprintf_callback, stdout, 6.52 - options); 6.53 + if (decode_instructions_pv != NULL) { 6.54 + printf("\nDecoding from %p to %p...with %s\n", from, to, DECODE_INSTRUCTIONS_VIRTUAL_NAME); 6.55 + if (raw) { 6.56 + res = (*decode_instructions_v)(from, to, 6.57 + (unsigned char*)from, to - from, 6.58 + simple_handle_event, stdout, 6.59 + NULL, stdout, 6.60 + options, 0); 6.61 + } else { 6.62 + res = (*decode_instructions_v)(from, to, 6.63 + (unsigned char*)from, to - from, 6.64 + handle_event, (void*) event_cookie, 6.65 + fprintf_callback, stdout, 6.66 + options, 0); 6.67 + } 6.68 + if (res != (void*)to) 6.69 + printf("*** Result was %p!\n", res); 6.70 } 6.71 - if (res != (void*)to) 6.72 - printf("*** Result was %p!\n", res); 6.73 + void* sres; 6.74 + if (decode_instructions_sv != NULL) { 6.75 + printf("\nDecoding from %p to %p...with old decode_instructions\n", from, to, DECODE_INSTRUCTIONS_NAME); 6.76 + if (raw) { 6.77 + sres = (*decode_instructions_s)(from, to, 6.78 + simple_handle_event, stdout, 6.79 + NULL, stdout, 6.80 + options); 6.81 + } else { 6.82 + sres = (*decode_instructions_s)(from, to, 6.83 + handle_event, (void*) event_cookie, 6.84 + fprintf_callback, stdout, 6.85 + options); 6.86 + } 6.87 + if (sres != (void *)to) 6.88 + printf("*** Result of decode_instructions %p!\n", sres); 6.89 + } 6.90 }
7.1 --- a/src/share/tools/hsdis/hsdis.c Mon Nov 05 19:33:44 2012 -0500 7.2 +++ b/src/share/tools/hsdis/hsdis.c Wed Nov 07 16:09:20 2012 -0800 7.3 @@ -99,7 +99,7 @@ 7.4 unsigned char* buffer, uintptr_t length, 7.5 event_callback_t event_callback_arg, void* event_stream_arg, 7.6 printf_callback_t printf_callback_arg, void* printf_stream_arg, 7.7 - const char* options) { 7.8 + const char* options, int newline) { 7.9 struct hsdis_app_data app_data; 7.10 memset(&app_data, 0, sizeof(app_data)); 7.11 app_data.start_va = start_va; 7.12 @@ -110,7 +110,7 @@ 7.13 app_data.event_stream = event_stream_arg; 7.14 app_data.printf_callback = printf_callback_arg; 7.15 app_data.printf_stream = printf_stream_arg; 7.16 - app_data.do_newline = false; 7.17 + app_data.do_newline = newline == 0 ? false : true; 7.18 7.19 return decode(&app_data, options); 7.20 } 7.21 @@ -132,7 +132,7 @@ 7.22 event_stream_arg, 7.23 printf_callback_arg, 7.24 printf_stream_arg, 7.25 - options); 7.26 + options, false); 7.27 } 7.28 7.29 static void* decode(struct hsdis_app_data* app_data, const char* options) { 7.30 @@ -173,7 +173,7 @@ 7.31 if (!app_data->losing) { 7.32 const char* insn_close = format_insn_close("/insn", &app_data->dinfo, 7.33 buf, sizeof(buf)); 7.34 - (*event_callback)(event_stream, insn_close, (void*) p) != NULL; 7.35 + (*event_callback)(event_stream, insn_close, (void*) p); 7.36 7.37 if (app_data->do_newline) { 7.38 /* follow each complete insn by a nice newline */ 7.39 @@ -182,13 +182,14 @@ 7.40 } 7.41 } 7.42 7.43 - (*event_callback)(event_stream, "/insns", (void*) p); 7.44 + if (app_data->losing) (*event_callback)(event_stream, "/insns", (void*) p); 7.45 return (void*) p; 7.46 } 7.47 } 7.48 7.49 /* take the address of the function, for luck, and also test the typedef: */ 7.50 -const decode_instructions_ftype decode_instructions_address = &decode_instructions_virtual; 7.51 +const decode_func_vtype decode_func_virtual_address = &decode_instructions_virtual; 7.52 +const decode_func_stype decode_func_address = &decode_instructions; 7.53 7.54 static const char* format_insn_close(const char* close, 7.55 disassemble_info* dinfo,
8.1 --- a/src/share/tools/hsdis/hsdis.h Mon Nov 05 19:33:44 2012 -0500 8.2 +++ b/src/share/tools/hsdis/hsdis.h Wed Nov 07 16:09:20 2012 -0800 8.3 @@ -47,6 +47,9 @@ 8.4 where tag is a simple identifier, signifying (as in XML) a element start, 8.5 element end, and standalone element. (To render as XML, add angle brackets.) 8.6 */ 8.7 +#ifndef SHARED_TOOLS_HSDIS_H 8.8 +#define SHARED_TOOLS_HSDIS_H 8.9 + 8.10 extern 8.11 #ifdef DLL_EXPORT 8.12 DLL_EXPORT 8.13 @@ -57,16 +60,37 @@ 8.14 void* event_stream, 8.15 int (*printf_callback)(void*, const char*, ...), 8.16 void* printf_stream, 8.17 - const char* options); 8.18 + const char* options, 8.19 + int newline /* bool value for nice new line */); 8.20 + 8.21 +/* This is the compatability interface for older versions of hotspot */ 8.22 +extern 8.23 +#ifdef DLL_ENTRY 8.24 + DLL_ENTRY 8.25 +#endif 8.26 +void* decode_instructions(void* start_pv, void* end_pv, 8.27 + void* (*event_callback)(void*, const char*, void*), 8.28 + void* event_stream, 8.29 + int (*printf_callback)(void*, const char*, ...), 8.30 + void* printf_stream, 8.31 + const char* options); 8.32 8.33 /* convenience typedefs */ 8.34 8.35 typedef void* (*decode_instructions_event_callback_ftype) (void*, const char*, void*); 8.36 typedef int (*decode_instructions_printf_callback_ftype) (void*, const char*, ...); 8.37 -typedef void* (*decode_instructions_ftype) (uintptr_t start_va, uintptr_t end_va, 8.38 - unsigned char* buffer, uintptr_t length, 8.39 - decode_instructions_event_callback_ftype event_callback, 8.40 - void* event_stream, 8.41 - decode_instructions_printf_callback_ftype printf_callback, 8.42 - void* printf_stream, 8.43 - const char* options); 8.44 +typedef void* (*decode_func_vtype) (uintptr_t start_va, uintptr_t end_va, 8.45 + unsigned char* buffer, uintptr_t length, 8.46 + decode_instructions_event_callback_ftype event_callback, 8.47 + void* event_stream, 8.48 + decode_instructions_printf_callback_ftype printf_callback, 8.49 + void* printf_stream, 8.50 + const char* options, 8.51 + int newline); 8.52 +typedef void* (*decode_func_stype) (void* start_pv, void* end_pv, 8.53 + decode_instructions_event_callback_ftype event_callback, 8.54 + void* event_stream, 8.55 + decode_instructions_printf_callback_ftype printf_callback, 8.56 + void* printf_stream, 8.57 + const char* options); 8.58 +#endif /* SHARED_TOOLS_HSDIS_H */
9.1 --- a/src/share/vm/ci/ciEnv.cpp Mon Nov 05 19:33:44 2012 -0500 9.2 +++ b/src/share/vm/ci/ciEnv.cpp Wed Nov 07 16:09:20 2012 -0800 9.3 @@ -768,8 +768,8 @@ 9.4 Method* m = lookup_method(accessor->get_instanceKlass(), lookup, name_sym, sig_sym, bc); 9.5 if (m != NULL && 9.6 (bc == Bytecodes::_invokestatic 9.7 - ? InstanceKlass::cast(m->method_holder())->is_not_initialized() 9.8 - : !InstanceKlass::cast(m->method_holder())->is_loaded())) { 9.9 + ? m->method_holder()->is_not_initialized() 9.10 + : !m->method_holder()->is_loaded())) { 9.11 m = NULL; 9.12 } 9.13 if (m != NULL) { 9.14 @@ -1056,7 +1056,7 @@ 9.15 method_name, 9.16 entry_bci); 9.17 } 9.18 - InstanceKlass::cast(method->method_holder())->add_osr_nmethod(nm); 9.19 + method->method_holder()->add_osr_nmethod(nm); 9.20 9.21 } 9.22 }
10.1 --- a/src/share/vm/ci/ciMethod.cpp Mon Nov 05 19:33:44 2012 -0500 10.2 +++ b/src/share/vm/ci/ciMethod.cpp Wed Nov 07 16:09:20 2012 -0800 10.3 @@ -105,7 +105,7 @@ 10.4 CHECK_UNHANDLED_OOPS_ONLY(Thread::current()->clear_unhandled_oops()); 10.5 } 10.6 10.7 - if (InstanceKlass::cast(h_m()->method_holder())->is_linked()) { 10.8 + if (h_m()->method_holder()->is_linked()) { 10.9 _can_be_statically_bound = h_m()->can_be_statically_bound(); 10.10 } else { 10.11 // Have to use a conservative value in this case. 10.12 @@ -188,7 +188,7 @@ 10.13 10.14 // Revert any breakpoint bytecodes in ci's copy 10.15 if (me->number_of_breakpoints() > 0) { 10.16 - BreakpointInfo* bp = InstanceKlass::cast(me->method_holder())->breakpoints(); 10.17 + BreakpointInfo* bp = me->method_holder()->breakpoints(); 10.18 for (; bp != NULL; bp = bp->next()) { 10.19 if (bp->match(me)) { 10.20 code_at_put(bp->bci(), bp->orig_bytecode());
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/src/share/vm/classfile/bytecodeAssembler.cpp Wed Nov 07 16:09:20 2012 -0800 11.3 @@ -0,0 +1,269 @@ 11.4 +/* 11.5 + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. 11.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 11.7 + * 11.8 + * This code is free software; you can redistribute it and/or modify it 11.9 + * under the terms of the GNU General Public License version 2 only, as 11.10 + * published by the Free Software Foundation. 11.11 + * 11.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 11.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11.15 + * version 2 for more details (a copy is included in the LICENSE file that 11.16 + * accompanied this code). 11.17 + * 11.18 + * You should have received a copy of the GNU General Public License version 11.19 + * 2 along with this work; if not, write to the Free Software Foundation, 11.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 11.21 + * 11.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 11.23 + * or visit www.oracle.com if you need additional information or have any 11.24 + * questions. 11.25 + * 11.26 + */ 11.27 + 11.28 +#include "precompiled.hpp" 11.29 + 11.30 +#include "classfile/bytecodeAssembler.hpp" 11.31 +#include "interpreter/bytecodes.hpp" 11.32 +#include "memory/oopFactory.hpp" 11.33 +#include "oops/constantPool.hpp" 11.34 + 11.35 +#ifdef TARGET_ARCH_x86 11.36 +# include "bytes_x86.hpp" 11.37 +#endif 11.38 +#ifdef TARGET_ARCH_sparc 11.39 +# include "bytes_sparc.hpp" 11.40 +#endif 11.41 +#ifdef TARGET_ARCH_zero 11.42 +# include "bytes_zero.hpp" 11.43 +#endif 11.44 +#ifdef TARGET_ARCH_arm 11.45 +# include "bytes_arm.hpp" 11.46 +#endif 11.47 +#ifdef TARGET_ARCH_ppc 11.48 +# include "bytes_ppc.hpp" 11.49 +#endif 11.50 + 11.51 +u2 BytecodeConstantPool::find_or_add(BytecodeCPEntry const& bcpe) { 11.52 + u2 index; 11.53 + u2* probe = _indices.get(bcpe); 11.54 + if (probe == NULL) { 11.55 + index = _entries.length(); 11.56 + _entries.append(bcpe); 11.57 + _indices.put(bcpe, index); 11.58 + } else { 11.59 + index = *probe; 11.60 + } 11.61 + return index + _orig->length(); 11.62 +} 11.63 + 11.64 +ConstantPool* BytecodeConstantPool::create_constant_pool(TRAPS) const { 11.65 + if (_entries.length() == 0) { 11.66 + return _orig; 11.67 + } 11.68 + 11.69 + ConstantPool* cp = ConstantPool::allocate( 11.70 + _orig->pool_holder()->class_loader_data(), 11.71 + _orig->length() + _entries.length(), CHECK_NULL); 11.72 + 11.73 + cp->set_pool_holder(_orig->pool_holder()); 11.74 + _orig->copy_cp_to(1, _orig->length() - 1, cp, 1, CHECK_NULL); 11.75 + 11.76 + for (int i = 0; i < _entries.length(); ++i) { 11.77 + BytecodeCPEntry entry = _entries.at(i); 11.78 + int idx = i + _orig->length(); 11.79 + switch (entry._tag) { 11.80 + case BytecodeCPEntry::UTF8: 11.81 + cp->symbol_at_put(idx, entry._u.utf8); 11.82 + entry._u.utf8->increment_refcount(); 11.83 + break; 11.84 + case BytecodeCPEntry::KLASS: 11.85 + cp->unresolved_klass_at_put( 11.86 + idx, cp->symbol_at(entry._u.klass)); 11.87 + break; 11.88 + case BytecodeCPEntry::STRING: 11.89 + cp->unresolved_string_at_put( 11.90 + idx, cp->symbol_at(entry._u.string)); 11.91 + break; 11.92 + case BytecodeCPEntry::NAME_AND_TYPE: 11.93 + cp->name_and_type_at_put(idx, 11.94 + entry._u.name_and_type.name_index, 11.95 + entry._u.name_and_type.type_index); 11.96 + break; 11.97 + case BytecodeCPEntry::METHODREF: 11.98 + cp->method_at_put(idx, 11.99 + entry._u.methodref.class_index, 11.100 + entry._u.methodref.name_and_type_index); 11.101 + break; 11.102 + default: 11.103 + ShouldNotReachHere(); 11.104 + } 11.105 + } 11.106 + return cp; 11.107 +} 11.108 + 11.109 +void BytecodeAssembler::append(u1 imm_u1) { 11.110 + _code->append(imm_u1); 11.111 +} 11.112 + 11.113 +void BytecodeAssembler::append(u2 imm_u2) { 11.114 + _code->append(0); 11.115 + _code->append(0); 11.116 + Bytes::put_Java_u2(_code->adr_at(_code->length() - 2), imm_u2); 11.117 +} 11.118 + 11.119 +void BytecodeAssembler::append(u4 imm_u4) { 11.120 + _code->append(0); 11.121 + _code->append(0); 11.122 + _code->append(0); 11.123 + _code->append(0); 11.124 + Bytes::put_Java_u4(_code->adr_at(_code->length() - 4), imm_u4); 11.125 +} 11.126 + 11.127 +void BytecodeAssembler::xload(u4 index, u1 onebyteop, u1 twobyteop) { 11.128 + if (index < 4) { 11.129 + _code->append(onebyteop + index); 11.130 + } else { 11.131 + _code->append(twobyteop); 11.132 + _code->append((u2)index); 11.133 + } 11.134 +} 11.135 + 11.136 +void BytecodeAssembler::dup() { 11.137 + _code->append(Bytecodes::_dup); 11.138 +} 11.139 + 11.140 +void BytecodeAssembler::_new(Symbol* sym) { 11.141 + u2 cpool_index = _cp->klass(sym); 11.142 + _code->append(Bytecodes::_new); 11.143 + append(cpool_index); 11.144 +} 11.145 + 11.146 +void BytecodeAssembler::load_string(Symbol* sym) { 11.147 + u2 cpool_index = _cp->string(sym); 11.148 + if (cpool_index < 0x100) { 11.149 + ldc(cpool_index); 11.150 + } else { 11.151 + ldc_w(cpool_index); 11.152 + } 11.153 +} 11.154 + 11.155 +void BytecodeAssembler::ldc(u1 index) { 11.156 + _code->append(Bytecodes::_ldc); 11.157 + append(index); 11.158 +} 11.159 + 11.160 +void BytecodeAssembler::ldc_w(u2 index) { 11.161 + _code->append(Bytecodes::_ldc_w); 11.162 + append(index); 11.163 +} 11.164 + 11.165 +void BytecodeAssembler::athrow() { 11.166 + _code->append(Bytecodes::_athrow); 11.167 +} 11.168 + 11.169 +void BytecodeAssembler::iload(u4 index) { 11.170 + xload(index, Bytecodes::_iload_0, Bytecodes::_iload); 11.171 +} 11.172 + 11.173 +void BytecodeAssembler::lload(u4 index) { 11.174 + xload(index, Bytecodes::_lload_0, Bytecodes::_lload); 11.175 +} 11.176 + 11.177 +void BytecodeAssembler::fload(u4 index) { 11.178 + xload(index, Bytecodes::_fload_0, Bytecodes::_fload); 11.179 +} 11.180 + 11.181 +void BytecodeAssembler::dload(u4 index) { 11.182 + xload(index, Bytecodes::_dload_0, Bytecodes::_dload); 11.183 +} 11.184 + 11.185 +void BytecodeAssembler::aload(u4 index) { 11.186 + xload(index, Bytecodes::_aload_0, Bytecodes::_aload); 11.187 +} 11.188 + 11.189 +void BytecodeAssembler::load(BasicType bt, u4 index) { 11.190 + switch (bt) { 11.191 + case T_BOOLEAN: 11.192 + case T_CHAR: 11.193 + case T_BYTE: 11.194 + case T_SHORT: 11.195 + case T_INT: iload(index); break; 11.196 + case T_FLOAT: fload(index); break; 11.197 + case T_DOUBLE: dload(index); break; 11.198 + case T_LONG: lload(index); break; 11.199 + case T_OBJECT: 11.200 + case T_ARRAY: aload(index); break; 11.201 + default: 11.202 + ShouldNotReachHere(); 11.203 + } 11.204 +} 11.205 + 11.206 +void BytecodeAssembler::checkcast(Symbol* sym) { 11.207 + u2 cpool_index = _cp->klass(sym); 11.208 + _code->append(Bytecodes::_checkcast); 11.209 + append(cpool_index); 11.210 +} 11.211 + 11.212 +void BytecodeAssembler::invokespecial(Method* method) { 11.213 + invokespecial(method->klass_name(), method->name(), method->signature()); 11.214 +} 11.215 + 11.216 +void BytecodeAssembler::invokespecial(Symbol* klss, Symbol* name, Symbol* sig) { 11.217 + u2 methodref_index = _cp->methodref(klss, name, sig); 11.218 + _code->append(Bytecodes::_invokespecial); 11.219 + append(methodref_index); 11.220 +} 11.221 + 11.222 +void BytecodeAssembler::invokevirtual(Method* method) { 11.223 + invokevirtual(method->klass_name(), method->name(), method->signature()); 11.224 +} 11.225 + 11.226 +void BytecodeAssembler::invokevirtual(Symbol* klss, Symbol* name, Symbol* sig) { 11.227 + u2 methodref_index = _cp->methodref(klss, name, sig); 11.228 + _code->append(Bytecodes::_invokevirtual); 11.229 + append(methodref_index); 11.230 +} 11.231 + 11.232 +void BytecodeAssembler::ireturn() { 11.233 + _code->append(Bytecodes::_ireturn); 11.234 +} 11.235 + 11.236 +void BytecodeAssembler::lreturn() { 11.237 + _code->append(Bytecodes::_lreturn); 11.238 +} 11.239 + 11.240 +void BytecodeAssembler::freturn() { 11.241 + _code->append(Bytecodes::_freturn); 11.242 +} 11.243 + 11.244 +void BytecodeAssembler::dreturn() { 11.245 + _code->append(Bytecodes::_dreturn); 11.246 +} 11.247 + 11.248 +void BytecodeAssembler::areturn() { 11.249 + _code->append(Bytecodes::_areturn); 11.250 +} 11.251 + 11.252 +void BytecodeAssembler::_return() { 11.253 + _code->append(Bytecodes::_return); 11.254 +} 11.255 + 11.256 +void BytecodeAssembler::_return(BasicType bt) { 11.257 + switch (bt) { 11.258 + case T_BOOLEAN: 11.259 + case T_CHAR: 11.260 + case T_BYTE: 11.261 + case T_SHORT: 11.262 + case T_INT: ireturn(); break; 11.263 + case T_FLOAT: freturn(); break; 11.264 + case T_DOUBLE: dreturn(); break; 11.265 + case T_LONG: lreturn(); break; 11.266 + case T_OBJECT: 11.267 + case T_ARRAY: areturn(); break; 11.268 + case T_VOID: _return(); break; 11.269 + default: 11.270 + ShouldNotReachHere(); 11.271 + } 11.272 +}
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/src/share/vm/classfile/bytecodeAssembler.hpp Wed Nov 07 16:09:20 2012 -0800 12.3 @@ -0,0 +1,214 @@ 12.4 +/* 12.5 + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. 12.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 12.7 + * 12.8 + * This code is free software; you can redistribute it and/or modify it 12.9 + * under the terms of the GNU General Public License version 2 only, as 12.10 + * published by the Free Software Foundation. 12.11 + * 12.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 12.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12.15 + * version 2 for more details (a copy is included in the LICENSE file that 12.16 + * accompanied this code). 12.17 + * 12.18 + * You should have received a copy of the GNU General Public License version 12.19 + * 2 along with this work; if not, write to the Free Software Foundation, 12.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 12.21 + * 12.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 12.23 + * or visit www.oracle.com if you need additional information or have any 12.24 + * questions. 12.25 + * 12.26 + */ 12.27 + 12.28 +#ifndef SHARE_VM_CLASSFILE_BYTECODEASSEMBLER_HPP 12.29 +#define SHARE_VM_CLASSFILE_BYTECODEASSEMBLER_HPP 12.30 + 12.31 +#include "memory/allocation.hpp" 12.32 +#include "oops/method.hpp" 12.33 +#include "oops/symbol.hpp" 12.34 +#include "utilities/globalDefinitions.hpp" 12.35 +#include "utilities/growableArray.hpp" 12.36 +#include "utilities/resourceHash.hpp" 12.37 + 12.38 + 12.39 +/** 12.40 + * Bytecode Assembler 12.41 + * 12.42 + * These classes are used to synthesize code for creating new methods from 12.43 + * within the VM. This is only a partial implementation of an assembler; 12.44 + * only the bytecodes that are needed by clients are implemented at this time. 12.45 + * This is used during default method analysis to create overpass methods 12.46 + * and add them to a call during parsing. Other uses (such as creating 12.47 + * bridges) may come later. Any missing bytecodes can be implemented on an 12.48 + * as-need basis. 12.49 + */ 12.50 + 12.51 +class BytecodeBuffer : public GrowableArray<u1> { 12.52 + public: 12.53 + BytecodeBuffer() : GrowableArray<u1>(20) {} 12.54 +}; 12.55 + 12.56 +// Entries in a yet-to-be-created constant pool. Limited types for now. 12.57 +class BytecodeCPEntry VALUE_OBJ_CLASS_SPEC { 12.58 + public: 12.59 + enum tag { 12.60 + ERROR_TAG, 12.61 + UTF8, 12.62 + KLASS, 12.63 + STRING, 12.64 + NAME_AND_TYPE, 12.65 + METHODREF 12.66 + }; 12.67 + 12.68 + u1 _tag; 12.69 + union { 12.70 + Symbol* utf8; 12.71 + u2 klass; 12.72 + u2 string; 12.73 + struct { 12.74 + u2 name_index; 12.75 + u2 type_index; 12.76 + } name_and_type; 12.77 + struct { 12.78 + u2 class_index; 12.79 + u2 name_and_type_index; 12.80 + } methodref; 12.81 + uintptr_t hash; 12.82 + } _u; 12.83 + 12.84 + BytecodeCPEntry() : _tag(ERROR_TAG) { _u.hash = 0; } 12.85 + BytecodeCPEntry(u1 tag) : _tag(tag) { _u.hash = 0; } 12.86 + 12.87 + static BytecodeCPEntry utf8(Symbol* symbol) { 12.88 + BytecodeCPEntry bcpe(UTF8); 12.89 + bcpe._u.utf8 = symbol; 12.90 + return bcpe; 12.91 + } 12.92 + 12.93 + static BytecodeCPEntry klass(u2 index) { 12.94 + BytecodeCPEntry bcpe(KLASS); 12.95 + bcpe._u.klass = index; 12.96 + return bcpe; 12.97 + } 12.98 + 12.99 + static BytecodeCPEntry string(u2 index) { 12.100 + BytecodeCPEntry bcpe(STRING); 12.101 + bcpe._u.string = index; 12.102 + return bcpe; 12.103 + } 12.104 + 12.105 + static BytecodeCPEntry name_and_type(u2 name, u2 type) { 12.106 + BytecodeCPEntry bcpe(NAME_AND_TYPE); 12.107 + bcpe._u.name_and_type.name_index = name; 12.108 + bcpe._u.name_and_type.type_index = type; 12.109 + return bcpe; 12.110 + } 12.111 + 12.112 + static BytecodeCPEntry methodref(u2 class_index, u2 nat) { 12.113 + BytecodeCPEntry bcpe(METHODREF); 12.114 + bcpe._u.methodref.class_index = class_index; 12.115 + bcpe._u.methodref.name_and_type_index = nat; 12.116 + return bcpe; 12.117 + } 12.118 + 12.119 + static bool equals(BytecodeCPEntry const& e0, BytecodeCPEntry const& e1) { 12.120 + return e0._tag == e1._tag && e0._u.hash == e1._u.hash; 12.121 + } 12.122 + 12.123 + static unsigned hash(BytecodeCPEntry const& e0) { 12.124 + return (unsigned)(e0._tag ^ e0._u.hash); 12.125 + } 12.126 +}; 12.127 + 12.128 +class BytecodeConstantPool : ResourceObj { 12.129 + private: 12.130 + typedef ResourceHashtable<BytecodeCPEntry, u2, 12.131 + &BytecodeCPEntry::hash, &BytecodeCPEntry::equals> IndexHash; 12.132 + 12.133 + ConstantPool* _orig; 12.134 + GrowableArray<BytecodeCPEntry> _entries; 12.135 + IndexHash _indices; 12.136 + 12.137 + u2 find_or_add(BytecodeCPEntry const& bcpe); 12.138 + 12.139 + public: 12.140 + 12.141 + BytecodeConstantPool(ConstantPool* orig) : _orig(orig) {} 12.142 + 12.143 + BytecodeCPEntry const& at(u2 index) const { return _entries.at(index); } 12.144 + 12.145 + InstanceKlass* pool_holder() const { 12.146 + return InstanceKlass::cast(_orig->pool_holder()); 12.147 + } 12.148 + 12.149 + u2 utf8(Symbol* sym) { 12.150 + return find_or_add(BytecodeCPEntry::utf8(sym)); 12.151 + } 12.152 + 12.153 + u2 klass(Symbol* class_name) { 12.154 + return find_or_add(BytecodeCPEntry::klass(utf8(class_name))); 12.155 + } 12.156 + 12.157 + u2 string(Symbol* str) { 12.158 + return find_or_add(BytecodeCPEntry::string(utf8(str))); 12.159 + } 12.160 + 12.161 + u2 name_and_type(Symbol* name, Symbol* sig) { 12.162 + return find_or_add(BytecodeCPEntry::name_and_type(utf8(name), utf8(sig))); 12.163 + } 12.164 + 12.165 + u2 methodref(Symbol* class_name, Symbol* name, Symbol* sig) { 12.166 + return find_or_add(BytecodeCPEntry::methodref( 12.167 + klass(class_name), name_and_type(name, sig))); 12.168 + } 12.169 + 12.170 + ConstantPool* create_constant_pool(TRAPS) const; 12.171 +}; 12.172 + 12.173 +// Partial bytecode assembler - only what we need for creating 12.174 +// overpass methods for default methods is implemented 12.175 +class BytecodeAssembler : StackObj { 12.176 + private: 12.177 + BytecodeBuffer* _code; 12.178 + BytecodeConstantPool* _cp; 12.179 + 12.180 + void append(u1 imm_u1); 12.181 + void append(u2 imm_u2); 12.182 + void append(u4 imm_u4); 12.183 + 12.184 + void xload(u4 index, u1 quick, u1 twobyte); 12.185 + 12.186 + public: 12.187 + BytecodeAssembler(BytecodeBuffer* buffer, BytecodeConstantPool* cp) 12.188 + : _code(buffer), _cp(cp) {} 12.189 + 12.190 + void aload(u4 index); 12.191 + void areturn(); 12.192 + void athrow(); 12.193 + void checkcast(Symbol* sym); 12.194 + void dload(u4 index); 12.195 + void dreturn(); 12.196 + void dup(); 12.197 + void fload(u4 index); 12.198 + void freturn(); 12.199 + void iload(u4 index); 12.200 + void invokespecial(Method* method); 12.201 + void invokespecial(Symbol* cls, Symbol* name, Symbol* sig); 12.202 + void invokevirtual(Method* method); 12.203 + void invokevirtual(Symbol* cls, Symbol* name, Symbol* sig); 12.204 + void ireturn(); 12.205 + void ldc(u1 index); 12.206 + void ldc_w(u2 index); 12.207 + void lload(u4 index); 12.208 + void lreturn(); 12.209 + void _new(Symbol* sym); 12.210 + void _return(); 12.211 + 12.212 + void load_string(Symbol* sym); 12.213 + void load(BasicType bt, u4 index); 12.214 + void _return(BasicType bt); 12.215 +}; 12.216 + 12.217 +#endif // SHARE_VM_CLASSFILE_BYTECODEASSEMBLER_HPP
13.1 --- a/src/share/vm/classfile/classFileParser.cpp Mon Nov 05 19:33:44 2012 -0500 13.2 +++ b/src/share/vm/classfile/classFileParser.cpp Wed Nov 07 16:09:20 2012 -0800 13.3 @@ -27,6 +27,8 @@ 13.4 #include "classfile/classLoader.hpp" 13.5 #include "classfile/classLoaderData.hpp" 13.6 #include "classfile/classLoaderData.inline.hpp" 13.7 +#include "classfile/defaultMethods.hpp" 13.8 +#include "classfile/genericSignatures.hpp" 13.9 #include "classfile/javaClasses.hpp" 13.10 #include "classfile/symbolTable.hpp" 13.11 #include "classfile/systemDictionary.hpp" 13.12 @@ -84,6 +86,9 @@ 13.13 // - to check NameAndType_info signatures more aggressively 13.14 #define JAVA_7_VERSION 51 13.15 13.16 +// Extension method support. 13.17 +#define JAVA_8_VERSION 52 13.18 + 13.19 13.20 void ClassFileParser::parse_constant_pool_entries(ClassLoaderData* loader_data, constantPoolHandle cp, int length, TRAPS) { 13.21 // Use a local copy of ClassFileStream. It helps the C++ compiler to optimize 13.22 @@ -785,6 +790,7 @@ 13.23 ClassLoaderData* loader_data, 13.24 Handle protection_domain, 13.25 Symbol* class_name, 13.26 + bool* has_default_methods, 13.27 TRAPS) { 13.28 ClassFileStream* cfs = stream(); 13.29 assert(length > 0, "only called for length>0"); 13.30 @@ -821,6 +827,9 @@ 13.31 if (!Klass::cast(interf())->is_interface()) { 13.32 THROW_MSG_(vmSymbols::java_lang_IncompatibleClassChangeError(), "Implementing class", NULL); 13.33 } 13.34 + if (InstanceKlass::cast(interf())->has_default_methods()) { 13.35 + *has_default_methods = true; 13.36 + } 13.37 interfaces->at_put(index, interf()); 13.38 } 13.39 13.40 @@ -1928,7 +1937,8 @@ 13.41 if (method_attribute_name == vmSymbols::tag_code()) { 13.42 // Parse Code attribute 13.43 if (_need_verify) { 13.44 - guarantee_property(!access_flags.is_native() && !access_flags.is_abstract(), 13.45 + guarantee_property( 13.46 + !access_flags.is_native() && !access_flags.is_abstract(), 13.47 "Code attribute in native or abstract methods in class file %s", 13.48 CHECK_(nullHandle)); 13.49 } 13.50 @@ -2125,7 +2135,9 @@ 13.51 runtime_visible_annotations_length = method_attribute_length; 13.52 runtime_visible_annotations = cfs->get_u1_buffer(); 13.53 assert(runtime_visible_annotations != NULL, "null visible annotations"); 13.54 - parse_annotations(runtime_visible_annotations, runtime_visible_annotations_length, cp, &parsed_annotations, CHECK_(nullHandle)); 13.55 + parse_annotations(runtime_visible_annotations, 13.56 + runtime_visible_annotations_length, cp, &parsed_annotations, 13.57 + CHECK_(nullHandle)); 13.58 cfs->skip_u1(runtime_visible_annotations_length, CHECK_(nullHandle)); 13.59 } else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_annotations()) { 13.60 runtime_invisible_annotations_length = method_attribute_length; 13.61 @@ -2169,12 +2181,10 @@ 13.62 } 13.63 13.64 // All sizing information for a Method* is finally available, now create it 13.65 - Method* m = Method::allocate(loader_data, code_length, access_flags, 13.66 - linenumber_table_length, 13.67 - total_lvt_length, 13.68 - exception_table_length, 13.69 - checked_exceptions_length, 13.70 - CHECK_(nullHandle)); 13.71 + Method* m = Method::allocate( 13.72 + loader_data, code_length, access_flags, linenumber_table_length, 13.73 + total_lvt_length, exception_table_length, checked_exceptions_length, 13.74 + ConstMethod::NORMAL, CHECK_(nullHandle)); 13.75 13.76 ClassLoadingService::add_class_method_size(m->size()*HeapWordSize); 13.77 13.78 @@ -2204,7 +2214,6 @@ 13.79 // Fill in code attribute information 13.80 m->set_max_stack(max_stack); 13.81 m->set_max_locals(max_locals); 13.82 - 13.83 m->constMethod()->set_stackmap_data(stackmap_data); 13.84 13.85 // Copy byte codes 13.86 @@ -2356,6 +2365,7 @@ 13.87 Array<AnnotationArray*>** methods_annotations, 13.88 Array<AnnotationArray*>** methods_parameter_annotations, 13.89 Array<AnnotationArray*>** methods_default_annotations, 13.90 + bool* has_default_methods, 13.91 TRAPS) { 13.92 ClassFileStream* cfs = stream(); 13.93 AnnotationArray* method_annotations = NULL; 13.94 @@ -2382,6 +2392,10 @@ 13.95 if (method->is_final()) { 13.96 *has_final_method = true; 13.97 } 13.98 + if (is_interface && !method->is_abstract() && !method->is_static()) { 13.99 + // default method 13.100 + *has_default_methods = true; 13.101 + } 13.102 methods->at_put(index, method()); 13.103 if (*methods_annotations == NULL) { 13.104 *methods_annotations = 13.105 @@ -2907,6 +2921,34 @@ 13.106 } 13.107 13.108 13.109 +#ifndef PRODUCT 13.110 +static void parseAndPrintGenericSignatures( 13.111 + instanceKlassHandle this_klass, TRAPS) { 13.112 + assert(ParseAllGenericSignatures == true, "Shouldn't call otherwise"); 13.113 + ResourceMark rm; 13.114 + 13.115 + if (this_klass->generic_signature() != NULL) { 13.116 + using namespace generic; 13.117 + ClassDescriptor* spec = ClassDescriptor::parse_generic_signature(this_klass(), CHECK); 13.118 + 13.119 + tty->print_cr("Parsing %s", this_klass->generic_signature()->as_C_string()); 13.120 + spec->print_on(tty); 13.121 + 13.122 + for (int i = 0; i < this_klass->methods()->length(); ++i) { 13.123 + Method* m = this_klass->methods()->at(i); 13.124 + MethodDescriptor* method_spec = MethodDescriptor::parse_generic_signature(m, spec); 13.125 + Symbol* sig = m->generic_signature(); 13.126 + if (sig == NULL) { 13.127 + sig = m->signature(); 13.128 + } 13.129 + tty->print_cr("Parsing %s", sig->as_C_string()); 13.130 + method_spec->print_on(tty); 13.131 + } 13.132 + } 13.133 +} 13.134 +#endif // ndef PRODUCT 13.135 + 13.136 + 13.137 instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name, 13.138 Handle class_loader, 13.139 Handle protection_domain, 13.140 @@ -2923,6 +2965,8 @@ 13.141 unsigned char *cached_class_file_bytes = NULL; 13.142 jint cached_class_file_length; 13.143 ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(class_loader()); 13.144 + bool has_default_methods = false; 13.145 + ResourceMark rm(THREAD); 13.146 13.147 ClassFileStream* cfs = stream(); 13.148 // Timing 13.149 @@ -3138,7 +3182,9 @@ 13.150 if (itfs_len == 0) { 13.151 local_interfaces = Universe::the_empty_klass_array(); 13.152 } else { 13.153 - local_interfaces = parse_interfaces(cp, itfs_len, loader_data, protection_domain, _class_name, CHECK_(nullHandle)); 13.154 + local_interfaces = parse_interfaces( 13.155 + cp, itfs_len, loader_data, protection_domain, _class_name, 13.156 + &has_default_methods, CHECK_(nullHandle)); 13.157 } 13.158 13.159 u2 java_fields_count = 0; 13.160 @@ -3164,6 +3210,7 @@ 13.161 &methods_annotations, 13.162 &methods_parameter_annotations, 13.163 &methods_default_annotations, 13.164 + &has_default_methods, 13.165 CHECK_(nullHandle)); 13.166 13.167 // Additional attributes 13.168 @@ -3193,6 +3240,11 @@ 13.169 super_klass = instanceKlassHandle(THREAD, kh()); 13.170 } 13.171 if (super_klass.not_null()) { 13.172 + 13.173 + if (super_klass->has_default_methods()) { 13.174 + has_default_methods = true; 13.175 + } 13.176 + 13.177 if (super_klass->is_interface()) { 13.178 ResourceMark rm(THREAD); 13.179 Exceptions::fthrow( 13.180 @@ -3229,14 +3281,11 @@ 13.181 int itable_size = 0; 13.182 int num_miranda_methods = 0; 13.183 13.184 - klassVtable::compute_vtable_size_and_num_mirandas(vtable_size, 13.185 - num_miranda_methods, 13.186 - super_klass(), 13.187 - methods, 13.188 - access_flags, 13.189 - class_loader, 13.190 - class_name, 13.191 - local_interfaces, 13.192 + GrowableArray<Method*> all_mirandas(20); 13.193 + 13.194 + klassVtable::compute_vtable_size_and_num_mirandas( 13.195 + &vtable_size, &num_miranda_methods, &all_mirandas, super_klass(), methods, 13.196 + access_flags, class_loader, class_name, local_interfaces, 13.197 CHECK_(nullHandle)); 13.198 13.199 // Size of Java itable (in words) 13.200 @@ -3656,6 +3705,7 @@ 13.201 13.202 this_klass->set_minor_version(minor_version); 13.203 this_klass->set_major_version(major_version); 13.204 + this_klass->set_has_default_methods(has_default_methods); 13.205 13.206 // Set up Method*::intrinsic_id as soon as we know the names of methods. 13.207 // (We used to do this lazily, but now we query it in Rewriter, 13.208 @@ -3673,6 +3723,16 @@ 13.209 cached_class_file_length); 13.210 } 13.211 13.212 + // Fill in field values obtained by parse_classfile_attributes 13.213 + if (parsed_annotations.has_any_annotations()) 13.214 + parsed_annotations.apply_to(this_klass); 13.215 + // Create annotations 13.216 + if (_annotations != NULL && this_klass->annotations() == NULL) { 13.217 + Annotations* anno = Annotations::allocate(loader_data, CHECK_NULL); 13.218 + this_klass->set_annotations(anno); 13.219 + } 13.220 + apply_parsed_class_attributes(this_klass); 13.221 + 13.222 // Miranda methods 13.223 if ((num_miranda_methods > 0) || 13.224 // if this class introduced new miranda methods or 13.225 @@ -3682,18 +3742,6 @@ 13.226 this_klass->set_has_miranda_methods(); // then set a flag 13.227 } 13.228 13.229 - // Fill in field values obtained by parse_classfile_attributes 13.230 - if (parsed_annotations.has_any_annotations()) { 13.231 - parsed_annotations.apply_to(this_klass); 13.232 - } 13.233 - // Create annotations 13.234 - if (_annotations != NULL && this_klass->annotations() == NULL) { 13.235 - Annotations* anno = Annotations::allocate(loader_data, CHECK_NULL); 13.236 - this_klass->set_annotations(anno); 13.237 - } 13.238 - apply_parsed_class_attributes(this_klass); 13.239 - 13.240 - // Compute transitive closure of interfaces this class implements 13.241 this_klass->set_transitive_interfaces(transitive_interfaces); 13.242 13.243 // Fill in information needed to compute superclasses. 13.244 @@ -3702,6 +3750,7 @@ 13.245 // Initialize itable offset tables 13.246 klassItable::setup_itable_offset_table(this_klass); 13.247 13.248 + // Compute transitive closure of interfaces this class implements 13.249 // Do final class setup 13.250 fill_oop_maps(this_klass, nonstatic_oop_map_count, nonstatic_oop_offsets, nonstatic_oop_counts); 13.251 13.252 @@ -3726,6 +3775,21 @@ 13.253 check_illegal_static_method(this_klass, CHECK_(nullHandle)); 13.254 } 13.255 13.256 + 13.257 +#ifdef ASSERT 13.258 + if (ParseAllGenericSignatures) { 13.259 + parseAndPrintGenericSignatures(this_klass, CHECK_(nullHandle)); 13.260 + } 13.261 +#endif 13.262 + 13.263 + // Generate any default methods - default methods are interface methods 13.264 + // that have a default implementation. This is new with Lambda project. 13.265 + if (has_default_methods && !access_flags.is_interface() && 13.266 + local_interfaces->length() > 0) { 13.267 + DefaultMethods::generate_default_methods( 13.268 + this_klass(), &all_mirandas, CHECK_(nullHandle)); 13.269 + } 13.270 + 13.271 // Allocate mirror and initialize static fields 13.272 java_lang_Class::create_mirror(this_klass, CHECK_(nullHandle)); 13.273 13.274 @@ -3744,6 +3808,7 @@ 13.275 false /* not shared class */); 13.276 13.277 if (TraceClassLoading) { 13.278 + ResourceMark rm; 13.279 // print in a single call to reduce interleaving of output 13.280 if (cfs->source() != NULL) { 13.281 tty->print("[Loaded %s from %s]\n", this_klass->external_name(), 13.282 @@ -3758,13 +3823,13 @@ 13.283 tty->print("[Loaded %s]\n", this_klass->external_name()); 13.284 } 13.285 } else { 13.286 - ResourceMark rm; 13.287 tty->print("[Loaded %s from %s]\n", this_klass->external_name(), 13.288 InstanceKlass::cast(class_loader->klass())->external_name()); 13.289 } 13.290 } 13.291 13.292 if (TraceClassResolution) { 13.293 + ResourceMark rm; 13.294 // print out the superclass. 13.295 const char * from = Klass::cast(this_klass())->external_name(); 13.296 if (this_klass->java_super() != NULL) { 13.297 @@ -3785,6 +3850,7 @@ 13.298 13.299 #ifndef PRODUCT 13.300 if( PrintCompactFieldsSavings ) { 13.301 + ResourceMark rm; 13.302 if( nonstatic_field_size < orig_nonstatic_field_size ) { 13.303 tty->print("[Saved %d of %d bytes in %s]\n", 13.304 (orig_nonstatic_field_size - nonstatic_field_size)*heapOopSize, 13.305 @@ -3811,7 +3877,6 @@ 13.306 return this_klass; 13.307 } 13.308 13.309 - 13.310 unsigned int 13.311 ClassFileParser::compute_oop_map_count(instanceKlassHandle super, 13.312 unsigned int nonstatic_oop_map_count, 13.313 @@ -4128,7 +4193,7 @@ 13.314 } 13.315 13.316 // continue to look from super_m's holder's super. 13.317 - k = InstanceKlass::cast(super_m->method_holder())->super(); 13.318 + k = super_m->method_holder()->super(); 13.319 continue; 13.320 } 13.321 13.322 @@ -4263,13 +4328,16 @@ 13.323 const bool is_strict = (flags & JVM_ACC_STRICT) != 0; 13.324 const bool is_synchronized = (flags & JVM_ACC_SYNCHRONIZED) != 0; 13.325 const bool major_gte_15 = _major_version >= JAVA_1_5_VERSION; 13.326 + const bool major_gte_8 = _major_version >= JAVA_8_VERSION; 13.327 const bool is_initializer = (name == vmSymbols::object_initializer_name()); 13.328 13.329 bool is_illegal = false; 13.330 13.331 if (is_interface) { 13.332 - if (!is_abstract || !is_public || is_static || is_final || 13.333 - is_native || (major_gte_15 && (is_synchronized || is_strict))) { 13.334 + if (!is_public || is_static || is_final || is_native || 13.335 + ((is_synchronized || is_strict) && major_gte_15 && 13.336 + (!major_gte_8 || is_abstract)) || 13.337 + (!major_gte_8 && !is_abstract)) { 13.338 is_illegal = true; 13.339 } 13.340 } else { // not interface
14.1 --- a/src/share/vm/classfile/classFileParser.hpp Mon Nov 05 19:33:44 2012 -0500 14.2 +++ b/src/share/vm/classfile/classFileParser.hpp Wed Nov 07 16:09:20 2012 -0800 14.3 @@ -151,6 +151,7 @@ 14.4 ClassLoaderData* loader_data, 14.5 Handle protection_domain, 14.6 Symbol* class_name, 14.7 + bool* has_default_methods, 14.8 TRAPS); 14.9 void record_defined_class_dependencies(instanceKlassHandle defined_klass, TRAPS); 14.10 14.11 @@ -188,6 +189,7 @@ 14.12 Array<AnnotationArray*>** methods_annotations, 14.13 Array<AnnotationArray*>** methods_parameter_annotations, 14.14 Array<AnnotationArray*>** methods_default_annotations, 14.15 + bool* has_default_method, 14.16 TRAPS); 14.17 Array<int>* sort_methods(ClassLoaderData* loader_data, 14.18 Array<Method*>* methods,
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 15.2 +++ b/src/share/vm/classfile/defaultMethods.cpp Wed Nov 07 16:09:20 2012 -0800 15.3 @@ -0,0 +1,1387 @@ 15.4 +/* 15.5 + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. 15.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 15.7 + * 15.8 + * This code is free software; you can redistribute it and/or modify it 15.9 + * under the terms of the GNU General Public License version 2 only, as 15.10 + * published by the Free Software Foundation. 15.11 + * 15.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 15.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 15.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15.15 + * version 2 for more details (a copy is included in the LICENSE file that 15.16 + * accompanied this code). 15.17 + * 15.18 + * You should have received a copy of the GNU General Public License version 15.19 + * 2 along with this work; if not, write to the Free Software Foundation, 15.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 15.21 + * 15.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 15.23 + * or visit www.oracle.com if you need additional information or have any 15.24 + * questions. 15.25 + * 15.26 + */ 15.27 + 15.28 +#include "precompiled.hpp" 15.29 +#include "classfile/bytecodeAssembler.hpp" 15.30 +#include "classfile/defaultMethods.hpp" 15.31 +#include "classfile/genericSignatures.hpp" 15.32 +#include "classfile/symbolTable.hpp" 15.33 +#include "memory/allocation.hpp" 15.34 +#include "memory/metadataFactory.hpp" 15.35 +#include "memory/resourceArea.hpp" 15.36 +#include "runtime/signature.hpp" 15.37 +#include "runtime/thread.hpp" 15.38 +#include "oops/instanceKlass.hpp" 15.39 +#include "oops/klass.hpp" 15.40 +#include "oops/method.hpp" 15.41 +#include "utilities/accessFlags.hpp" 15.42 +#include "utilities/exceptions.hpp" 15.43 +#include "utilities/ostream.hpp" 15.44 +#include "utilities/pair.hpp" 15.45 +#include "utilities/resourceHash.hpp" 15.46 + 15.47 +typedef enum { QUALIFIED, DISQUALIFIED } QualifiedState; 15.48 + 15.49 +// Because we use an iterative algorithm when iterating over the type 15.50 +// hierarchy, we can't use traditional scoped objects which automatically do 15.51 +// cleanup in the destructor when the scope is exited. PseudoScope (and 15.52 +// PseudoScopeMark) provides a similar functionality, but for when you want a 15.53 +// scoped object in non-stack memory (such as in resource memory, as we do 15.54 +// here). You've just got to remember to call 'destroy()' on the scope when 15.55 +// leaving it (and marks have to be explicitly added). 15.56 +class PseudoScopeMark : public ResourceObj { 15.57 + public: 15.58 + virtual void destroy() = 0; 15.59 +}; 15.60 + 15.61 +class PseudoScope : public ResourceObj { 15.62 + private: 15.63 + GrowableArray<PseudoScopeMark*> _marks; 15.64 + public: 15.65 + 15.66 + static PseudoScope* cast(void* data) { 15.67 + return static_cast<PseudoScope*>(data); 15.68 + } 15.69 + 15.70 + void add_mark(PseudoScopeMark* psm) { 15.71 + _marks.append(psm); 15.72 + } 15.73 + 15.74 + void destroy() { 15.75 + for (int i = 0; i < _marks.length(); ++i) { 15.76 + _marks.at(i)->destroy(); 15.77 + } 15.78 + } 15.79 +}; 15.80 + 15.81 +class ContextMark : public PseudoScopeMark { 15.82 + private: 15.83 + generic::Context::Mark _mark; 15.84 + public: 15.85 + ContextMark(const generic::Context::Mark& cm) : _mark(cm) {} 15.86 + virtual void destroy() { _mark.destroy(); } 15.87 +}; 15.88 + 15.89 +#ifndef PRODUCT 15.90 +static void print_slot(outputStream* str, Symbol* name, Symbol* signature) { 15.91 + ResourceMark rm; 15.92 + str->print("%s%s", name->as_C_string(), signature->as_C_string()); 15.93 +} 15.94 + 15.95 +static void print_method(outputStream* str, Method* mo, bool with_class=true) { 15.96 + ResourceMark rm; 15.97 + if (with_class) { 15.98 + str->print("%s.", mo->klass_name()->as_C_string()); 15.99 + } 15.100 + print_slot(str, mo->name(), mo->signature()); 15.101 +} 15.102 +#endif // ndef PRODUCT 15.103 + 15.104 +/** 15.105 + * Perform a depth-first iteration over the class hierarchy, applying 15.106 + * algorithmic logic as it goes. 15.107 + * 15.108 + * This class is one half of the inheritance hierarchy analysis mechanism. 15.109 + * It is meant to be used in conjunction with another class, the algorithm, 15.110 + * which is indicated by the ALGO template parameter. This class can be 15.111 + * paired with any algorithm class that provides the required methods. 15.112 + * 15.113 + * This class contains all the mechanics for iterating over the class hierarchy 15.114 + * starting at a particular root, without recursing (thus limiting stack growth 15.115 + * from this point). It visits each superclass (if present) and superinterface 15.116 + * in a depth-first manner, with callbacks to the ALGO class as each class is 15.117 + * encountered (visit()), The algorithm can cut-off further exploration of a 15.118 + * particular branch by returning 'false' from a visit() call. 15.119 + * 15.120 + * The ALGO class, must provide a visit() method, which each of which will be 15.121 + * called once for each node in the inheritance tree during the iteration. In 15.122 + * addition, it can provide a memory block via new_node_data(InstanceKlass*), 15.123 + * which it can use for node-specific storage (and access via the 15.124 + * current_data() and data_at_depth(int) methods). 15.125 + * 15.126 + * Bare minimum needed to be an ALGO class: 15.127 + * class Algo : public HierarchyVisitor<Algo> { 15.128 + * void* new_node_data(InstanceKlass* cls) { return NULL; } 15.129 + * void free_node_data(void* data) { return; } 15.130 + * bool visit() { return true; } 15.131 + * }; 15.132 + */ 15.133 +template <class ALGO> 15.134 +class HierarchyVisitor : StackObj { 15.135 + private: 15.136 + 15.137 + class Node : public ResourceObj { 15.138 + public: 15.139 + InstanceKlass* _class; 15.140 + bool _super_was_visited; 15.141 + int _interface_index; 15.142 + void* _algorithm_data; 15.143 + 15.144 + Node(InstanceKlass* cls, void* data, bool visit_super) 15.145 + : _class(cls), _super_was_visited(!visit_super), 15.146 + _interface_index(0), _algorithm_data(data) {} 15.147 + 15.148 + int number_of_interfaces() { return _class->local_interfaces()->length(); } 15.149 + int interface_index() { return _interface_index; } 15.150 + void set_super_visited() { _super_was_visited = true; } 15.151 + void increment_visited_interface() { ++_interface_index; } 15.152 + void set_all_interfaces_visited() { 15.153 + _interface_index = number_of_interfaces(); 15.154 + } 15.155 + bool has_visited_super() { return _super_was_visited; } 15.156 + bool has_visited_all_interfaces() { 15.157 + return interface_index() >= number_of_interfaces(); 15.158 + } 15.159 + InstanceKlass* interface_at(int index) { 15.160 + return InstanceKlass::cast(_class->local_interfaces()->at(index)); 15.161 + } 15.162 + InstanceKlass* next_super() { return _class->java_super(); } 15.163 + InstanceKlass* next_interface() { 15.164 + return interface_at(interface_index()); 15.165 + } 15.166 + }; 15.167 + 15.168 + bool _cancelled; 15.169 + GrowableArray<Node*> _path; 15.170 + 15.171 + Node* current_top() const { return _path.top(); } 15.172 + bool has_more_nodes() const { return !_path.is_empty(); } 15.173 + void push(InstanceKlass* cls, void* data) { 15.174 + assert(cls != NULL, "Requires a valid instance class"); 15.175 + Node* node = new Node(cls, data, has_super(cls)); 15.176 + _path.push(node); 15.177 + } 15.178 + void pop() { _path.pop(); } 15.179 + 15.180 + void reset_iteration() { 15.181 + _cancelled = false; 15.182 + _path.clear(); 15.183 + } 15.184 + bool is_cancelled() const { return _cancelled; } 15.185 + 15.186 + static bool has_super(InstanceKlass* cls) { 15.187 + return cls->super() != NULL && !cls->is_interface(); 15.188 + } 15.189 + 15.190 + Node* node_at_depth(int i) const { 15.191 + return (i >= _path.length()) ? NULL : _path.at(_path.length() - i - 1); 15.192 + } 15.193 + 15.194 + protected: 15.195 + 15.196 + // Accessors available to the algorithm 15.197 + int current_depth() const { return _path.length() - 1; } 15.198 + 15.199 + InstanceKlass* class_at_depth(int i) { 15.200 + Node* n = node_at_depth(i); 15.201 + return n == NULL ? NULL : n->_class; 15.202 + } 15.203 + InstanceKlass* current_class() { return class_at_depth(0); } 15.204 + 15.205 + void* data_at_depth(int i) { 15.206 + Node* n = node_at_depth(i); 15.207 + return n == NULL ? NULL : n->_algorithm_data; 15.208 + } 15.209 + void* current_data() { return data_at_depth(0); } 15.210 + 15.211 + void cancel_iteration() { _cancelled = true; } 15.212 + 15.213 + public: 15.214 + 15.215 + void run(InstanceKlass* root) { 15.216 + ALGO* algo = static_cast<ALGO*>(this); 15.217 + 15.218 + reset_iteration(); 15.219 + 15.220 + void* algo_data = algo->new_node_data(root); 15.221 + push(root, algo_data); 15.222 + bool top_needs_visit = true; 15.223 + 15.224 + do { 15.225 + Node* top = current_top(); 15.226 + if (top_needs_visit) { 15.227 + if (algo->visit() == false) { 15.228 + // algorithm does not want to continue along this path. Arrange 15.229 + // it so that this state is immediately popped off the stack 15.230 + top->set_super_visited(); 15.231 + top->set_all_interfaces_visited(); 15.232 + } 15.233 + top_needs_visit = false; 15.234 + } 15.235 + 15.236 + if (top->has_visited_super() && top->has_visited_all_interfaces()) { 15.237 + algo->free_node_data(top->_algorithm_data); 15.238 + pop(); 15.239 + } else { 15.240 + InstanceKlass* next = NULL; 15.241 + if (top->has_visited_super() == false) { 15.242 + next = top->next_super(); 15.243 + top->set_super_visited(); 15.244 + } else { 15.245 + next = top->next_interface(); 15.246 + top->increment_visited_interface(); 15.247 + } 15.248 + assert(next != NULL, "Otherwise we shouldn't be here"); 15.249 + algo_data = algo->new_node_data(next); 15.250 + push(next, algo_data); 15.251 + top_needs_visit = true; 15.252 + } 15.253 + } while (!is_cancelled() && has_more_nodes()); 15.254 + } 15.255 +}; 15.256 + 15.257 +#ifndef PRODUCT 15.258 +class PrintHierarchy : public HierarchyVisitor<PrintHierarchy> { 15.259 + public: 15.260 + 15.261 + bool visit() { 15.262 + InstanceKlass* cls = current_class(); 15.263 + streamIndentor si(tty, current_depth() * 2); 15.264 + tty->indent().print_cr("%s", cls->name()->as_C_string()); 15.265 + return true; 15.266 + } 15.267 + 15.268 + void* new_node_data(InstanceKlass* cls) { return NULL; } 15.269 + void free_node_data(void* data) { return; } 15.270 +}; 15.271 +#endif // ndef PRODUCT 15.272 + 15.273 +// Used to register InstanceKlass objects and all related metadata structures 15.274 +// (Methods, ConstantPools) as "in-use" by the current thread so that they can't 15.275 +// be deallocated by class redefinition while we're using them. The classes are 15.276 +// de-registered when this goes out of scope. 15.277 +// 15.278 +// Once a class is registered, we need not bother with methodHandles or 15.279 +// constantPoolHandles for it's associated metadata. 15.280 +class KeepAliveRegistrar : public StackObj { 15.281 + private: 15.282 + Thread* _thread; 15.283 + GrowableArray<ConstantPool*> _keep_alive; 15.284 + 15.285 + public: 15.286 + KeepAliveRegistrar(Thread* thread) : _thread(thread), _keep_alive(20) { 15.287 + assert(thread == Thread::current(), "Must be current thread"); 15.288 + } 15.289 + 15.290 + ~KeepAliveRegistrar() { 15.291 + for (int i = _keep_alive.length() - 1; i >= 0; --i) { 15.292 + ConstantPool* cp = _keep_alive.at(i); 15.293 + int idx = _thread->metadata_handles()->find_from_end(cp); 15.294 + assert(idx > 0, "Must be in the list"); 15.295 + _thread->metadata_handles()->remove_at(idx); 15.296 + } 15.297 + } 15.298 + 15.299 + // Register a class as 'in-use' by the thread. It's fine to register a class 15.300 + // multiple times (though perhaps inefficient) 15.301 + void register_class(InstanceKlass* ik) { 15.302 + ConstantPool* cp = ik->constants(); 15.303 + _keep_alive.push(cp); 15.304 + _thread->metadata_handles()->push(cp); 15.305 + } 15.306 +}; 15.307 + 15.308 +class KeepAliveVisitor : public HierarchyVisitor<KeepAliveVisitor> { 15.309 + private: 15.310 + KeepAliveRegistrar* _registrar; 15.311 + 15.312 + public: 15.313 + KeepAliveVisitor(KeepAliveRegistrar* registrar) : _registrar(registrar) {} 15.314 + 15.315 + void* new_node_data(InstanceKlass* cls) { return NULL; } 15.316 + void free_node_data(void* data) { return; } 15.317 + 15.318 + bool visit() { 15.319 + _registrar->register_class(current_class()); 15.320 + return true; 15.321 + } 15.322 +}; 15.323 + 15.324 +// A method family contains a set of all methods that implement a single 15.325 +// language-level method. Because of erasure, these methods may have different 15.326 +// signatures. As members of the set are collected while walking over the 15.327 +// hierarchy, they are tagged with a qualification state. The qualification 15.328 +// state for an erased method is set to disqualified if there exists a path 15.329 +// from the root of hierarchy to the method that contains an interleaving 15.330 +// language-equivalent method defined in an interface. 15.331 +class MethodFamily : public ResourceObj { 15.332 + private: 15.333 + 15.334 + generic::MethodDescriptor* _descriptor; // language-level description 15.335 + GrowableArray<Pair<Method*,QualifiedState> > _members; 15.336 + ResourceHashtable<Method*, int> _member_index; 15.337 + 15.338 + Method* _selected_target; // Filled in later, if a unique target exists 15.339 + Symbol* _exception_message; // If no unique target is found 15.340 + 15.341 + bool contains_method(Method* method) { 15.342 + int* lookup = _member_index.get(method); 15.343 + return lookup != NULL; 15.344 + } 15.345 + 15.346 + void add_method(Method* method, QualifiedState state) { 15.347 + Pair<Method*,QualifiedState> entry(method, state); 15.348 + _member_index.put(method, _members.length()); 15.349 + _members.append(entry); 15.350 + } 15.351 + 15.352 + void disqualify_method(Method* method) { 15.353 + int* index = _member_index.get(method); 15.354 + assert(index != NULL && *index >= 0 && *index < _members.length(), "bad index"); 15.355 + _members.at(*index).second = DISQUALIFIED; 15.356 + } 15.357 + 15.358 + Symbol* generate_no_defaults_message(TRAPS) const; 15.359 + Symbol* generate_abstract_method_message(Method* method, TRAPS) const; 15.360 + Symbol* generate_conflicts_message(GrowableArray<Method*>* methods, TRAPS) const; 15.361 + 15.362 + public: 15.363 + 15.364 + MethodFamily(generic::MethodDescriptor* canonical_desc) 15.365 + : _descriptor(canonical_desc), _selected_target(NULL), 15.366 + _exception_message(NULL) {} 15.367 + 15.368 + generic::MethodDescriptor* descriptor() const { return _descriptor; } 15.369 + 15.370 + bool descriptor_matches(generic::MethodDescriptor* md, generic::Context* ctx) { 15.371 + return descriptor()->covariant_match(md, ctx); 15.372 + } 15.373 + 15.374 + void set_target_if_empty(Method* m) { 15.375 + if (_selected_target == NULL && !m->is_overpass()) { 15.376 + _selected_target = m; 15.377 + } 15.378 + } 15.379 + 15.380 + void record_qualified_method(Method* m) { 15.381 + // If the method already exists in the set as qualified, this operation is 15.382 + // redundant. If it already exists as disqualified, then we leave it as 15.383 + // disqualfied. Thus we only add to the set if it's not already in the 15.384 + // set. 15.385 + if (!contains_method(m)) { 15.386 + add_method(m, QUALIFIED); 15.387 + } 15.388 + } 15.389 + 15.390 + void record_disqualified_method(Method* m) { 15.391 + // If not in the set, add it as disqualified. If it's already in the set, 15.392 + // then set the state to disqualified no matter what the previous state was. 15.393 + if (!contains_method(m)) { 15.394 + add_method(m, DISQUALIFIED); 15.395 + } else { 15.396 + disqualify_method(m); 15.397 + } 15.398 + } 15.399 + 15.400 + bool has_target() const { return _selected_target != NULL; } 15.401 + bool throws_exception() { return _exception_message != NULL; } 15.402 + 15.403 + Method* get_selected_target() { return _selected_target; } 15.404 + Symbol* get_exception_message() { return _exception_message; } 15.405 + 15.406 + // Either sets the target or the exception error message 15.407 + void determine_target(InstanceKlass* root, TRAPS) { 15.408 + if (has_target() || throws_exception()) { 15.409 + return; 15.410 + } 15.411 + 15.412 + GrowableArray<Method*> qualified_methods; 15.413 + for (int i = 0; i < _members.length(); ++i) { 15.414 + Pair<Method*,QualifiedState> entry = _members.at(i); 15.415 + if (entry.second == QUALIFIED) { 15.416 + qualified_methods.append(entry.first); 15.417 + } 15.418 + } 15.419 + 15.420 + if (qualified_methods.length() == 0) { 15.421 + _exception_message = generate_no_defaults_message(CHECK); 15.422 + } else if (qualified_methods.length() == 1) { 15.423 + Method* method = qualified_methods.at(0); 15.424 + if (method->is_abstract()) { 15.425 + _exception_message = generate_abstract_method_message(method, CHECK); 15.426 + } else { 15.427 + _selected_target = qualified_methods.at(0); 15.428 + } 15.429 + } else { 15.430 + _exception_message = generate_conflicts_message(&qualified_methods,CHECK); 15.431 + } 15.432 + 15.433 + assert((has_target() ^ throws_exception()) == 1, 15.434 + "One and only one must be true"); 15.435 + } 15.436 + 15.437 + bool contains_signature(Symbol* query) { 15.438 + for (int i = 0; i < _members.length(); ++i) { 15.439 + if (query == _members.at(i).first->signature()) { 15.440 + return true; 15.441 + } 15.442 + } 15.443 + return false; 15.444 + } 15.445 + 15.446 +#ifndef PRODUCT 15.447 + void print_on(outputStream* str) const { 15.448 + print_on(str, 0); 15.449 + } 15.450 + 15.451 + void print_on(outputStream* str, int indent) const { 15.452 + streamIndentor si(str, indent * 2); 15.453 + 15.454 + generic::Context ctx(NULL); // empty, as _descriptor already canonicalized 15.455 + TempNewSymbol family = descriptor()->reify_signature(&ctx, Thread::current()); 15.456 + str->indent().print_cr("Logical Method %s:", family->as_C_string()); 15.457 + 15.458 + streamIndentor si2(str); 15.459 + for (int i = 0; i < _members.length(); ++i) { 15.460 + str->indent(); 15.461 + print_method(str, _members.at(i).first); 15.462 + if (_members.at(i).second == DISQUALIFIED) { 15.463 + str->print(" (disqualified)"); 15.464 + } 15.465 + str->print_cr(""); 15.466 + } 15.467 + 15.468 + if (_selected_target != NULL) { 15.469 + print_selected(str, 1); 15.470 + } 15.471 + } 15.472 + 15.473 + void print_selected(outputStream* str, int indent) const { 15.474 + assert(has_target(), "Should be called otherwise"); 15.475 + streamIndentor si(str, indent * 2); 15.476 + str->indent().print("Selected method: "); 15.477 + print_method(str, _selected_target); 15.478 + str->print_cr(""); 15.479 + } 15.480 + 15.481 + void print_exception(outputStream* str, int indent) { 15.482 + assert(throws_exception(), "Should be called otherwise"); 15.483 + streamIndentor si(str, indent * 2); 15.484 + str->indent().print_cr("%s", _exception_message->as_C_string()); 15.485 + } 15.486 +#endif // ndef PRODUCT 15.487 +}; 15.488 + 15.489 +Symbol* MethodFamily::generate_no_defaults_message(TRAPS) const { 15.490 + return SymbolTable::new_symbol("No qualifying defaults found", CHECK_NULL); 15.491 +} 15.492 + 15.493 +Symbol* MethodFamily::generate_abstract_method_message(Method* method, TRAPS) const { 15.494 + Symbol* klass = method->klass_name(); 15.495 + Symbol* name = method->name(); 15.496 + Symbol* sig = method->signature(); 15.497 + stringStream ss; 15.498 + ss.print("Method "); 15.499 + ss.write((const char*)klass->bytes(), klass->utf8_length()); 15.500 + ss.print("."); 15.501 + ss.write((const char*)name->bytes(), name->utf8_length()); 15.502 + ss.write((const char*)sig->bytes(), sig->utf8_length()); 15.503 + ss.print(" is abstract"); 15.504 + return SymbolTable::new_symbol(ss.base(), (int)ss.size(), CHECK_NULL); 15.505 +} 15.506 + 15.507 +Symbol* MethodFamily::generate_conflicts_message(GrowableArray<Method*>* methods, TRAPS) const { 15.508 + stringStream ss; 15.509 + ss.print("Conflicting default methods:"); 15.510 + for (int i = 0; i < methods->length(); ++i) { 15.511 + Method* method = methods->at(i); 15.512 + Symbol* klass = method->klass_name(); 15.513 + Symbol* name = method->name(); 15.514 + ss.print(" "); 15.515 + ss.write((const char*)klass->bytes(), klass->utf8_length()); 15.516 + ss.print("."); 15.517 + ss.write((const char*)name->bytes(), name->utf8_length()); 15.518 + } 15.519 + return SymbolTable::new_symbol(ss.base(), (int)ss.size(), CHECK_NULL); 15.520 +} 15.521 + 15.522 +class StateRestorer; 15.523 + 15.524 +// StatefulMethodFamily is a wrapper around MethodFamily that maintains the 15.525 +// qualification state during hierarchy visitation, and applies that state 15.526 +// when adding members to the MethodFamily. 15.527 +class StatefulMethodFamily : public ResourceObj { 15.528 + friend class StateRestorer; 15.529 + private: 15.530 + MethodFamily* _method; 15.531 + QualifiedState _qualification_state; 15.532 + 15.533 + void set_qualification_state(QualifiedState state) { 15.534 + _qualification_state = state; 15.535 + } 15.536 + 15.537 + public: 15.538 + StatefulMethodFamily(generic::MethodDescriptor* md, generic::Context* ctx) { 15.539 + _method = new MethodFamily(md->canonicalize(ctx)); 15.540 + _qualification_state = QUALIFIED; 15.541 + } 15.542 + 15.543 + void set_target_if_empty(Method* m) { _method->set_target_if_empty(m); } 15.544 + 15.545 + MethodFamily* get_method_family() { return _method; } 15.546 + 15.547 + bool descriptor_matches(generic::MethodDescriptor* md, generic::Context* ctx) { 15.548 + return _method->descriptor_matches(md, ctx); 15.549 + } 15.550 + 15.551 + StateRestorer* record_method_and_dq_further(Method* mo); 15.552 +}; 15.553 + 15.554 +class StateRestorer : public PseudoScopeMark { 15.555 + private: 15.556 + StatefulMethodFamily* _method; 15.557 + QualifiedState _state_to_restore; 15.558 + public: 15.559 + StateRestorer(StatefulMethodFamily* dm, QualifiedState state) 15.560 + : _method(dm), _state_to_restore(state) {} 15.561 + ~StateRestorer() { destroy(); } 15.562 + void restore_state() { _method->set_qualification_state(_state_to_restore); } 15.563 + virtual void destroy() { restore_state(); } 15.564 +}; 15.565 + 15.566 +StateRestorer* StatefulMethodFamily::record_method_and_dq_further(Method* mo) { 15.567 + StateRestorer* mark = new StateRestorer(this, _qualification_state); 15.568 + if (_qualification_state == QUALIFIED) { 15.569 + _method->record_qualified_method(mo); 15.570 + } else { 15.571 + _method->record_disqualified_method(mo); 15.572 + } 15.573 + // Everything found "above"??? this method in the hierarchy walk is set to 15.574 + // disqualified 15.575 + set_qualification_state(DISQUALIFIED); 15.576 + return mark; 15.577 +} 15.578 + 15.579 +class StatefulMethodFamilies : public ResourceObj { 15.580 + private: 15.581 + GrowableArray<StatefulMethodFamily*> _methods; 15.582 + 15.583 + public: 15.584 + StatefulMethodFamily* find_matching( 15.585 + generic::MethodDescriptor* md, generic::Context* ctx) { 15.586 + for (int i = 0; i < _methods.length(); ++i) { 15.587 + StatefulMethodFamily* existing = _methods.at(i); 15.588 + if (existing->descriptor_matches(md, ctx)) { 15.589 + return existing; 15.590 + } 15.591 + } 15.592 + return NULL; 15.593 + } 15.594 + 15.595 + StatefulMethodFamily* find_matching_or_create( 15.596 + generic::MethodDescriptor* md, generic::Context* ctx) { 15.597 + StatefulMethodFamily* method = find_matching(md, ctx); 15.598 + if (method == NULL) { 15.599 + method = new StatefulMethodFamily(md, ctx); 15.600 + _methods.append(method); 15.601 + } 15.602 + return method; 15.603 + } 15.604 + 15.605 + void extract_families_into(GrowableArray<MethodFamily*>* array) { 15.606 + for (int i = 0; i < _methods.length(); ++i) { 15.607 + array->append(_methods.at(i)->get_method_family()); 15.608 + } 15.609 + } 15.610 +}; 15.611 + 15.612 +// Represents a location corresponding to a vtable slot for methods that 15.613 +// neither the class nor any of it's ancestors provide an implementaion. 15.614 +// Default methods may be present to fill this slot. 15.615 +class EmptyVtableSlot : public ResourceObj { 15.616 + private: 15.617 + Symbol* _name; 15.618 + Symbol* _signature; 15.619 + int _size_of_parameters; 15.620 + MethodFamily* _binding; 15.621 + 15.622 + public: 15.623 + EmptyVtableSlot(Method* method) 15.624 + : _name(method->name()), _signature(method->signature()), 15.625 + _size_of_parameters(method->size_of_parameters()), _binding(NULL) {} 15.626 + 15.627 + Symbol* name() const { return _name; } 15.628 + Symbol* signature() const { return _signature; } 15.629 + int size_of_parameters() const { return _size_of_parameters; } 15.630 + 15.631 + void bind_family(MethodFamily* lm) { _binding = lm; } 15.632 + bool is_bound() { return _binding != NULL; } 15.633 + MethodFamily* get_binding() { return _binding; } 15.634 + 15.635 +#ifndef PRODUCT 15.636 + void print_on(outputStream* str) const { 15.637 + print_slot(str, name(), signature()); 15.638 + } 15.639 +#endif // ndef PRODUCT 15.640 +}; 15.641 + 15.642 +static GrowableArray<EmptyVtableSlot*>* find_empty_vtable_slots( 15.643 + InstanceKlass* klass, GrowableArray<Method*>* mirandas, TRAPS) { 15.644 + 15.645 + assert(klass != NULL, "Must be valid class"); 15.646 + 15.647 + GrowableArray<EmptyVtableSlot*>* slots = new GrowableArray<EmptyVtableSlot*>(); 15.648 + 15.649 + // All miranda methods are obvious candidates 15.650 + for (int i = 0; i < mirandas->length(); ++i) { 15.651 + EmptyVtableSlot* slot = new EmptyVtableSlot(mirandas->at(i)); 15.652 + slots->append(slot); 15.653 + } 15.654 + 15.655 + // Also any overpasses in our superclasses, that we haven't implemented. 15.656 + // (can't use the vtable because it is not guaranteed to be initialized yet) 15.657 + InstanceKlass* super = klass->java_super(); 15.658 + while (super != NULL) { 15.659 + for (int i = 0; i < super->methods()->length(); ++i) { 15.660 + Method* m = super->methods()->at(i); 15.661 + if (m->is_overpass()) { 15.662 + // m is a method that would have been a miranda if not for the 15.663 + // default method processing that occurred on behalf of our superclass, 15.664 + // so it's a method we want to re-examine in this new context. That is, 15.665 + // unless we have a real implementation of it in the current class. 15.666 + Method* impl = klass->lookup_method(m->name(), m->signature()); 15.667 + if (impl == NULL || impl->is_overpass()) { 15.668 + slots->append(new EmptyVtableSlot(m)); 15.669 + } 15.670 + } 15.671 + } 15.672 + super = super->java_super(); 15.673 + } 15.674 + 15.675 +#ifndef PRODUCT 15.676 + if (TraceDefaultMethods) { 15.677 + tty->print_cr("Slots that need filling:"); 15.678 + streamIndentor si(tty); 15.679 + for (int i = 0; i < slots->length(); ++i) { 15.680 + tty->indent(); 15.681 + slots->at(i)->print_on(tty); 15.682 + tty->print_cr(""); 15.683 + } 15.684 + } 15.685 +#endif // ndef PRODUCT 15.686 + return slots; 15.687 +} 15.688 + 15.689 +// Iterates over the type hierarchy looking for all methods with a specific 15.690 +// method name. The result of this is a set of method families each of 15.691 +// which is populated with a set of methods that implement the same 15.692 +// language-level signature. 15.693 +class FindMethodsByName : public HierarchyVisitor<FindMethodsByName> { 15.694 + private: 15.695 + // Context data 15.696 + Thread* THREAD; 15.697 + generic::DescriptorCache* _cache; 15.698 + Symbol* _method_name; 15.699 + generic::Context* _ctx; 15.700 + StatefulMethodFamilies _families; 15.701 + 15.702 + public: 15.703 + 15.704 + FindMethodsByName(generic::DescriptorCache* cache, Symbol* name, 15.705 + generic::Context* ctx, Thread* thread) : 15.706 + _cache(cache), _method_name(name), _ctx(ctx), THREAD(thread) {} 15.707 + 15.708 + void get_discovered_families(GrowableArray<MethodFamily*>* methods) { 15.709 + _families.extract_families_into(methods); 15.710 + } 15.711 + 15.712 + void* new_node_data(InstanceKlass* cls) { return new PseudoScope(); } 15.713 + void free_node_data(void* node_data) { 15.714 + PseudoScope::cast(node_data)->destroy(); 15.715 + } 15.716 + 15.717 + bool visit() { 15.718 + PseudoScope* scope = PseudoScope::cast(current_data()); 15.719 + InstanceKlass* klass = current_class(); 15.720 + InstanceKlass* sub = current_depth() > 0 ? class_at_depth(1) : NULL; 15.721 + 15.722 + ContextMark* cm = new ContextMark(_ctx->mark()); 15.723 + scope->add_mark(cm); // will restore context when scope is freed 15.724 + 15.725 + _ctx->apply_type_arguments(sub, klass, THREAD); 15.726 + 15.727 + int start, end = 0; 15.728 + start = klass->find_method_by_name(_method_name, &end); 15.729 + if (start != -1) { 15.730 + for (int i = start; i < end; ++i) { 15.731 + Method* m = klass->methods()->at(i); 15.732 + // This gets the method's parameter list with its generic type 15.733 + // parameters resolved 15.734 + generic::MethodDescriptor* md = _cache->descriptor_for(m, THREAD); 15.735 + 15.736 + // Find all methods on this hierarchy that match this method 15.737 + // (name, signature). This class collects other families of this 15.738 + // method name. 15.739 + StatefulMethodFamily* family = 15.740 + _families.find_matching_or_create(md, _ctx); 15.741 + 15.742 + if (klass->is_interface()) { 15.743 + // ??? 15.744 + StateRestorer* restorer = family->record_method_and_dq_further(m); 15.745 + scope->add_mark(restorer); 15.746 + } else { 15.747 + // This is the rule that methods in classes "win" (bad word) over 15.748 + // methods in interfaces. This works because of single inheritance 15.749 + family->set_target_if_empty(m); 15.750 + } 15.751 + } 15.752 + } 15.753 + return true; 15.754 + } 15.755 +}; 15.756 + 15.757 +#ifndef PRODUCT 15.758 +static void print_families( 15.759 + GrowableArray<MethodFamily*>* methods, Symbol* match) { 15.760 + streamIndentor si(tty, 4); 15.761 + if (methods->length() == 0) { 15.762 + tty->indent(); 15.763 + tty->print_cr("No Logical Method found"); 15.764 + } 15.765 + for (int i = 0; i < methods->length(); ++i) { 15.766 + tty->indent(); 15.767 + MethodFamily* lm = methods->at(i); 15.768 + if (lm->contains_signature(match)) { 15.769 + tty->print_cr("<Matching>"); 15.770 + } else { 15.771 + tty->print_cr("<Non-Matching>"); 15.772 + } 15.773 + lm->print_on(tty, 1); 15.774 + } 15.775 +} 15.776 +#endif // ndef PRODUCT 15.777 + 15.778 +static void merge_in_new_methods(InstanceKlass* klass, 15.779 + GrowableArray<Method*>* new_methods, TRAPS); 15.780 +static void create_overpasses( 15.781 + GrowableArray<EmptyVtableSlot*>* slots, InstanceKlass* klass, TRAPS); 15.782 + 15.783 +// This is the guts of the default methods implementation. This is called just 15.784 +// after the classfile has been parsed if some ancestor has default methods. 15.785 +// 15.786 +// First if finds any name/signature slots that need any implementation (either 15.787 +// because they are miranda or a superclass's implementation is an overpass 15.788 +// itself). For each slot, iterate over the hierarchy, using generic signature 15.789 +// information to partition any methods that match the name into method families 15.790 +// where each family contains methods whose signatures are equivalent at the 15.791 +// language level (i.e., their reified parameters match and return values are 15.792 +// covariant). Check those sets to see if they contain a signature that matches 15.793 +// the slot we're looking at (if we're lucky, there might be other empty slots 15.794 +// that we can fill using the same analysis). 15.795 +// 15.796 +// For each slot filled, we generate an overpass method that either calls the 15.797 +// unique default method candidate using invokespecial, or throws an exception 15.798 +// (in the case of no default method candidates, or more than one valid 15.799 +// candidate). These methods are then added to the class's method list. If 15.800 +// the method set we're using contains methods (qualified or not) with a 15.801 +// different runtime signature than the method we're creating, then we have to 15.802 +// create bridges with those signatures too. 15.803 +void DefaultMethods::generate_default_methods( 15.804 + InstanceKlass* klass, GrowableArray<Method*>* mirandas, TRAPS) { 15.805 + 15.806 + // This resource mark is the bound for all memory allocation that takes 15.807 + // place during default method processing. After this goes out of scope, 15.808 + // all (Resource) objects' memory will be reclaimed. Be careful if adding an 15.809 + // embedded resource mark under here as that memory can't be used outside 15.810 + // whatever scope it's in. 15.811 + ResourceMark rm(THREAD); 15.812 + 15.813 + generic::DescriptorCache cache; 15.814 + 15.815 + // Keep entire hierarchy alive for the duration of the computation 15.816 + KeepAliveRegistrar keepAlive(THREAD); 15.817 + KeepAliveVisitor loadKeepAlive(&keepAlive); 15.818 + loadKeepAlive.run(klass); 15.819 + 15.820 +#ifndef PRODUCT 15.821 + if (TraceDefaultMethods) { 15.822 + ResourceMark rm; // be careful with these! 15.823 + tty->print_cr("Class %s requires default method processing", 15.824 + klass->name()->as_klass_external_name()); 15.825 + PrintHierarchy printer; 15.826 + printer.run(klass); 15.827 + } 15.828 +#endif // ndef PRODUCT 15.829 + 15.830 + GrowableArray<EmptyVtableSlot*>* empty_slots = 15.831 + find_empty_vtable_slots(klass, mirandas, CHECK); 15.832 + 15.833 + for (int i = 0; i < empty_slots->length(); ++i) { 15.834 + EmptyVtableSlot* slot = empty_slots->at(i); 15.835 +#ifndef PRODUCT 15.836 + if (TraceDefaultMethods) { 15.837 + streamIndentor si(tty, 2); 15.838 + tty->indent().print("Looking for default methods for slot "); 15.839 + slot->print_on(tty); 15.840 + tty->print_cr(""); 15.841 + } 15.842 +#endif // ndef PRODUCT 15.843 + if (slot->is_bound()) { 15.844 +#ifndef PRODUCT 15.845 + if (TraceDefaultMethods) { 15.846 + streamIndentor si(tty, 4); 15.847 + tty->indent().print_cr("Already bound to logical method:"); 15.848 + slot->get_binding()->print_on(tty, 1); 15.849 + } 15.850 +#endif // ndef PRODUCT 15.851 + continue; // covered by previous processing 15.852 + } 15.853 + 15.854 + generic::Context ctx(&cache); 15.855 + FindMethodsByName visitor(&cache, slot->name(), &ctx, CHECK); 15.856 + visitor.run(klass); 15.857 + 15.858 + GrowableArray<MethodFamily*> discovered_families; 15.859 + visitor.get_discovered_families(&discovered_families); 15.860 + 15.861 +#ifndef PRODUCT 15.862 + if (TraceDefaultMethods) { 15.863 + print_families(&discovered_families, slot->signature()); 15.864 + } 15.865 +#endif // ndef PRODUCT 15.866 + 15.867 + // Find and populate any other slots that match the discovered families 15.868 + for (int j = i; j < empty_slots->length(); ++j) { 15.869 + EmptyVtableSlot* open_slot = empty_slots->at(j); 15.870 + 15.871 + if (slot->name() == open_slot->name()) { 15.872 + for (int k = 0; k < discovered_families.length(); ++k) { 15.873 + MethodFamily* lm = discovered_families.at(k); 15.874 + 15.875 + if (lm->contains_signature(open_slot->signature())) { 15.876 + lm->determine_target(klass, CHECK); 15.877 + open_slot->bind_family(lm); 15.878 + } 15.879 + } 15.880 + } 15.881 + } 15.882 + } 15.883 + 15.884 +#ifndef PRODUCT 15.885 + if (TraceDefaultMethods) { 15.886 + tty->print_cr("Creating overpasses..."); 15.887 + } 15.888 +#endif // ndef PRODUCT 15.889 + 15.890 + create_overpasses(empty_slots, klass, CHECK); 15.891 + 15.892 +#ifndef PRODUCT 15.893 + if (TraceDefaultMethods) { 15.894 + tty->print_cr("Default method processing complete"); 15.895 + } 15.896 +#endif // ndef PRODUCT 15.897 +} 15.898 + 15.899 + 15.900 +/** 15.901 + * Generic analysis was used upon interface '_target' and found a unique 15.902 + * default method candidate with generic signature '_method_desc'. This 15.903 + * method is only viable if it would also be in the set of default method 15.904 + * candidates if we ran a full analysis on the current class. 15.905 + * 15.906 + * The only reason that the method would not be in the set of candidates for 15.907 + * the current class is if that there's another covariantly matching method 15.908 + * which is "more specific" than the found method -- i.e., one could find a 15.909 + * path in the interface hierarchy in which the matching method appears 15.910 + * before we get to '_target'. 15.911 + * 15.912 + * In order to determine this, we examine all of the implemented 15.913 + * interfaces. If we find path that leads to the '_target' interface, then 15.914 + * we examine that path to see if there are any methods that would shadow 15.915 + * the selected method along that path. 15.916 + */ 15.917 +class ShadowChecker : public HierarchyVisitor<ShadowChecker> { 15.918 + private: 15.919 + generic::DescriptorCache* _cache; 15.920 + Thread* THREAD; 15.921 + 15.922 + InstanceKlass* _target; 15.923 + 15.924 + Symbol* _method_name; 15.925 + InstanceKlass* _method_holder; 15.926 + generic::MethodDescriptor* _method_desc; 15.927 + bool _found_shadow; 15.928 + 15.929 + bool path_has_shadow() { 15.930 + generic::Context ctx(_cache); 15.931 + 15.932 + for (int i = current_depth() - 1; i > 0; --i) { 15.933 + InstanceKlass* ik = class_at_depth(i); 15.934 + InstanceKlass* sub = class_at_depth(i + 1); 15.935 + ctx.apply_type_arguments(sub, ik, THREAD); 15.936 + 15.937 + if (ik->is_interface()) { 15.938 + int end; 15.939 + int start = ik->find_method_by_name(_method_name, &end); 15.940 + if (start != -1) { 15.941 + for (int j = start; j < end; ++j) { 15.942 + Method* mo = ik->methods()->at(j); 15.943 + generic::MethodDescriptor* md = _cache->descriptor_for(mo, THREAD); 15.944 + if (_method_desc->covariant_match(md, &ctx)) { 15.945 + return true; 15.946 + } 15.947 + } 15.948 + } 15.949 + } 15.950 + } 15.951 + return false; 15.952 + } 15.953 + 15.954 + public: 15.955 + 15.956 + ShadowChecker(generic::DescriptorCache* cache, Thread* thread, 15.957 + Symbol* name, InstanceKlass* holder, generic::MethodDescriptor* desc, 15.958 + InstanceKlass* target) 15.959 + : _cache(cache), THREAD(thread), _method_name(name), _method_holder(holder), 15.960 + _method_desc(desc), _target(target), _found_shadow(false) {} 15.961 + 15.962 + void* new_node_data(InstanceKlass* cls) { return NULL; } 15.963 + void free_node_data(void* data) { return; } 15.964 + 15.965 + bool visit() { 15.966 + InstanceKlass* ik = current_class(); 15.967 + if (ik == _target && current_depth() == 1) { 15.968 + return false; // This was the specified super -- no need to search it 15.969 + } 15.970 + if (ik == _method_holder || ik == _target) { 15.971 + // We found a path that should be examined to see if it shadows _method 15.972 + if (path_has_shadow()) { 15.973 + _found_shadow = true; 15.974 + cancel_iteration(); 15.975 + } 15.976 + return false; // no need to continue up hierarchy 15.977 + } 15.978 + return true; 15.979 + } 15.980 + 15.981 + bool found_shadow() { return _found_shadow; } 15.982 +}; 15.983 + 15.984 +// This is called during linktime when we find an invokespecial call that 15.985 +// refers to a direct superinterface. It indicates that we should find the 15.986 +// default method in the hierarchy of that superinterface, and if that method 15.987 +// would have been a candidate from the point of view of 'this' class, then we 15.988 +// return that method. 15.989 +Method* DefaultMethods::find_super_default( 15.990 + Klass* cls, Klass* super, Symbol* method_name, Symbol* sig, TRAPS) { 15.991 + 15.992 + ResourceMark rm(THREAD); 15.993 + 15.994 + assert(cls != NULL && super != NULL, "Need real classes"); 15.995 + 15.996 + InstanceKlass* current_class = InstanceKlass::cast(cls); 15.997 + InstanceKlass* direction = InstanceKlass::cast(super); 15.998 + 15.999 + // Keep entire hierarchy alive for the duration of the computation 15.1000 + KeepAliveRegistrar keepAlive(THREAD); 15.1001 + KeepAliveVisitor loadKeepAlive(&keepAlive); 15.1002 + loadKeepAlive.run(current_class); 15.1003 + 15.1004 +#ifndef PRODUCT 15.1005 + if (TraceDefaultMethods) { 15.1006 + tty->print_cr("Finding super default method %s.%s%s from %s", 15.1007 + direction->name()->as_C_string(), 15.1008 + method_name->as_C_string(), sig->as_C_string(), 15.1009 + current_class->name()->as_C_string()); 15.1010 + } 15.1011 +#endif // ndef PRODUCT 15.1012 + 15.1013 + if (!direction->is_interface()) { 15.1014 + // We should not be here 15.1015 + return NULL; 15.1016 + } 15.1017 + 15.1018 + generic::DescriptorCache cache; 15.1019 + generic::Context ctx(&cache); 15.1020 + 15.1021 + // Prime the initial generic context for current -> direction 15.1022 + ctx.apply_type_arguments(current_class, direction, CHECK_NULL); 15.1023 + 15.1024 + FindMethodsByName visitor(&cache, method_name, &ctx, CHECK_NULL); 15.1025 + visitor.run(direction); 15.1026 + 15.1027 + GrowableArray<MethodFamily*> families; 15.1028 + visitor.get_discovered_families(&families); 15.1029 + 15.1030 +#ifndef PRODUCT 15.1031 + if (TraceDefaultMethods) { 15.1032 + print_families(&families, sig); 15.1033 + } 15.1034 +#endif // ndef PRODUCT 15.1035 + 15.1036 + MethodFamily* selected_family = NULL; 15.1037 + 15.1038 + for (int i = 0; i < families.length(); ++i) { 15.1039 + MethodFamily* lm = families.at(i); 15.1040 + if (lm->contains_signature(sig)) { 15.1041 + lm->determine_target(current_class, CHECK_NULL); 15.1042 + selected_family = lm; 15.1043 + } 15.1044 + } 15.1045 + 15.1046 + if (selected_family->has_target()) { 15.1047 + Method* target = selected_family->get_selected_target(); 15.1048 + InstanceKlass* holder = InstanceKlass::cast(target->method_holder()); 15.1049 + 15.1050 + // Verify that the identified method is valid from the context of 15.1051 + // the current class 15.1052 + ShadowChecker checker(&cache, THREAD, target->name(), 15.1053 + holder, selected_family->descriptor(), direction); 15.1054 + checker.run(current_class); 15.1055 + 15.1056 + if (checker.found_shadow()) { 15.1057 +#ifndef PRODUCT 15.1058 + if (TraceDefaultMethods) { 15.1059 + tty->print_cr(" Only candidate found was shadowed."); 15.1060 + } 15.1061 +#endif // ndef PRODUCT 15.1062 + THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(), 15.1063 + "Accessible default method not found", NULL); 15.1064 + } else { 15.1065 +#ifndef PRODUCT 15.1066 + if (TraceDefaultMethods) { 15.1067 + tty->print(" Returning "); 15.1068 + print_method(tty, target, true); 15.1069 + tty->print_cr(""); 15.1070 + } 15.1071 +#endif // ndef PRODUCT 15.1072 + return target; 15.1073 + } 15.1074 + } else { 15.1075 + assert(selected_family->throws_exception(), "must have target or throw"); 15.1076 + THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(), 15.1077 + selected_family->get_exception_message()->as_C_string(), NULL); 15.1078 + } 15.1079 +} 15.1080 + 15.1081 + 15.1082 +static int assemble_redirect( 15.1083 + BytecodeConstantPool* cp, BytecodeBuffer* buffer, 15.1084 + Symbol* incoming, Method* target, TRAPS) { 15.1085 + 15.1086 + BytecodeAssembler assem(buffer, cp); 15.1087 + 15.1088 + SignatureStream in(incoming, true); 15.1089 + SignatureStream out(target->signature(), true); 15.1090 + u2 parameter_count = 0; 15.1091 + 15.1092 + assem.aload(parameter_count++); // load 'this' 15.1093 + 15.1094 + while (!in.at_return_type()) { 15.1095 + assert(!out.at_return_type(), "Parameter counts do not match"); 15.1096 + BasicType bt = in.type(); 15.1097 + assert(out.type() == bt, "Parameter types are not compatible"); 15.1098 + assem.load(bt, parameter_count); 15.1099 + if (in.is_object() && in.as_symbol(THREAD) != out.as_symbol(THREAD)) { 15.1100 + assem.checkcast(out.as_symbol(THREAD)); 15.1101 + } else if (bt == T_LONG || bt == T_DOUBLE) { 15.1102 + ++parameter_count; // longs and doubles use two slots 15.1103 + } 15.1104 + ++parameter_count; 15.1105 + in.next(); 15.1106 + out.next(); 15.1107 + } 15.1108 + assert(out.at_return_type(), "Parameter counts do not match"); 15.1109 + assert(in.type() == out.type(), "Return types are not compatible"); 15.1110 + 15.1111 + if (parameter_count == 1 && (in.type() == T_LONG || in.type() == T_DOUBLE)) { 15.1112 + ++parameter_count; // need room for return value 15.1113 + } 15.1114 + if (target->method_holder()->is_interface()) { 15.1115 + assem.invokespecial(target); 15.1116 + } else { 15.1117 + assem.invokevirtual(target); 15.1118 + } 15.1119 + 15.1120 + if (in.is_object() && in.as_symbol(THREAD) != out.as_symbol(THREAD)) { 15.1121 + assem.checkcast(in.as_symbol(THREAD)); 15.1122 + } 15.1123 + assem._return(in.type()); 15.1124 + return parameter_count; 15.1125 +} 15.1126 + 15.1127 +static int assemble_abstract_method_error( 15.1128 + BytecodeConstantPool* cp, BytecodeBuffer* buffer, Symbol* message, TRAPS) { 15.1129 + 15.1130 + Symbol* errorName = vmSymbols::java_lang_AbstractMethodError(); 15.1131 + Symbol* init = vmSymbols::object_initializer_name(); 15.1132 + Symbol* sig = vmSymbols::string_void_signature(); 15.1133 + 15.1134 + BytecodeAssembler assem(buffer, cp); 15.1135 + 15.1136 + assem._new(errorName); 15.1137 + assem.dup(); 15.1138 + assem.load_string(message); 15.1139 + assem.invokespecial(errorName, init, sig); 15.1140 + assem.athrow(); 15.1141 + 15.1142 + return 3; // max stack size: [ exception, exception, string ] 15.1143 +} 15.1144 + 15.1145 +static Method* new_method( 15.1146 + BytecodeConstantPool* cp, BytecodeBuffer* bytecodes, Symbol* name, 15.1147 + Symbol* sig, AccessFlags flags, int max_stack, int params, 15.1148 + ConstMethod::MethodType mt, TRAPS) { 15.1149 + 15.1150 + address code_start = static_cast<address>(bytecodes->adr_at(0)); 15.1151 + int code_length = bytecodes->length(); 15.1152 + 15.1153 + Method* m = Method::allocate(cp->pool_holder()->class_loader_data(), 15.1154 + code_length, flags, 0, 0, 0, 0, mt, CHECK_NULL); 15.1155 + 15.1156 + m->set_constants(NULL); // This will get filled in later 15.1157 + m->set_name_index(cp->utf8(name)); 15.1158 + m->set_signature_index(cp->utf8(sig)); 15.1159 + m->set_generic_signature_index(0); 15.1160 +#ifdef CC_INTERP 15.1161 + ResultTypeFinder rtf(sig); 15.1162 + m->set_result_index(rtf.type()); 15.1163 +#endif 15.1164 + m->set_size_of_parameters(params); 15.1165 + m->set_max_stack(max_stack); 15.1166 + m->set_max_locals(params); 15.1167 + m->constMethod()->set_stackmap_data(NULL); 15.1168 + m->set_code(code_start); 15.1169 + m->set_force_inline(true); 15.1170 + 15.1171 + return m; 15.1172 +} 15.1173 + 15.1174 +static void switchover_constant_pool(BytecodeConstantPool* bpool, 15.1175 + InstanceKlass* klass, GrowableArray<Method*>* new_methods, TRAPS) { 15.1176 + 15.1177 + if (new_methods->length() > 0) { 15.1178 + ConstantPool* cp = bpool->create_constant_pool(CHECK); 15.1179 + if (cp != klass->constants()) { 15.1180 + klass->class_loader_data()->add_to_deallocate_list(klass->constants()); 15.1181 + klass->set_constants(cp); 15.1182 + cp->set_pool_holder(klass); 15.1183 + 15.1184 + for (int i = 0; i < new_methods->length(); ++i) { 15.1185 + new_methods->at(i)->set_constants(cp); 15.1186 + } 15.1187 + for (int i = 0; i < klass->methods()->length(); ++i) { 15.1188 + Method* mo = klass->methods()->at(i); 15.1189 + mo->set_constants(cp); 15.1190 + } 15.1191 + } 15.1192 + } 15.1193 +} 15.1194 + 15.1195 +// A "bridge" is a method created by javac to bridge the gap between 15.1196 +// an implementation and a generically-compatible, but different, signature. 15.1197 +// Bridges have actual bytecode implementation in classfiles. 15.1198 +// An "overpass", on the other hand, performs the same function as a bridge 15.1199 +// but does not occur in a classfile; the VM creates overpass itself, 15.1200 +// when it needs a path to get from a call site to an default method, and 15.1201 +// a bridge doesn't exist. 15.1202 +static void create_overpasses( 15.1203 + GrowableArray<EmptyVtableSlot*>* slots, 15.1204 + InstanceKlass* klass, TRAPS) { 15.1205 + 15.1206 + GrowableArray<Method*> overpasses; 15.1207 + BytecodeConstantPool bpool(klass->constants()); 15.1208 + 15.1209 + for (int i = 0; i < slots->length(); ++i) { 15.1210 + EmptyVtableSlot* slot = slots->at(i); 15.1211 + 15.1212 + if (slot->is_bound()) { 15.1213 + MethodFamily* method = slot->get_binding(); 15.1214 + int max_stack = 0; 15.1215 + BytecodeBuffer buffer; 15.1216 + 15.1217 +#ifndef PRODUCT 15.1218 + if (TraceDefaultMethods) { 15.1219 + tty->print("for slot: "); 15.1220 + slot->print_on(tty); 15.1221 + tty->print_cr(""); 15.1222 + if (method->has_target()) { 15.1223 + method->print_selected(tty, 1); 15.1224 + } else { 15.1225 + method->print_exception(tty, 1); 15.1226 + } 15.1227 + } 15.1228 +#endif // ndef PRODUCT 15.1229 + if (method->has_target()) { 15.1230 + Method* selected = method->get_selected_target(); 15.1231 + max_stack = assemble_redirect( 15.1232 + &bpool, &buffer, slot->signature(), selected, CHECK); 15.1233 + } else if (method->throws_exception()) { 15.1234 + max_stack = assemble_abstract_method_error( 15.1235 + &bpool, &buffer, method->get_exception_message(), CHECK); 15.1236 + } 15.1237 + AccessFlags flags = accessFlags_from( 15.1238 + JVM_ACC_PUBLIC | JVM_ACC_SYNTHETIC | JVM_ACC_BRIDGE); 15.1239 + Method* m = new_method(&bpool, &buffer, slot->name(), slot->signature(), 15.1240 + flags, max_stack, slot->size_of_parameters(), 15.1241 + ConstMethod::OVERPASS, CHECK); 15.1242 + if (m != NULL) { 15.1243 + overpasses.push(m); 15.1244 + } 15.1245 + } 15.1246 + } 15.1247 + 15.1248 +#ifndef PRODUCT 15.1249 + if (TraceDefaultMethods) { 15.1250 + tty->print_cr("Created %d overpass methods", overpasses.length()); 15.1251 + } 15.1252 +#endif // ndef PRODUCT 15.1253 + 15.1254 + switchover_constant_pool(&bpool, klass, &overpasses, CHECK); 15.1255 + merge_in_new_methods(klass, &overpasses, CHECK); 15.1256 +} 15.1257 + 15.1258 +static void sort_methods(GrowableArray<Method*>* methods) { 15.1259 + // Note that this must sort using the same key as is used for sorting 15.1260 + // methods in InstanceKlass. 15.1261 + bool sorted = true; 15.1262 + for (int i = methods->length() - 1; i > 0; --i) { 15.1263 + for (int j = 0; j < i; ++j) { 15.1264 + Method* m1 = methods->at(j); 15.1265 + Method* m2 = methods->at(j + 1); 15.1266 + if ((uintptr_t)m1->name() > (uintptr_t)m2->name()) { 15.1267 + methods->at_put(j, m2); 15.1268 + methods->at_put(j + 1, m1); 15.1269 + sorted = false; 15.1270 + } 15.1271 + } 15.1272 + if (sorted) break; 15.1273 + sorted = true; 15.1274 + } 15.1275 +#ifdef ASSERT 15.1276 + uintptr_t prev = 0; 15.1277 + for (int i = 0; i < methods->length(); ++i) { 15.1278 + Method* mh = methods->at(i); 15.1279 + uintptr_t nv = (uintptr_t)mh->name(); 15.1280 + assert(nv >= prev, "Incorrect overpass method ordering"); 15.1281 + prev = nv; 15.1282 + } 15.1283 +#endif 15.1284 +} 15.1285 + 15.1286 +static void merge_in_new_methods(InstanceKlass* klass, 15.1287 + GrowableArray<Method*>* new_methods, TRAPS) { 15.1288 + 15.1289 + enum { ANNOTATIONS, PARAMETERS, DEFAULTS, NUM_ARRAYS }; 15.1290 + 15.1291 + Array<AnnotationArray*>* original_annots[NUM_ARRAYS]; 15.1292 + 15.1293 + Array<Method*>* original_methods = klass->methods(); 15.1294 + Annotations* annots = klass->annotations(); 15.1295 + original_annots[ANNOTATIONS] = annots->methods_annotations(); 15.1296 + original_annots[PARAMETERS] = annots->methods_parameter_annotations(); 15.1297 + original_annots[DEFAULTS] = annots->methods_default_annotations(); 15.1298 + 15.1299 + Array<int>* original_ordering = klass->method_ordering(); 15.1300 + Array<int>* merged_ordering = Universe::the_empty_int_array(); 15.1301 + 15.1302 + int new_size = klass->methods()->length() + new_methods->length(); 15.1303 + 15.1304 + Array<AnnotationArray*>* merged_annots[NUM_ARRAYS]; 15.1305 + 15.1306 + Array<Method*>* merged_methods = MetadataFactory::new_array<Method*>( 15.1307 + klass->class_loader_data(), new_size, NULL, CHECK); 15.1308 + for (int i = 0; i < NUM_ARRAYS; ++i) { 15.1309 + if (original_annots[i] != NULL) { 15.1310 + merged_annots[i] = MetadataFactory::new_array<AnnotationArray*>( 15.1311 + klass->class_loader_data(), new_size, CHECK); 15.1312 + } else { 15.1313 + merged_annots[i] = NULL; 15.1314 + } 15.1315 + } 15.1316 + if (original_ordering != NULL && original_ordering->length() > 0) { 15.1317 + merged_ordering = MetadataFactory::new_array<int>( 15.1318 + klass->class_loader_data(), new_size, CHECK); 15.1319 + } 15.1320 + int method_order_index = klass->methods()->length(); 15.1321 + 15.1322 + sort_methods(new_methods); 15.1323 + 15.1324 + // Perform grand merge of existing methods and new methods 15.1325 + int orig_idx = 0; 15.1326 + int new_idx = 0; 15.1327 + 15.1328 + for (int i = 0; i < new_size; ++i) { 15.1329 + Method* orig_method = NULL; 15.1330 + Method* new_method = NULL; 15.1331 + if (orig_idx < original_methods->length()) { 15.1332 + orig_method = original_methods->at(orig_idx); 15.1333 + } 15.1334 + if (new_idx < new_methods->length()) { 15.1335 + new_method = new_methods->at(new_idx); 15.1336 + } 15.1337 + 15.1338 + if (orig_method != NULL && 15.1339 + (new_method == NULL || orig_method->name() < new_method->name())) { 15.1340 + merged_methods->at_put(i, orig_method); 15.1341 + original_methods->at_put(orig_idx, NULL); 15.1342 + for (int j = 0; j < NUM_ARRAYS; ++j) { 15.1343 + if (merged_annots[j] != NULL) { 15.1344 + merged_annots[j]->at_put(i, original_annots[j]->at(orig_idx)); 15.1345 + original_annots[j]->at_put(orig_idx, NULL); 15.1346 + } 15.1347 + } 15.1348 + if (merged_ordering->length() > 0) { 15.1349 + merged_ordering->at_put(i, original_ordering->at(orig_idx)); 15.1350 + } 15.1351 + ++orig_idx; 15.1352 + } else { 15.1353 + merged_methods->at_put(i, new_method); 15.1354 + if (merged_ordering->length() > 0) { 15.1355 + merged_ordering->at_put(i, method_order_index++); 15.1356 + } 15.1357 + ++new_idx; 15.1358 + } 15.1359 + // update idnum for new location 15.1360 + merged_methods->at(i)->set_method_idnum(i); 15.1361 + } 15.1362 + 15.1363 + // Verify correct order 15.1364 +#ifdef ASSERT 15.1365 + uintptr_t prev = 0; 15.1366 + for (int i = 0; i < merged_methods->length(); ++i) { 15.1367 + Method* mo = merged_methods->at(i); 15.1368 + uintptr_t nv = (uintptr_t)mo->name(); 15.1369 + assert(nv >= prev, "Incorrect method ordering"); 15.1370 + prev = nv; 15.1371 + } 15.1372 +#endif 15.1373 + 15.1374 + // Replace klass methods with new merged lists 15.1375 + klass->set_methods(merged_methods); 15.1376 + annots->set_methods_annotations(merged_annots[ANNOTATIONS]); 15.1377 + annots->set_methods_parameter_annotations(merged_annots[PARAMETERS]); 15.1378 + annots->set_methods_default_annotations(merged_annots[DEFAULTS]); 15.1379 + 15.1380 + ClassLoaderData* cld = klass->class_loader_data(); 15.1381 + MetadataFactory::free_array(cld, original_methods); 15.1382 + for (int i = 0; i < NUM_ARRAYS; ++i) { 15.1383 + MetadataFactory::free_array(cld, original_annots[i]); 15.1384 + } 15.1385 + if (original_ordering->length() > 0) { 15.1386 + klass->set_method_ordering(merged_ordering); 15.1387 + MetadataFactory::free_array(cld, original_ordering); 15.1388 + } 15.1389 +} 15.1390 +
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 16.2 +++ b/src/share/vm/classfile/defaultMethods.hpp Wed Nov 07 16:09:20 2012 -0800 16.3 @@ -0,0 +1,58 @@ 16.4 +/* 16.5 + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. 16.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 16.7 + * 16.8 + * This code is free software; you can redistribute it and/or modify it 16.9 + * under the terms of the GNU General Public License version 2 only, as 16.10 + * published by the Free Software Foundation. 16.11 + * 16.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 16.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16.15 + * version 2 for more details (a copy is included in the LICENSE file that 16.16 + * accompanied this code). 16.17 + * 16.18 + * You should have received a copy of the GNU General Public License version 16.19 + * 2 along with this work; if not, write to the Free Software Foundation, 16.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 16.21 + * 16.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 16.23 + * or visit www.oracle.com if you need additional information or have any 16.24 + * questions. 16.25 + * 16.26 + */ 16.27 + 16.28 +#ifndef SHARE_VM_CLASSFILE_DEFAULTMETHODS_HPP 16.29 +#define SHARE_VM_CLASSFILE_DEFAULTMETHODS_HPP 16.30 + 16.31 +#include "runtime/handles.hpp" 16.32 +#include "utilities/growableArray.hpp" 16.33 +#include "utilities/exceptions.hpp" 16.34 + 16.35 +class InstanceKlass; 16.36 +class Symbol; 16.37 +class Method; 16.38 + 16.39 +class DefaultMethods : AllStatic { 16.40 + public: 16.41 + 16.42 + // Analyzes class and determines which default methods are inherited 16.43 + // from interfaces (and has no other implementation). For each method 16.44 + // (and each different signature the method could have), create an 16.45 + // "overpass" method that is an instance method that redirects to the 16.46 + // default method. Overpass methods are added to the methods lists for 16.47 + // the class. 16.48 + static void generate_default_methods( 16.49 + InstanceKlass* klass, GrowableArray<Method*>* mirandas, TRAPS); 16.50 + 16.51 + 16.52 + // Called during linking when an invokespecial to an direct interface 16.53 + // method is found. Selects and returns a method if there is a unique 16.54 + // default method in the 'super_iface' part of the hierarchy which is 16.55 + // also a candidate default for 'this_klass'. Otherwise throws an AME. 16.56 + static Method* find_super_default( 16.57 + Klass* this_klass, Klass* super_iface, 16.58 + Symbol* method_name, Symbol* method_sig, TRAPS); 16.59 +}; 16.60 + 16.61 +#endif // SHARE_VM_CLASSFILE_DEFAULTMETHODS_HPP
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 17.2 +++ b/src/share/vm/classfile/genericSignatures.cpp Wed Nov 07 16:09:20 2012 -0800 17.3 @@ -0,0 +1,1272 @@ 17.4 +/* 17.5 + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. 17.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 17.7 + * 17.8 + * This code is free software; you can redistribute it and/or modify it 17.9 + * under the terms of the GNU General Public License version 2 only, as 17.10 + * published by the Free Software Foundation. 17.11 + * 17.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 17.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 17.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17.15 + * version 2 for more details (a copy is included in the LICENSE file that 17.16 + * accompanied this code). 17.17 + * 17.18 + * You should have received a copy of the GNU General Public License version 17.19 + * 2 along with this work; if not, write to the Free Software Foundation, 17.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17.21 + * 17.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 17.23 + * or visit www.oracle.com if you need additional information or have any 17.24 + * questions. 17.25 + * 17.26 + */ 17.27 + 17.28 +#include "precompiled.hpp" 17.29 + 17.30 +#include "classfile/genericSignatures.hpp" 17.31 +#include "classfile/symbolTable.hpp" 17.32 +#include "classfile/systemDictionary.hpp" 17.33 +#include "memory/resourceArea.hpp" 17.34 + 17.35 +namespace generic { 17.36 + 17.37 +// Helper class for parsing the generic signature Symbol in klass and methods 17.38 +class DescriptorStream : public ResourceObj { 17.39 + private: 17.40 + Symbol* _symbol; 17.41 + int _offset; 17.42 + int _mark; 17.43 + const char* _parse_error; 17.44 + 17.45 + void set_parse_error(const char* error) { 17.46 + assert(error != NULL, "Can't set NULL error string"); 17.47 + _parse_error = error; 17.48 + } 17.49 + 17.50 + public: 17.51 + DescriptorStream(Symbol* sym) 17.52 + : _symbol(sym), _offset(0), _mark(-1), _parse_error(NULL) {} 17.53 + 17.54 + const char* parse_error() const { 17.55 + return _parse_error; 17.56 + } 17.57 + 17.58 + bool at_end() { return _offset >= _symbol->utf8_length(); } 17.59 + 17.60 + char peek() { 17.61 + if (at_end()) { 17.62 + set_parse_error("Peeking past end of signature"); 17.63 + return '\0'; 17.64 + } else { 17.65 + return _symbol->byte_at(_offset); 17.66 + } 17.67 + } 17.68 + 17.69 + char read() { 17.70 + if (at_end()) { 17.71 + set_parse_error("Reading past end of signature"); 17.72 + return '\0'; 17.73 + } else { 17.74 + return _symbol->byte_at(_offset++); 17.75 + } 17.76 + } 17.77 + 17.78 + void read(char expected) { 17.79 + char c = read(); 17.80 + assert_char(c, expected, 0); 17.81 + } 17.82 + 17.83 + void assert_char(char c, char expected, int pos = -1) { 17.84 + if (c != expected) { 17.85 + const char* fmt = "Parse error at %d: expected %c but got %c"; 17.86 + size_t len = strlen(fmt) + 5; 17.87 + char* buffer = NEW_RESOURCE_ARRAY(char, len); 17.88 + jio_snprintf(buffer, len, fmt, _offset + pos, expected, c); 17.89 + set_parse_error(buffer); 17.90 + } 17.91 + } 17.92 + 17.93 + void push(char c) { 17.94 + assert(c == _symbol->byte_at(_offset - 1), "Pushing back wrong value"); 17.95 + --_offset; 17.96 + } 17.97 + 17.98 + void expect_end() { 17.99 + if (!at_end()) { 17.100 + set_parse_error("Unexpected data trailing signature"); 17.101 + } 17.102 + } 17.103 + 17.104 + bool has_mark() { return _mark != -1; } 17.105 + 17.106 + void set_mark() { 17.107 + _mark = _offset; 17.108 + } 17.109 + 17.110 + Identifier* identifier_from_mark() { 17.111 + assert(has_mark(), "Mark should be set"); 17.112 + if (!has_mark()) { 17.113 + set_parse_error("Expected mark to be set"); 17.114 + return NULL; 17.115 + } else { 17.116 + Identifier* id = new Identifier(_symbol, _mark, _offset - 1); 17.117 + _mark = -1; 17.118 + return id; 17.119 + } 17.120 + } 17.121 +}; 17.122 + 17.123 + 17.124 +#define CHECK_FOR_PARSE_ERROR() \ 17.125 + if (STREAM->parse_error() != NULL) { \ 17.126 + if (VerifyGenericSignatures) { \ 17.127 + fatal(STREAM->parse_error()); \ 17.128 + } \ 17.129 + return NULL; \ 17.130 + } 0 17.131 + 17.132 +#define READ() STREAM->read(); CHECK_FOR_PARSE_ERROR() 17.133 +#define PEEK() STREAM->peek(); CHECK_FOR_PARSE_ERROR() 17.134 +#define PUSH(c) STREAM->push(c) 17.135 +#define EXPECT(c) STREAM->read(c); CHECK_FOR_PARSE_ERROR() 17.136 +#define EXPECTED(c, ch) STREAM->assert_char(c, ch); CHECK_FOR_PARSE_ERROR() 17.137 +#define EXPECT_END() STREAM->expect_end(); CHECK_FOR_PARSE_ERROR() 17.138 + 17.139 +#define CHECK_STREAM STREAM); CHECK_FOR_PARSE_ERROR(); (0 17.140 + 17.141 +#ifndef PRODUCT 17.142 +void Identifier::print_on(outputStream* str) const { 17.143 + for (int i = _begin; i < _end; ++i) { 17.144 + str->print("%c", (char)_sym->byte_at(i)); 17.145 + } 17.146 +} 17.147 +#endif // ndef PRODUCT 17.148 + 17.149 +bool Identifier::equals(Identifier* other) { 17.150 + if (_sym == other->_sym && _begin == other->_begin && _end == other->_end) { 17.151 + return true; 17.152 + } else if (_end - _begin != other->_end - other->_begin) { 17.153 + return false; 17.154 + } else { 17.155 + size_t len = _end - _begin; 17.156 + char* addr = ((char*)_sym->bytes()) + _begin; 17.157 + char* oaddr = ((char*)other->_sym->bytes()) + other->_begin; 17.158 + return strncmp(addr, oaddr, len) == 0; 17.159 + } 17.160 +} 17.161 + 17.162 +bool Identifier::equals(Symbol* sym) { 17.163 + Identifier id(sym, 0, sym->utf8_length()); 17.164 + return equals(&id); 17.165 +} 17.166 + 17.167 +/** 17.168 + * A formal type parameter may be found in the the enclosing class, but it could 17.169 + * also come from an enclosing method or outer class, in the case of inner-outer 17.170 + * classes or anonymous classes. For example: 17.171 + * 17.172 + * class Outer<T,V> { 17.173 + * class Inner<W> { 17.174 + * void m(T t, V v, W w); 17.175 + * } 17.176 + * } 17.177 + * 17.178 + * In this case, the type variables in m()'s signature are not all found in the 17.179 + * immediate enclosing class (Inner). class Inner has only type parameter W, 17.180 + * but it's outer_class field will reference Outer's descriptor which contains 17.181 + * T & V (no outer_method in this case). 17.182 + * 17.183 + * If you have an anonymous class, it has both an enclosing method *and* an 17.184 + * enclosing class where type parameters can be declared: 17.185 + * 17.186 + * class MOuter<T> { 17.187 + * <V> void bar(V v) { 17.188 + * Runnable r = new Runnable() { 17.189 + * public void run() {} 17.190 + * public void foo(T t, V v) { ... } 17.191 + * }; 17.192 + * } 17.193 + * } 17.194 + * 17.195 + * In this case, foo will be a member of some class, Runnable$1, which has no 17.196 + * formal parameters itself, but has an outer_method (bar()) which provides 17.197 + * type parameter V, and an outer class MOuter with type parameter T. 17.198 + * 17.199 + * It is also possible that the outer class is itself an inner class to some 17.200 + * other class (or an anonymous class with an enclosing method), so we need to 17.201 + * follow the outer_class/outer_method chain to it's end when looking for a 17.202 + * type parameter. 17.203 + */ 17.204 +TypeParameter* Descriptor::find_type_parameter(Identifier* id, int* depth) { 17.205 + 17.206 + int current_depth = 0; 17.207 + 17.208 + MethodDescriptor* outer_method = as_method_signature(); 17.209 + ClassDescriptor* outer_class = as_class_signature(); 17.210 + 17.211 + if (outer_class == NULL) { // 'this' is a method signature; use the holder 17.212 + outer_class = outer_method->outer_class(); 17.213 + } 17.214 + 17.215 + while (outer_method != NULL || outer_class != NULL) { 17.216 + if (outer_method != NULL) { 17.217 + for (int i = 0; i < outer_method->type_parameters().length(); ++i) { 17.218 + TypeParameter* p = outer_method->type_parameters().at(i); 17.219 + if (p->identifier()->equals(id)) { 17.220 + *depth = -1; // indicates this this is a method parameter 17.221 + return p; 17.222 + } 17.223 + } 17.224 + } 17.225 + if (outer_class != NULL) { 17.226 + for (int i = 0; i < outer_class->type_parameters().length(); ++i) { 17.227 + TypeParameter* p = outer_class->type_parameters().at(i); 17.228 + if (p->identifier()->equals(id)) { 17.229 + *depth = current_depth; 17.230 + return p; 17.231 + } 17.232 + } 17.233 + outer_method = outer_class->outer_method(); 17.234 + outer_class = outer_class->outer_class(); 17.235 + ++current_depth; 17.236 + } 17.237 + } 17.238 + 17.239 + if (VerifyGenericSignatures) { 17.240 + fatal("Could not resolve identifier"); 17.241 + } 17.242 + 17.243 + return NULL; 17.244 +} 17.245 + 17.246 +ClassDescriptor* ClassDescriptor::parse_generic_signature(Klass* klass, TRAPS) { 17.247 + return parse_generic_signature(klass, NULL, CHECK_NULL); 17.248 +} 17.249 + 17.250 +ClassDescriptor* ClassDescriptor::parse_generic_signature( 17.251 + Klass* klass, Symbol* original_name, TRAPS) { 17.252 + 17.253 + InstanceKlass* ik = InstanceKlass::cast(klass); 17.254 + Symbol* sym = ik->generic_signature(); 17.255 + 17.256 + ClassDescriptor* spec; 17.257 + 17.258 + if (sym == NULL || (spec = ClassDescriptor::parse_generic_signature(sym)) == NULL) { 17.259 + spec = ClassDescriptor::placeholder(ik); 17.260 + } 17.261 + 17.262 + u2 outer_index = get_outer_class_index(ik, CHECK_NULL); 17.263 + if (outer_index != 0) { 17.264 + if (original_name == NULL) { 17.265 + original_name = ik->name(); 17.266 + } 17.267 + Handle class_loader = Handle(THREAD, ik->class_loader()); 17.268 + Handle protection_domain = Handle(THREAD, ik->protection_domain()); 17.269 + 17.270 + Symbol* outer_name = ik->constants()->klass_name_at(outer_index); 17.271 + Klass* outer = SystemDictionary::find( 17.272 + outer_name, class_loader, protection_domain, CHECK_NULL); 17.273 + if (outer == NULL && !THREAD->is_Compiler_thread()) { 17.274 + outer = SystemDictionary::resolve_super_or_fail(original_name, 17.275 + outer_name, class_loader, protection_domain, false, CHECK_NULL); 17.276 + } 17.277 + 17.278 + InstanceKlass* outer_ik; 17.279 + ClassDescriptor* outer_spec = NULL; 17.280 + if (outer == NULL) { 17.281 + outer_spec = ClassDescriptor::placeholder(ik); 17.282 + assert(false, "Outer class not loaded and not loadable from here"); 17.283 + } else { 17.284 + outer_ik = InstanceKlass::cast(outer); 17.285 + outer_spec = parse_generic_signature(outer, original_name, CHECK_NULL); 17.286 + } 17.287 + spec->set_outer_class(outer_spec); 17.288 + 17.289 + u2 encl_method_idx = ik->enclosing_method_method_index(); 17.290 + if (encl_method_idx != 0 && outer_ik != NULL) { 17.291 + ConstantPool* cp = ik->constants(); 17.292 + u2 name_index = cp->name_ref_index_at(encl_method_idx); 17.293 + u2 sig_index = cp->signature_ref_index_at(encl_method_idx); 17.294 + Symbol* name = cp->symbol_at(name_index); 17.295 + Symbol* sig = cp->symbol_at(sig_index); 17.296 + Method* m = outer_ik->find_method(name, sig); 17.297 + if (m != NULL) { 17.298 + Symbol* gsig = m->generic_signature(); 17.299 + if (gsig != NULL) { 17.300 + MethodDescriptor* gms = MethodDescriptor::parse_generic_signature(gsig, outer_spec); 17.301 + spec->set_outer_method(gms); 17.302 + } 17.303 + } else if (VerifyGenericSignatures) { 17.304 + ResourceMark rm; 17.305 + stringStream ss; 17.306 + ss.print("Could not find method %s %s in class %s", 17.307 + name->as_C_string(), sig->as_C_string(), outer_name->as_C_string()); 17.308 + fatal(ss.as_string()); 17.309 + } 17.310 + } 17.311 + } 17.312 + 17.313 + spec->bind_variables_to_parameters(); 17.314 + return spec; 17.315 +} 17.316 + 17.317 +ClassDescriptor* ClassDescriptor::placeholder(InstanceKlass* klass) { 17.318 + GrowableArray<TypeParameter*> formals; 17.319 + GrowableArray<ClassType*> interfaces; 17.320 + ClassType* super_type = NULL; 17.321 + 17.322 + Klass* super_klass = klass->super(); 17.323 + if (super_klass != NULL) { 17.324 + InstanceKlass* super = InstanceKlass::cast(super_klass); 17.325 + super_type = ClassType::from_symbol(super->name()); 17.326 + } 17.327 + 17.328 + for (int i = 0; i < klass->local_interfaces()->length(); ++i) { 17.329 + InstanceKlass* iface = InstanceKlass::cast(klass->local_interfaces()->at(i)); 17.330 + interfaces.append(ClassType::from_symbol(iface->name())); 17.331 + } 17.332 + return new ClassDescriptor(formals, super_type, interfaces); 17.333 +} 17.334 + 17.335 +ClassDescriptor* ClassDescriptor::parse_generic_signature(Symbol* sym) { 17.336 + 17.337 + DescriptorStream ds(sym); 17.338 + DescriptorStream* STREAM = &ds; 17.339 + 17.340 + GrowableArray<TypeParameter*> parameters(8); 17.341 + char c = READ(); 17.342 + if (c == '<') { 17.343 + c = READ(); 17.344 + while (c != '>') { 17.345 + PUSH(c); 17.346 + TypeParameter* ftp = TypeParameter::parse_generic_signature(CHECK_STREAM); 17.347 + parameters.append(ftp); 17.348 + c = READ(); 17.349 + } 17.350 + } else { 17.351 + PUSH(c); 17.352 + } 17.353 + 17.354 + EXPECT('L'); 17.355 + ClassType* super = ClassType::parse_generic_signature(CHECK_STREAM); 17.356 + 17.357 + GrowableArray<ClassType*> signatures(2); 17.358 + while (!STREAM->at_end()) { 17.359 + EXPECT('L'); 17.360 + ClassType* iface = ClassType::parse_generic_signature(CHECK_STREAM); 17.361 + signatures.append(iface); 17.362 + } 17.363 + 17.364 + EXPECT_END(); 17.365 + 17.366 + return new ClassDescriptor(parameters, super, signatures); 17.367 +} 17.368 + 17.369 +#ifndef PRODUCT 17.370 +void ClassDescriptor::print_on(outputStream* str) const { 17.371 + str->indent().print_cr("ClassDescriptor {"); 17.372 + { 17.373 + streamIndentor si(str); 17.374 + if (_type_parameters.length() > 0) { 17.375 + str->indent().print_cr("Formals {"); 17.376 + { 17.377 + streamIndentor si(str); 17.378 + for (int i = 0; i < _type_parameters.length(); ++i) { 17.379 + _type_parameters.at(i)->print_on(str); 17.380 + } 17.381 + } 17.382 + str->indent().print_cr("}"); 17.383 + } 17.384 + if (_super != NULL) { 17.385 + str->indent().print_cr("Superclass: "); 17.386 + { 17.387 + streamIndentor si(str); 17.388 + _super->print_on(str); 17.389 + } 17.390 + } 17.391 + if (_interfaces.length() > 0) { 17.392 + str->indent().print_cr("SuperInterfaces: {"); 17.393 + { 17.394 + streamIndentor si(str); 17.395 + for (int i = 0; i < _interfaces.length(); ++i) { 17.396 + _interfaces.at(i)->print_on(str); 17.397 + } 17.398 + } 17.399 + str->indent().print_cr("}"); 17.400 + } 17.401 + if (_outer_method != NULL) { 17.402 + str->indent().print_cr("Outer Method: {"); 17.403 + { 17.404 + streamIndentor si(str); 17.405 + _outer_method->print_on(str); 17.406 + } 17.407 + str->indent().print_cr("}"); 17.408 + } 17.409 + if (_outer_class != NULL) { 17.410 + str->indent().print_cr("Outer Class: {"); 17.411 + { 17.412 + streamIndentor si(str); 17.413 + _outer_class->print_on(str); 17.414 + } 17.415 + str->indent().print_cr("}"); 17.416 + } 17.417 + } 17.418 + str->indent().print_cr("}"); 17.419 +} 17.420 +#endif // ndef PRODUCT 17.421 + 17.422 +ClassType* ClassDescriptor::interface_desc(Symbol* sym) { 17.423 + for (int i = 0; i < _interfaces.length(); ++i) { 17.424 + if (_interfaces.at(i)->identifier()->equals(sym)) { 17.425 + return _interfaces.at(i); 17.426 + } 17.427 + } 17.428 + if (VerifyGenericSignatures) { 17.429 + fatal("Did not find expected interface"); 17.430 + } 17.431 + return NULL; 17.432 +} 17.433 + 17.434 +void ClassDescriptor::bind_variables_to_parameters() { 17.435 + if (_outer_class != NULL) { 17.436 + _outer_class->bind_variables_to_parameters(); 17.437 + } 17.438 + if (_outer_method != NULL) { 17.439 + _outer_method->bind_variables_to_parameters(); 17.440 + } 17.441 + for (int i = 0; i < _type_parameters.length(); ++i) { 17.442 + _type_parameters.at(i)->bind_variables_to_parameters(this, i); 17.443 + } 17.444 + if (_super != NULL) { 17.445 + _super->bind_variables_to_parameters(this); 17.446 + } 17.447 + for (int i = 0; i < _interfaces.length(); ++i) { 17.448 + _interfaces.at(i)->bind_variables_to_parameters(this); 17.449 + } 17.450 +} 17.451 + 17.452 +ClassDescriptor* ClassDescriptor::canonicalize(Context* ctx) { 17.453 + 17.454 + GrowableArray<TypeParameter*> type_params(_type_parameters.length()); 17.455 + for (int i = 0; i < _type_parameters.length(); ++i) { 17.456 + type_params.append(_type_parameters.at(i)->canonicalize(ctx, 0)); 17.457 + } 17.458 + 17.459 + ClassDescriptor* outer = _outer_class == NULL ? NULL : 17.460 + _outer_class->canonicalize(ctx); 17.461 + 17.462 + ClassType* super = _super == NULL ? NULL : _super->canonicalize(ctx, 0); 17.463 + 17.464 + GrowableArray<ClassType*> interfaces(_interfaces.length()); 17.465 + for (int i = 0; i < _interfaces.length(); ++i) { 17.466 + interfaces.append(_interfaces.at(i)->canonicalize(ctx, 0)); 17.467 + } 17.468 + 17.469 + MethodDescriptor* md = _outer_method == NULL ? NULL : 17.470 + _outer_method->canonicalize(ctx); 17.471 + 17.472 + return new ClassDescriptor(type_params, super, interfaces, outer, md); 17.473 +} 17.474 + 17.475 +u2 ClassDescriptor::get_outer_class_index(InstanceKlass* klass, TRAPS) { 17.476 + int inner_index = InstanceKlass::inner_class_inner_class_info_offset; 17.477 + int outer_index = InstanceKlass::inner_class_outer_class_info_offset; 17.478 + int name_offset = InstanceKlass::inner_class_inner_name_offset; 17.479 + int next_offset = InstanceKlass::inner_class_next_offset; 17.480 + 17.481 + if (klass->inner_classes() == NULL || klass->inner_classes()->length() == 0) { 17.482 + // No inner class info => no declaring class 17.483 + return 0; 17.484 + } 17.485 + 17.486 + Array<u2>* i_icls = klass->inner_classes(); 17.487 + ConstantPool* i_cp = klass->constants(); 17.488 + int i_length = i_icls->length(); 17.489 + 17.490 + // Find inner_klass attribute 17.491 + for (int i = 0; i + next_offset < i_length; i += next_offset) { 17.492 + u2 ioff = i_icls->at(i + inner_index); 17.493 + u2 ooff = i_icls->at(i + outer_index); 17.494 + u2 noff = i_icls->at(i + name_offset); 17.495 + if (ioff != 0) { 17.496 + // Check to see if the name matches the class we're looking for 17.497 + // before attempting to find the class. 17.498 + if (i_cp->klass_name_at_matches(klass, ioff) && ooff != 0) { 17.499 + return ooff; 17.500 + } 17.501 + } 17.502 + } 17.503 + 17.504 + // It may be anonymous; try for that. 17.505 + u2 encl_method_class_idx = klass->enclosing_method_class_index(); 17.506 + if (encl_method_class_idx != 0) { 17.507 + return encl_method_class_idx; 17.508 + } 17.509 + 17.510 + return 0; 17.511 +} 17.512 + 17.513 +MethodDescriptor* MethodDescriptor::parse_generic_signature(Method* m, ClassDescriptor* outer) { 17.514 + Symbol* generic_sig = m->generic_signature(); 17.515 + MethodDescriptor* md = NULL; 17.516 + if (generic_sig == NULL || (md = parse_generic_signature(generic_sig, outer)) == NULL) { 17.517 + md = parse_generic_signature(m->signature(), outer); 17.518 + } 17.519 + assert(md != NULL, "Could not parse method signature"); 17.520 + md->bind_variables_to_parameters(); 17.521 + return md; 17.522 +} 17.523 + 17.524 +MethodDescriptor* MethodDescriptor::parse_generic_signature(Symbol* sym, ClassDescriptor* outer) { 17.525 + 17.526 + DescriptorStream ds(sym); 17.527 + DescriptorStream* STREAM = &ds; 17.528 + 17.529 + GrowableArray<TypeParameter*> params(8); 17.530 + char c = READ(); 17.531 + if (c == '<') { 17.532 + c = READ(); 17.533 + while (c != '>') { 17.534 + PUSH(c); 17.535 + TypeParameter* ftp = TypeParameter::parse_generic_signature(CHECK_STREAM); 17.536 + params.append(ftp); 17.537 + c = READ(); 17.538 + } 17.539 + } else { 17.540 + PUSH(c); 17.541 + } 17.542 + 17.543 + EXPECT('('); 17.544 + 17.545 + GrowableArray<Type*> parameters(8); 17.546 + c = READ(); 17.547 + while (c != ')') { 17.548 + PUSH(c); 17.549 + Type* arg = Type::parse_generic_signature(CHECK_STREAM); 17.550 + parameters.append(arg); 17.551 + c = READ(); 17.552 + } 17.553 + 17.554 + Type* rt = Type::parse_generic_signature(CHECK_STREAM); 17.555 + 17.556 + GrowableArray<Type*> throws; 17.557 + while (!STREAM->at_end()) { 17.558 + EXPECT('^'); 17.559 + Type* spec = Type::parse_generic_signature(CHECK_STREAM); 17.560 + throws.append(spec); 17.561 + } 17.562 + 17.563 + return new MethodDescriptor(params, outer, parameters, rt, throws); 17.564 +} 17.565 + 17.566 +void MethodDescriptor::bind_variables_to_parameters() { 17.567 + for (int i = 0; i < _type_parameters.length(); ++i) { 17.568 + _type_parameters.at(i)->bind_variables_to_parameters(this, i); 17.569 + } 17.570 + for (int i = 0; i < _parameters.length(); ++i) { 17.571 + _parameters.at(i)->bind_variables_to_parameters(this); 17.572 + } 17.573 + _return_type->bind_variables_to_parameters(this); 17.574 + for (int i = 0; i < _throws.length(); ++i) { 17.575 + _throws.at(i)->bind_variables_to_parameters(this); 17.576 + } 17.577 +} 17.578 + 17.579 +bool MethodDescriptor::covariant_match(MethodDescriptor* other, Context* ctx) { 17.580 + 17.581 + if (_parameters.length() == other->_parameters.length()) { 17.582 + for (int i = 0; i < _parameters.length(); ++i) { 17.583 + if (!_parameters.at(i)->covariant_match(other->_parameters.at(i), ctx)) { 17.584 + return false; 17.585 + } 17.586 + } 17.587 + 17.588 + if (_return_type->as_primitive() != NULL) { 17.589 + return _return_type->covariant_match(other->_return_type, ctx); 17.590 + } else { 17.591 + // return type is a reference 17.592 + return other->_return_type->as_class() != NULL || 17.593 + other->_return_type->as_variable() != NULL || 17.594 + other->_return_type->as_array() != NULL; 17.595 + } 17.596 + } else { 17.597 + return false; 17.598 + } 17.599 +} 17.600 + 17.601 +MethodDescriptor* MethodDescriptor::canonicalize(Context* ctx) { 17.602 + 17.603 + GrowableArray<TypeParameter*> type_params(_type_parameters.length()); 17.604 + for (int i = 0; i < _type_parameters.length(); ++i) { 17.605 + type_params.append(_type_parameters.at(i)->canonicalize(ctx, 0)); 17.606 + } 17.607 + 17.608 + ClassDescriptor* outer = _outer_class == NULL ? NULL : 17.609 + _outer_class->canonicalize(ctx); 17.610 + 17.611 + GrowableArray<Type*> params(_parameters.length()); 17.612 + for (int i = 0; i < _parameters.length(); ++i) { 17.613 + params.append(_parameters.at(i)->canonicalize(ctx, 0)); 17.614 + } 17.615 + 17.616 + Type* rt = _return_type->canonicalize(ctx, 0); 17.617 + 17.618 + GrowableArray<Type*> throws(_throws.length()); 17.619 + for (int i = 0; i < _throws.length(); ++i) { 17.620 + throws.append(_throws.at(i)->canonicalize(ctx, 0)); 17.621 + } 17.622 + 17.623 + return new MethodDescriptor(type_params, outer, params, rt, throws); 17.624 +} 17.625 + 17.626 +#ifndef PRODUCT 17.627 +TempNewSymbol MethodDescriptor::reify_signature(Context* ctx, TRAPS) { 17.628 + stringStream ss(256); 17.629 + 17.630 + ss.print("("); 17.631 + for (int i = 0; i < _parameters.length(); ++i) { 17.632 + _parameters.at(i)->reify_signature(&ss, ctx); 17.633 + } 17.634 + ss.print(")"); 17.635 + _return_type->reify_signature(&ss, ctx); 17.636 + return SymbolTable::new_symbol(ss.base(), (int)ss.size(), THREAD); 17.637 +} 17.638 + 17.639 +void MethodDescriptor::print_on(outputStream* str) const { 17.640 + str->indent().print_cr("MethodDescriptor {"); 17.641 + { 17.642 + streamIndentor si(str); 17.643 + if (_type_parameters.length() > 0) { 17.644 + str->indent().print_cr("Formals: {"); 17.645 + { 17.646 + streamIndentor si(str); 17.647 + for (int i = 0; i < _type_parameters.length(); ++i) { 17.648 + _type_parameters.at(i)->print_on(str); 17.649 + } 17.650 + } 17.651 + str->indent().print_cr("}"); 17.652 + } 17.653 + str->indent().print_cr("Parameters: {"); 17.654 + { 17.655 + streamIndentor si(str); 17.656 + for (int i = 0; i < _parameters.length(); ++i) { 17.657 + _parameters.at(i)->print_on(str); 17.658 + } 17.659 + } 17.660 + str->indent().print_cr("}"); 17.661 + str->indent().print_cr("Return Type: "); 17.662 + { 17.663 + streamIndentor si(str); 17.664 + _return_type->print_on(str); 17.665 + } 17.666 + 17.667 + if (_throws.length() > 0) { 17.668 + str->indent().print_cr("Throws: {"); 17.669 + { 17.670 + streamIndentor si(str); 17.671 + for (int i = 0; i < _throws.length(); ++i) { 17.672 + _throws.at(i)->print_on(str); 17.673 + } 17.674 + } 17.675 + str->indent().print_cr("}"); 17.676 + } 17.677 + } 17.678 + str->indent().print_cr("}"); 17.679 +} 17.680 +#endif // ndef PRODUCT 17.681 + 17.682 +TypeParameter* TypeParameter::parse_generic_signature(DescriptorStream* STREAM) { 17.683 + STREAM->set_mark(); 17.684 + char c = READ(); 17.685 + while (c != ':') { 17.686 + c = READ(); 17.687 + } 17.688 + 17.689 + Identifier* id = STREAM->identifier_from_mark(); 17.690 + 17.691 + ClassType* class_bound = NULL; 17.692 + GrowableArray<ClassType*> interface_bounds(8); 17.693 + 17.694 + c = READ(); 17.695 + if (c != '>') { 17.696 + if (c != ':') { 17.697 + EXPECTED(c, 'L'); 17.698 + class_bound = ClassType::parse_generic_signature(CHECK_STREAM); 17.699 + c = READ(); 17.700 + } 17.701 + 17.702 + while (c == ':') { 17.703 + EXPECT('L'); 17.704 + ClassType* fts = ClassType::parse_generic_signature(CHECK_STREAM); 17.705 + interface_bounds.append(fts); 17.706 + c = READ(); 17.707 + } 17.708 + } 17.709 + PUSH(c); 17.710 + 17.711 + return new TypeParameter(id, class_bound, interface_bounds); 17.712 +} 17.713 + 17.714 +void TypeParameter::bind_variables_to_parameters(Descriptor* sig, int position) { 17.715 + if (_class_bound != NULL) { 17.716 + _class_bound->bind_variables_to_parameters(sig); 17.717 + } 17.718 + for (int i = 0; i < _interface_bounds.length(); ++i) { 17.719 + _interface_bounds.at(i)->bind_variables_to_parameters(sig); 17.720 + } 17.721 + _position = position; 17.722 +} 17.723 + 17.724 +Type* TypeParameter::resolve( 17.725 + Context* ctx, int inner_depth, int ctx_depth) { 17.726 + 17.727 + if (inner_depth == -1) { 17.728 + // This indicates that the parameter is a method type parameter, which 17.729 + // isn't resolveable using the class hierarchy context 17.730 + return bound(); 17.731 + } 17.732 + 17.733 + ClassType* provider = ctx->at_depth(ctx_depth); 17.734 + if (provider != NULL) { 17.735 + for (int i = 0; i < inner_depth && provider != NULL; ++i) { 17.736 + provider = provider->outer_class(); 17.737 + } 17.738 + if (provider != NULL) { 17.739 + TypeArgument* arg = provider->type_argument_at(_position); 17.740 + if (arg != NULL) { 17.741 + Type* value = arg->lower_bound(); 17.742 + return value->canonicalize(ctx, ctx_depth + 1); 17.743 + } 17.744 + } 17.745 + } 17.746 + 17.747 + return bound(); 17.748 +} 17.749 + 17.750 +TypeParameter* TypeParameter::canonicalize(Context* ctx, int ctx_depth) { 17.751 + ClassType* bound = _class_bound == NULL ? NULL : 17.752 + _class_bound->canonicalize(ctx, ctx_depth); 17.753 + 17.754 + GrowableArray<ClassType*> ifaces(_interface_bounds.length()); 17.755 + for (int i = 0; i < _interface_bounds.length(); ++i) { 17.756 + ifaces.append(_interface_bounds.at(i)->canonicalize(ctx, ctx_depth)); 17.757 + } 17.758 + 17.759 + TypeParameter* ret = new TypeParameter(_identifier, bound, ifaces); 17.760 + ret->_position = _position; 17.761 + return ret; 17.762 +} 17.763 + 17.764 +ClassType* TypeParameter::bound() { 17.765 + if (_class_bound != NULL) { 17.766 + return _class_bound; 17.767 + } 17.768 + 17.769 + if (_interface_bounds.length() == 1) { 17.770 + return _interface_bounds.at(0); 17.771 + } 17.772 + 17.773 + return ClassType::java_lang_Object(); // TODO: investigate this case 17.774 +} 17.775 + 17.776 +#ifndef PRODUCT 17.777 +void TypeParameter::print_on(outputStream* str) const { 17.778 + str->indent().print_cr("Formal: {"); 17.779 + { 17.780 + streamIndentor si(str); 17.781 + 17.782 + str->indent().print("Identifier: "); 17.783 + _identifier->print_on(str); 17.784 + str->print_cr(""); 17.785 + if (_class_bound != NULL) { 17.786 + str->indent().print_cr("Class Bound: "); 17.787 + streamIndentor si(str); 17.788 + _class_bound->print_on(str); 17.789 + } 17.790 + if (_interface_bounds.length() > 0) { 17.791 + str->indent().print_cr("Interface Bounds: {"); 17.792 + { 17.793 + streamIndentor si(str); 17.794 + for (int i = 0; i < _interface_bounds.length(); ++i) { 17.795 + _interface_bounds.at(i)->print_on(str); 17.796 + } 17.797 + } 17.798 + str->indent().print_cr("}"); 17.799 + } 17.800 + str->indent().print_cr("Ordinal Position: %d", _position); 17.801 + } 17.802 + str->indent().print_cr("}"); 17.803 +} 17.804 +#endif // ndef PRODUCT 17.805 + 17.806 +Type* Type::parse_generic_signature(DescriptorStream* STREAM) { 17.807 + char c = READ(); 17.808 + switch (c) { 17.809 + case 'L': 17.810 + return ClassType::parse_generic_signature(CHECK_STREAM); 17.811 + case 'T': 17.812 + return TypeVariable::parse_generic_signature(CHECK_STREAM); 17.813 + case '[': 17.814 + return ArrayType::parse_generic_signature(CHECK_STREAM); 17.815 + default: 17.816 + return new PrimitiveType(c); 17.817 + } 17.818 +} 17.819 + 17.820 +Identifier* ClassType::parse_generic_signature_simple(GrowableArray<TypeArgument*>* args, 17.821 + bool* has_inner, DescriptorStream* STREAM) { 17.822 + STREAM->set_mark(); 17.823 + 17.824 + char c = READ(); 17.825 + while (c != ';' && c != '.' && c != '<') { c = READ(); } 17.826 + Identifier* id = STREAM->identifier_from_mark(); 17.827 + 17.828 + if (c == '<') { 17.829 + c = READ(); 17.830 + while (c != '>') { 17.831 + PUSH(c); 17.832 + TypeArgument* arg = TypeArgument::parse_generic_signature(CHECK_STREAM); 17.833 + args->append(arg); 17.834 + c = READ(); 17.835 + } 17.836 + c = READ(); 17.837 + } 17.838 + 17.839 + *has_inner = (c == '.'); 17.840 + if (!(*has_inner)) { 17.841 + EXPECTED(c, ';'); 17.842 + } 17.843 + 17.844 + return id; 17.845 +} 17.846 + 17.847 +ClassType* ClassType::parse_generic_signature(DescriptorStream* STREAM) { 17.848 + return parse_generic_signature(NULL, CHECK_STREAM); 17.849 +} 17.850 + 17.851 +ClassType* ClassType::parse_generic_signature(ClassType* outer, DescriptorStream* STREAM) { 17.852 + GrowableArray<TypeArgument*> args; 17.853 + ClassType* gct = NULL; 17.854 + bool has_inner = false; 17.855 + 17.856 + Identifier* id = parse_generic_signature_simple(&args, &has_inner, STREAM); 17.857 + if (id != NULL) { 17.858 + gct = new ClassType(id, args, outer); 17.859 + 17.860 + if (has_inner) { 17.861 + gct = parse_generic_signature(gct, CHECK_STREAM); 17.862 + } 17.863 + } 17.864 + return gct; 17.865 +} 17.866 + 17.867 +ClassType* ClassType::from_symbol(Symbol* sym) { 17.868 + assert(sym != NULL, "Must not be null"); 17.869 + GrowableArray<TypeArgument*> args; 17.870 + Identifier* id = new Identifier(sym, 0, sym->utf8_length()); 17.871 + return new ClassType(id, args, NULL); 17.872 +} 17.873 + 17.874 +ClassType* ClassType::java_lang_Object() { 17.875 + return from_symbol(vmSymbols::java_lang_Object()); 17.876 +} 17.877 + 17.878 +void ClassType::bind_variables_to_parameters(Descriptor* sig) { 17.879 + for (int i = 0; i < _type_arguments.length(); ++i) { 17.880 + _type_arguments.at(i)->bind_variables_to_parameters(sig); 17.881 + } 17.882 + if (_outer_class != NULL) { 17.883 + _outer_class->bind_variables_to_parameters(sig); 17.884 + } 17.885 +} 17.886 + 17.887 +TypeArgument* ClassType::type_argument_at(int i) { 17.888 + if (i >= 0 && i < _type_arguments.length()) { 17.889 + return _type_arguments.at(i); 17.890 + } else { 17.891 + return NULL; 17.892 + } 17.893 +} 17.894 + 17.895 +#ifndef PRODUCT 17.896 +void ClassType::reify_signature(stringStream* ss, Context* ctx) { 17.897 + ss->print("L"); 17.898 + _identifier->print_on(ss); 17.899 + ss->print(";"); 17.900 +} 17.901 + 17.902 +void ClassType::print_on(outputStream* str) const { 17.903 + str->indent().print_cr("Class {"); 17.904 + { 17.905 + streamIndentor si(str); 17.906 + str->indent().print("Name: "); 17.907 + _identifier->print_on(str); 17.908 + str->print_cr(""); 17.909 + if (_type_arguments.length() != 0) { 17.910 + str->indent().print_cr("Type Arguments: {"); 17.911 + { 17.912 + streamIndentor si(str); 17.913 + for (int j = 0; j < _type_arguments.length(); ++j) { 17.914 + _type_arguments.at(j)->print_on(str); 17.915 + } 17.916 + } 17.917 + str->indent().print_cr("}"); 17.918 + } 17.919 + if (_outer_class != NULL) { 17.920 + str->indent().print_cr("Outer Class: "); 17.921 + streamIndentor sir(str); 17.922 + _outer_class->print_on(str); 17.923 + } 17.924 + } 17.925 + str->indent().print_cr("}"); 17.926 +} 17.927 +#endif // ndef PRODUCT 17.928 + 17.929 +bool ClassType::covariant_match(Type* other, Context* ctx) { 17.930 + 17.931 + if (other == this) { 17.932 + return true; 17.933 + } 17.934 + 17.935 + TypeVariable* variable = other->as_variable(); 17.936 + if (variable != NULL) { 17.937 + other = variable->resolve(ctx, 0); 17.938 + } 17.939 + 17.940 + ClassType* outer = outer_class(); 17.941 + ClassType* other_class = other->as_class(); 17.942 + 17.943 + if (other_class == NULL || 17.944 + (outer == NULL) != (other_class->outer_class() == NULL)) { 17.945 + return false; 17.946 + } 17.947 + 17.948 + if (!_identifier->equals(other_class->_identifier)) { 17.949 + return false; 17.950 + } 17.951 + 17.952 + if (outer != NULL && !outer->covariant_match(other_class->outer_class(), ctx)) { 17.953 + return false; 17.954 + } 17.955 + 17.956 + return true; 17.957 +} 17.958 + 17.959 +ClassType* ClassType::canonicalize(Context* ctx, int ctx_depth) { 17.960 + 17.961 + GrowableArray<TypeArgument*> args(_type_arguments.length()); 17.962 + for (int i = 0; i < _type_arguments.length(); ++i) { 17.963 + args.append(_type_arguments.at(i)->canonicalize(ctx, ctx_depth)); 17.964 + } 17.965 + 17.966 + ClassType* outer = _outer_class == NULL ? NULL : 17.967 + _outer_class->canonicalize(ctx, ctx_depth); 17.968 + 17.969 + return new ClassType(_identifier, args, outer); 17.970 +} 17.971 + 17.972 +TypeVariable* TypeVariable::parse_generic_signature(DescriptorStream* STREAM) { 17.973 + STREAM->set_mark(); 17.974 + char c = READ(); 17.975 + while (c != ';') { 17.976 + c = READ(); 17.977 + } 17.978 + Identifier* id = STREAM->identifier_from_mark(); 17.979 + 17.980 + return new TypeVariable(id); 17.981 +} 17.982 + 17.983 +void TypeVariable::bind_variables_to_parameters(Descriptor* sig) { 17.984 + _parameter = sig->find_type_parameter(_id, &_inner_depth); 17.985 + if (VerifyGenericSignatures && _parameter == NULL) { 17.986 + fatal("Could not find formal parameter"); 17.987 + } 17.988 +} 17.989 + 17.990 +Type* TypeVariable::resolve(Context* ctx, int ctx_depth) { 17.991 + if (parameter() != NULL) { 17.992 + return parameter()->resolve(ctx, inner_depth(), ctx_depth); 17.993 + } else { 17.994 + if (VerifyGenericSignatures) { 17.995 + fatal("Type variable matches no parameter"); 17.996 + } 17.997 + return NULL; 17.998 + } 17.999 +} 17.1000 + 17.1001 +bool TypeVariable::covariant_match(Type* other, Context* ctx) { 17.1002 + 17.1003 + if (other == this) { 17.1004 + return true; 17.1005 + } 17.1006 + 17.1007 + Context my_context(NULL); // empty, results in erasure 17.1008 + Type* my_type = resolve(&my_context, 0); 17.1009 + if (my_type == NULL) { 17.1010 + return false; 17.1011 + } 17.1012 + 17.1013 + return my_type->covariant_match(other, ctx); 17.1014 +} 17.1015 + 17.1016 +Type* TypeVariable::canonicalize(Context* ctx, int ctx_depth) { 17.1017 + return resolve(ctx, ctx_depth); 17.1018 +} 17.1019 + 17.1020 +#ifndef PRODUCT 17.1021 +void TypeVariable::reify_signature(stringStream* ss, Context* ctx) { 17.1022 + Type* type = resolve(ctx, 0); 17.1023 + if (type != NULL) { 17.1024 + type->reify_signature(ss, ctx); 17.1025 + } 17.1026 +} 17.1027 + 17.1028 +void TypeVariable::print_on(outputStream* str) const { 17.1029 + str->indent().print_cr("Type Variable {"); 17.1030 + { 17.1031 + streamIndentor si(str); 17.1032 + str->indent().print("Name: "); 17.1033 + _id->print_on(str); 17.1034 + str->print_cr(""); 17.1035 + str->indent().print_cr("Inner depth: %d", _inner_depth); 17.1036 + } 17.1037 + str->indent().print_cr("}"); 17.1038 +} 17.1039 +#endif // ndef PRODUCT 17.1040 + 17.1041 +ArrayType* ArrayType::parse_generic_signature(DescriptorStream* STREAM) { 17.1042 + Type* base = Type::parse_generic_signature(CHECK_STREAM); 17.1043 + return new ArrayType(base); 17.1044 +} 17.1045 + 17.1046 +void ArrayType::bind_variables_to_parameters(Descriptor* sig) { 17.1047 + assert(_base != NULL, "Invalid base"); 17.1048 + _base->bind_variables_to_parameters(sig); 17.1049 +} 17.1050 + 17.1051 +bool ArrayType::covariant_match(Type* other, Context* ctx) { 17.1052 + assert(_base != NULL, "Invalid base"); 17.1053 + 17.1054 + if (other == this) { 17.1055 + return true; 17.1056 + } 17.1057 + 17.1058 + ArrayType* other_array = other->as_array(); 17.1059 + return (other_array != NULL && _base->covariant_match(other_array->_base, ctx)); 17.1060 +} 17.1061 + 17.1062 +ArrayType* ArrayType::canonicalize(Context* ctx, int ctx_depth) { 17.1063 + assert(_base != NULL, "Invalid base"); 17.1064 + return new ArrayType(_base->canonicalize(ctx, ctx_depth)); 17.1065 +} 17.1066 + 17.1067 +#ifndef PRODUCT 17.1068 +void ArrayType::reify_signature(stringStream* ss, Context* ctx) { 17.1069 + assert(_base != NULL, "Invalid base"); 17.1070 + ss->print("["); 17.1071 + _base->reify_signature(ss, ctx); 17.1072 +} 17.1073 + 17.1074 +void ArrayType::print_on(outputStream* str) const { 17.1075 + str->indent().print_cr("Array {"); 17.1076 + { 17.1077 + streamIndentor si(str); 17.1078 + _base->print_on(str); 17.1079 + } 17.1080 + str->indent().print_cr("}"); 17.1081 +} 17.1082 +#endif // ndef PRODUCT 17.1083 + 17.1084 +bool PrimitiveType::covariant_match(Type* other, Context* ctx) { 17.1085 + 17.1086 + PrimitiveType* other_prim = other->as_primitive(); 17.1087 + return (other_prim != NULL && _type == other_prim->_type); 17.1088 +} 17.1089 + 17.1090 +PrimitiveType* PrimitiveType::canonicalize(Context* ctx, int ctxd) { 17.1091 + return this; 17.1092 +} 17.1093 + 17.1094 +#ifndef PRODUCT 17.1095 +void PrimitiveType::reify_signature(stringStream* ss, Context* ctx) { 17.1096 + ss->print("%c", _type); 17.1097 +} 17.1098 + 17.1099 +void PrimitiveType::print_on(outputStream* str) const { 17.1100 + str->indent().print_cr("Primitive: '%c'", _type); 17.1101 +} 17.1102 +#endif // ndef PRODUCT 17.1103 + 17.1104 +void PrimitiveType::bind_variables_to_parameters(Descriptor* sig) { 17.1105 +} 17.1106 + 17.1107 +TypeArgument* TypeArgument::parse_generic_signature(DescriptorStream* STREAM) { 17.1108 + char c = READ(); 17.1109 + Type* type = NULL; 17.1110 + 17.1111 + switch (c) { 17.1112 + case '*': 17.1113 + return new TypeArgument(ClassType::java_lang_Object(), NULL); 17.1114 + break; 17.1115 + default: 17.1116 + PUSH(c); 17.1117 + // fall-through 17.1118 + case '+': 17.1119 + case '-': 17.1120 + type = Type::parse_generic_signature(CHECK_STREAM); 17.1121 + if (c == '+') { 17.1122 + return new TypeArgument(type, NULL); 17.1123 + } else if (c == '-') { 17.1124 + return new TypeArgument(ClassType::java_lang_Object(), type); 17.1125 + } else { 17.1126 + return new TypeArgument(type, type); 17.1127 + } 17.1128 + } 17.1129 +} 17.1130 + 17.1131 +void TypeArgument::bind_variables_to_parameters(Descriptor* sig) { 17.1132 + assert(_lower_bound != NULL, "Invalid lower bound"); 17.1133 + _lower_bound->bind_variables_to_parameters(sig); 17.1134 + if (_upper_bound != NULL && _upper_bound != _lower_bound) { 17.1135 + _upper_bound->bind_variables_to_parameters(sig); 17.1136 + } 17.1137 +} 17.1138 + 17.1139 +bool TypeArgument::covariant_match(TypeArgument* other, Context* ctx) { 17.1140 + assert(_lower_bound != NULL, "Invalid lower bound"); 17.1141 + 17.1142 + if (other == this) { 17.1143 + return true; 17.1144 + } 17.1145 + 17.1146 + if (!_lower_bound->covariant_match(other->lower_bound(), ctx)) { 17.1147 + return false; 17.1148 + } 17.1149 + return true; 17.1150 +} 17.1151 + 17.1152 +TypeArgument* TypeArgument::canonicalize(Context* ctx, int ctx_depth) { 17.1153 + assert(_lower_bound != NULL, "Invalid lower bound"); 17.1154 + Type* lower = _lower_bound->canonicalize(ctx, ctx_depth); 17.1155 + Type* upper = NULL; 17.1156 + 17.1157 + if (_upper_bound == _lower_bound) { 17.1158 + upper = lower; 17.1159 + } else if (_upper_bound != NULL) { 17.1160 + upper = _upper_bound->canonicalize(ctx, ctx_depth); 17.1161 + } 17.1162 + 17.1163 + return new TypeArgument(lower, upper); 17.1164 +} 17.1165 + 17.1166 +#ifndef PRODUCT 17.1167 +void TypeArgument::print_on(outputStream* str) const { 17.1168 + str->indent().print_cr("TypeArgument {"); 17.1169 + { 17.1170 + streamIndentor si(str); 17.1171 + if (_lower_bound != NULL) { 17.1172 + str->indent().print("Lower bound: "); 17.1173 + _lower_bound->print_on(str); 17.1174 + } 17.1175 + if (_upper_bound != NULL) { 17.1176 + str->indent().print("Upper bound: "); 17.1177 + _upper_bound->print_on(str); 17.1178 + } 17.1179 + } 17.1180 + str->indent().print_cr("}"); 17.1181 +} 17.1182 +#endif // ndef PRODUCT 17.1183 + 17.1184 +void Context::Mark::destroy() { 17.1185 + if (is_active()) { 17.1186 + _context->reset_to_mark(_marked_size); 17.1187 + } 17.1188 + deactivate(); 17.1189 +} 17.1190 + 17.1191 +void Context::apply_type_arguments( 17.1192 + InstanceKlass* current, InstanceKlass* super, TRAPS) { 17.1193 + assert(_cache != NULL, "Cannot use an empty context"); 17.1194 + ClassType* spec = NULL; 17.1195 + if (current != NULL) { 17.1196 + ClassDescriptor* descriptor = _cache->descriptor_for(current, CHECK); 17.1197 + if (super == current->super()) { 17.1198 + spec = descriptor->super(); 17.1199 + } else { 17.1200 + spec = descriptor->interface_desc(super->name()); 17.1201 + } 17.1202 + if (spec != NULL) { 17.1203 + _type_arguments.push(spec); 17.1204 + } 17.1205 + } 17.1206 +} 17.1207 + 17.1208 +void Context::reset_to_mark(int size) { 17.1209 + _type_arguments.trunc_to(size); 17.1210 +} 17.1211 + 17.1212 +ClassType* Context::at_depth(int i) const { 17.1213 + if (i < _type_arguments.length()) { 17.1214 + return _type_arguments.at(_type_arguments.length() - 1 - i); 17.1215 + } 17.1216 + return NULL; 17.1217 +} 17.1218 + 17.1219 +#ifndef PRODUCT 17.1220 +void Context::print_on(outputStream* str) const { 17.1221 + str->indent().print_cr("Context {"); 17.1222 + for (int i = 0; i < _type_arguments.length(); ++i) { 17.1223 + streamIndentor si(str); 17.1224 + str->indent().print("leval %d: ", i); 17.1225 + ClassType* ct = at_depth(i); 17.1226 + if (ct == NULL) { 17.1227 + str->print_cr("<empty>"); 17.1228 + continue; 17.1229 + } else { 17.1230 + str->print_cr("{"); 17.1231 + } 17.1232 + 17.1233 + for (int j = 0; j < ct->type_arguments_length(); ++j) { 17.1234 + streamIndentor si(str); 17.1235 + TypeArgument* ta = ct->type_argument_at(j); 17.1236 + Type* bound = ta->lower_bound(); 17.1237 + bound->print_on(str); 17.1238 + } 17.1239 + str->indent().print_cr("}"); 17.1240 + } 17.1241 + str->indent().print_cr("}"); 17.1242 +} 17.1243 +#endif // ndef PRODUCT 17.1244 + 17.1245 +ClassDescriptor* DescriptorCache::descriptor_for(InstanceKlass* ik, TRAPS) { 17.1246 + 17.1247 + ClassDescriptor** existing = _class_descriptors.get(ik); 17.1248 + if (existing == NULL) { 17.1249 + ClassDescriptor* cd = ClassDescriptor::parse_generic_signature(ik, CHECK_NULL); 17.1250 + _class_descriptors.put(ik, cd); 17.1251 + return cd; 17.1252 + } else { 17.1253 + return *existing; 17.1254 + } 17.1255 +} 17.1256 + 17.1257 +MethodDescriptor* DescriptorCache::descriptor_for( 17.1258 + Method* mh, ClassDescriptor* cd, TRAPS) { 17.1259 + assert(mh != NULL && cd != NULL, "Should not be NULL"); 17.1260 + MethodDescriptor** existing = _method_descriptors.get(mh); 17.1261 + if (existing == NULL) { 17.1262 + MethodDescriptor* md = MethodDescriptor::parse_generic_signature(mh, cd); 17.1263 + _method_descriptors.put(mh, md); 17.1264 + return md; 17.1265 + } else { 17.1266 + return *existing; 17.1267 + } 17.1268 +} 17.1269 +MethodDescriptor* DescriptorCache::descriptor_for(Method* mh, TRAPS) { 17.1270 + ClassDescriptor* cd = descriptor_for( 17.1271 + InstanceKlass::cast(mh->method_holder()), CHECK_NULL); 17.1272 + return descriptor_for(mh, cd, THREAD); 17.1273 +} 17.1274 + 17.1275 +} // namespace generic
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 18.2 +++ b/src/share/vm/classfile/genericSignatures.hpp Wed Nov 07 16:09:20 2012 -0800 18.3 @@ -0,0 +1,467 @@ 18.4 +/* 18.5 + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. 18.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 18.7 + * 18.8 + * This code is free software; you can redistribute it and/or modify it 18.9 + * under the terms of the GNU General Public License version 2 only, as 18.10 + * published by the Free Software Foundation. 18.11 + * 18.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 18.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 18.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 18.15 + * version 2 for more details (a copy is included in the LICENSE file that 18.16 + * accompanied this code). 18.17 + * 18.18 + * You should have received a copy of the GNU General Public License version 18.19 + * 2 along with this work; if not, write to the Free Software Foundation, 18.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18.21 + * 18.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 18.23 + * or visit www.oracle.com if you need additional information or have any 18.24 + * questions. 18.25 + * 18.26 + */ 18.27 + 18.28 +#ifndef SHARE_VM_CLASSFILE_GENERICSIGNATURES_HPP 18.29 +#define SHARE_VM_CLASSFILE_GENERICSIGNATURES_HPP 18.30 + 18.31 +#include "classfile/symbolTable.hpp" 18.32 +#include "memory/allocation.hpp" 18.33 +#include "runtime/signature.hpp" 18.34 +#include "utilities/growableArray.hpp" 18.35 +#include "utilities/resourceHash.hpp" 18.36 + 18.37 +class stringStream; 18.38 + 18.39 +namespace generic { 18.40 + 18.41 +class Identifier; 18.42 +class ClassDescriptor; 18.43 +class MethodDescriptor; 18.44 + 18.45 +class TypeParameter; // a formal type parameter declared in generic signatures 18.46 +class TypeArgument; // The "type value" passed to fill parameters in supertypes 18.47 +class TypeVariable; // A usage of a type parameter as a value 18.48 +/** 18.49 + * Example: 18.50 + * 18.51 + * <T, V> class Foo extends Bar<String> { int m(V v) {} } 18.52 + * ^^^^^^ ^^^^^^ ^^ 18.53 + * type parameters type argument type variable 18.54 + * 18.55 + * Note that a type variable could be passed as an argument too: 18.56 + * <T, V> class Foo extends Bar<T> { int m(V v) {} } 18.57 + * ^^^ 18.58 + * type argument's value is a type variable 18.59 + */ 18.60 + 18.61 + 18.62 +class Type; 18.63 +class ClassType; 18.64 +class ArrayType; 18.65 +class PrimitiveType; 18.66 +class Context; 18.67 +class DescriptorCache; 18.68 + 18.69 +class DescriptorStream; 18.70 + 18.71 +class Identifier : public ResourceObj { 18.72 + private: 18.73 + Symbol* _sym; 18.74 + int _begin; 18.75 + int _end; 18.76 + 18.77 + public: 18.78 + Identifier(Symbol* sym, int begin, int end) : 18.79 + _sym(sym), _begin(begin), _end(end) {} 18.80 + 18.81 + bool equals(Identifier* other); 18.82 + bool equals(Symbol* sym); 18.83 + 18.84 +#ifndef PRODUCT 18.85 + void print_on(outputStream* str) const; 18.86 +#endif // ndef PRODUCT 18.87 +}; 18.88 + 18.89 +class Descriptor : public ResourceObj { 18.90 + protected: 18.91 + GrowableArray<TypeParameter*> _type_parameters; 18.92 + ClassDescriptor* _outer_class; 18.93 + 18.94 + Descriptor(GrowableArray<TypeParameter*>& params, 18.95 + ClassDescriptor* outer) 18.96 + : _type_parameters(params), _outer_class(outer) {} 18.97 + 18.98 + public: 18.99 + 18.100 + ClassDescriptor* outer_class() { return _outer_class; } 18.101 + void set_outer_class(ClassDescriptor* sig) { _outer_class = sig; } 18.102 + 18.103 + virtual ClassDescriptor* as_class_signature() { return NULL; } 18.104 + virtual MethodDescriptor* as_method_signature() { return NULL; } 18.105 + 18.106 + bool is_class_signature() { return as_class_signature() != NULL; } 18.107 + bool is_method_signature() { return as_method_signature() != NULL; } 18.108 + 18.109 + GrowableArray<TypeParameter*>& type_parameters() { 18.110 + return _type_parameters; 18.111 + } 18.112 + 18.113 + TypeParameter* find_type_parameter(Identifier* id, int* param_depth); 18.114 + 18.115 + virtual void bind_variables_to_parameters() = 0; 18.116 + 18.117 +#ifndef PRODUCT 18.118 + virtual void print_on(outputStream* str) const = 0; 18.119 +#endif 18.120 +}; 18.121 + 18.122 +class ClassDescriptor : public Descriptor { 18.123 + private: 18.124 + ClassType* _super; 18.125 + GrowableArray<ClassType*> _interfaces; 18.126 + MethodDescriptor* _outer_method; 18.127 + 18.128 + ClassDescriptor(GrowableArray<TypeParameter*>& ftp, ClassType* scs, 18.129 + GrowableArray<ClassType*>& sis, ClassDescriptor* outer_class = NULL, 18.130 + MethodDescriptor* outer_method = NULL) 18.131 + : Descriptor(ftp, outer_class), _super(scs), _interfaces(sis), 18.132 + _outer_method(outer_method) {} 18.133 + 18.134 + static u2 get_outer_class_index(InstanceKlass* k, TRAPS); 18.135 + static ClassDescriptor* parse_generic_signature(Klass* k, Symbol* original_name, TRAPS); 18.136 + 18.137 + public: 18.138 + 18.139 + virtual ClassDescriptor* as_class_signature() { return this; } 18.140 + 18.141 + MethodDescriptor* outer_method() { return _outer_method; } 18.142 + void set_outer_method(MethodDescriptor* m) { _outer_method = m; } 18.143 + 18.144 + ClassType* super() { return _super; } 18.145 + ClassType* interface_desc(Symbol* sym); 18.146 + 18.147 + static ClassDescriptor* parse_generic_signature(Klass* k, TRAPS); 18.148 + static ClassDescriptor* parse_generic_signature(Symbol* sym); 18.149 + 18.150 + // For use in superclass chains in positions where this is no generic info 18.151 + static ClassDescriptor* placeholder(InstanceKlass* klass); 18.152 + 18.153 +#ifndef PRODUCT 18.154 + void print_on(outputStream* str) const; 18.155 +#endif 18.156 + 18.157 + ClassDescriptor* canonicalize(Context* ctx); 18.158 + 18.159 + // Linking sets the position index in any contained TypeVariable type 18.160 + // to correspond to the location of that identifier in the formal type 18.161 + // parameters. 18.162 + void bind_variables_to_parameters(); 18.163 +}; 18.164 + 18.165 +class MethodDescriptor : public Descriptor { 18.166 + private: 18.167 + GrowableArray<Type*> _parameters; 18.168 + Type* _return_type; 18.169 + GrowableArray<Type*> _throws; 18.170 + 18.171 + MethodDescriptor(GrowableArray<TypeParameter*>& ftp, ClassDescriptor* outer, 18.172 + GrowableArray<Type*>& sigs, Type* rt, GrowableArray<Type*>& throws) 18.173 + : Descriptor(ftp, outer), _parameters(sigs), _return_type(rt), 18.174 + _throws(throws) {} 18.175 + 18.176 + public: 18.177 + 18.178 + static MethodDescriptor* parse_generic_signature(Method* m, ClassDescriptor* outer); 18.179 + static MethodDescriptor* parse_generic_signature(Symbol* sym, ClassDescriptor* outer); 18.180 + 18.181 + MethodDescriptor* as_method_signature() { return this; } 18.182 + 18.183 + // Performs generic analysis on the method parameters to determine 18.184 + // if both methods refer to the same argument types. 18.185 + bool covariant_match(MethodDescriptor* other, Context* ctx); 18.186 + 18.187 + // Returns a new method descriptor with all generic variables 18.188 + // removed and replaced with whatever is indicated using the Context. 18.189 + MethodDescriptor* canonicalize(Context* ctx); 18.190 + 18.191 + void bind_variables_to_parameters(); 18.192 + 18.193 +#ifndef PRODUCT 18.194 + TempNewSymbol reify_signature(Context* ctx, TRAPS); 18.195 + void print_on(outputStream* str) const; 18.196 +#endif 18.197 +}; 18.198 + 18.199 +class TypeParameter : public ResourceObj { 18.200 + private: 18.201 + Identifier* _identifier; 18.202 + ClassType* _class_bound; 18.203 + GrowableArray<ClassType*> _interface_bounds; 18.204 + 18.205 + // The position is the ordinal location of the parameter within the 18.206 + // formal parameter list (excluding outer classes). It is only set for 18.207 + // formal type parameters that are associated with a class -- method 18.208 + // type parameters are left as -1. When resolving a generic variable to 18.209 + // find the actual type, this index is used to access the generic type 18.210 + // argument in the provided context object. 18.211 + int _position; // Assigned during variable linking 18.212 + 18.213 + TypeParameter(Identifier* id, ClassType* class_bound, 18.214 + GrowableArray<ClassType*>& interface_bounds) : 18.215 + _identifier(id), _class_bound(class_bound), 18.216 + _interface_bounds(interface_bounds), _position(-1) {} 18.217 + 18.218 + public: 18.219 + static TypeParameter* parse_generic_signature(DescriptorStream* str); 18.220 + 18.221 + ClassType* bound(); 18.222 + int position() { return _position; } 18.223 + 18.224 + void bind_variables_to_parameters(Descriptor* sig, int position); 18.225 + Identifier* identifier() { return _identifier; } 18.226 + 18.227 + Type* resolve(Context* ctx, int inner_depth, int ctx_depth); 18.228 + TypeParameter* canonicalize(Context* ctx, int ctx_depth); 18.229 + 18.230 +#ifndef PRODUCT 18.231 + void print_on(outputStream* str) const; 18.232 +#endif 18.233 +}; 18.234 + 18.235 +class Type : public ResourceObj { 18.236 + public: 18.237 + static Type* parse_generic_signature(DescriptorStream* str); 18.238 + 18.239 + virtual ClassType* as_class() { return NULL; } 18.240 + virtual TypeVariable* as_variable() { return NULL; } 18.241 + virtual ArrayType* as_array() { return NULL; } 18.242 + virtual PrimitiveType* as_primitive() { return NULL; } 18.243 + 18.244 + virtual bool covariant_match(Type* gt, Context* ctx) = 0; 18.245 + virtual Type* canonicalize(Context* ctx, int ctx_depth) = 0; 18.246 + 18.247 + virtual void bind_variables_to_parameters(Descriptor* sig) = 0; 18.248 + 18.249 +#ifndef PRODUCT 18.250 + virtual void reify_signature(stringStream* ss, Context* ctx) = 0; 18.251 + virtual void print_on(outputStream* str) const = 0; 18.252 +#endif 18.253 +}; 18.254 + 18.255 +class ClassType : public Type { 18.256 + friend class ClassDescriptor; 18.257 + protected: 18.258 + Identifier* _identifier; 18.259 + GrowableArray<TypeArgument*> _type_arguments; 18.260 + ClassType* _outer_class; 18.261 + 18.262 + ClassType(Identifier* identifier, 18.263 + GrowableArray<TypeArgument*>& args, 18.264 + ClassType* outer) 18.265 + : _identifier(identifier), _type_arguments(args), _outer_class(outer) {} 18.266 + 18.267 + // Returns true if there are inner classes to read 18.268 + static Identifier* parse_generic_signature_simple( 18.269 + GrowableArray<TypeArgument*>* args, 18.270 + bool* has_inner, DescriptorStream* str); 18.271 + 18.272 + static ClassType* parse_generic_signature(ClassType* outer, 18.273 + DescriptorStream* str); 18.274 + static ClassType* from_symbol(Symbol* sym); 18.275 + 18.276 + public: 18.277 + ClassType* as_class() { return this; } 18.278 + 18.279 + static ClassType* parse_generic_signature(DescriptorStream* str); 18.280 + static ClassType* java_lang_Object(); 18.281 + 18.282 + Identifier* identifier() { return _identifier; } 18.283 + int type_arguments_length() { return _type_arguments.length(); } 18.284 + TypeArgument* type_argument_at(int i); 18.285 + 18.286 + virtual ClassType* outer_class() { return _outer_class; } 18.287 + 18.288 + bool covariant_match(Type* gt, Context* ctx); 18.289 + ClassType* canonicalize(Context* ctx, int context_depth); 18.290 + 18.291 + void bind_variables_to_parameters(Descriptor* sig); 18.292 + 18.293 +#ifndef PRODUCT 18.294 + void reify_signature(stringStream* ss, Context* ctx); 18.295 + void print_on(outputStream* str) const; 18.296 +#endif 18.297 +}; 18.298 + 18.299 +class TypeVariable : public Type { 18.300 + private: 18.301 + Identifier* _id; 18.302 + TypeParameter* _parameter; // assigned during linking 18.303 + 18.304 + // how many steps "out" from inner classes, -1 if method 18.305 + int _inner_depth; 18.306 + 18.307 + TypeVariable(Identifier* id) 18.308 + : _id(id), _parameter(NULL), _inner_depth(0) {} 18.309 + 18.310 + public: 18.311 + TypeVariable* as_variable() { return this; } 18.312 + 18.313 + static TypeVariable* parse_generic_signature(DescriptorStream* str); 18.314 + 18.315 + Identifier* identifier() { return _id; } 18.316 + TypeParameter* parameter() { return _parameter; } 18.317 + int inner_depth() { return _inner_depth; } 18.318 + 18.319 + void bind_variables_to_parameters(Descriptor* sig); 18.320 + 18.321 + Type* resolve(Context* ctx, int ctx_depth); 18.322 + bool covariant_match(Type* gt, Context* ctx); 18.323 + Type* canonicalize(Context* ctx, int ctx_depth); 18.324 + 18.325 +#ifndef PRODUCT 18.326 + void reify_signature(stringStream* ss, Context* ctx); 18.327 + void print_on(outputStream* str) const; 18.328 +#endif 18.329 +}; 18.330 + 18.331 +class ArrayType : public Type { 18.332 + private: 18.333 + Type* _base; 18.334 + 18.335 + ArrayType(Type* base) : _base(base) {} 18.336 + 18.337 + public: 18.338 + ArrayType* as_array() { return this; } 18.339 + 18.340 + static ArrayType* parse_generic_signature(DescriptorStream* str); 18.341 + 18.342 + bool covariant_match(Type* gt, Context* ctx); 18.343 + ArrayType* canonicalize(Context* ctx, int ctx_depth); 18.344 + 18.345 + void bind_variables_to_parameters(Descriptor* sig); 18.346 + 18.347 +#ifndef PRODUCT 18.348 + void reify_signature(stringStream* ss, Context* ctx); 18.349 + void print_on(outputStream* str) const; 18.350 +#endif 18.351 +}; 18.352 + 18.353 +class PrimitiveType : public Type { 18.354 + friend class Type; 18.355 + private: 18.356 + char _type; // includes V for void 18.357 + 18.358 + PrimitiveType(char& type) : _type(type) {} 18.359 + 18.360 + public: 18.361 + PrimitiveType* as_primitive() { return this; } 18.362 + 18.363 + bool covariant_match(Type* gt, Context* ctx); 18.364 + PrimitiveType* canonicalize(Context* ctx, int ctx_depth); 18.365 + 18.366 + void bind_variables_to_parameters(Descriptor* sig); 18.367 + 18.368 +#ifndef PRODUCT 18.369 + void reify_signature(stringStream* ss, Context* ctx); 18.370 + void print_on(outputStream* str) const; 18.371 +#endif 18.372 +}; 18.373 + 18.374 +class TypeArgument : public ResourceObj { 18.375 + private: 18.376 + Type* _lower_bound; 18.377 + Type* _upper_bound; // may be null or == _lower_bound 18.378 + 18.379 + TypeArgument(Type* lower_bound, Type* upper_bound) 18.380 + : _lower_bound(lower_bound), _upper_bound(upper_bound) {} 18.381 + 18.382 + public: 18.383 + 18.384 + static TypeArgument* parse_generic_signature(DescriptorStream* str); 18.385 + 18.386 + Type* lower_bound() { return _lower_bound; } 18.387 + Type* upper_bound() { return _upper_bound; } 18.388 + 18.389 + void bind_variables_to_parameters(Descriptor* sig); 18.390 + TypeArgument* canonicalize(Context* ctx, int ctx_depth); 18.391 + 18.392 + bool covariant_match(TypeArgument* a, Context* ctx); 18.393 + 18.394 +#ifndef PRODUCT 18.395 + void print_on(outputStream* str) const; 18.396 +#endif 18.397 +}; 18.398 + 18.399 + 18.400 +class Context : public ResourceObj { 18.401 + private: 18.402 + DescriptorCache* _cache; 18.403 + GrowableArray<ClassType*> _type_arguments; 18.404 + 18.405 + void reset_to_mark(int size); 18.406 + 18.407 + public: 18.408 + // When this object goes out of scope or 'destroy' is 18.409 + // called, then the application of the type to the 18.410 + // context is wound-back (unless it's been deactivated). 18.411 + class Mark : public StackObj { 18.412 + private: 18.413 + mutable Context* _context; 18.414 + int _marked_size; 18.415 + 18.416 + bool is_active() const { return _context != NULL; } 18.417 + void deactivate() const { _context = NULL; } 18.418 + 18.419 + public: 18.420 + Mark() : _context(NULL), _marked_size(0) {} 18.421 + Mark(Context* ctx, int sz) : _context(ctx), _marked_size(sz) {} 18.422 + Mark(const Mark& m) : _context(m._context), _marked_size(m._marked_size) { 18.423 + m.deactivate(); // Ownership is transferred 18.424 + } 18.425 + 18.426 + Mark& operator=(const Mark& cm) { 18.427 + destroy(); 18.428 + _context = cm._context; 18.429 + _marked_size = cm._marked_size; 18.430 + cm.deactivate(); 18.431 + return *this; 18.432 + } 18.433 + 18.434 + void destroy(); 18.435 + ~Mark() { destroy(); } 18.436 + }; 18.437 + 18.438 + Context(DescriptorCache* cache) : _cache(cache) {} 18.439 + 18.440 + Mark mark() { return Mark(this, _type_arguments.length()); } 18.441 + void apply_type_arguments(InstanceKlass* current, InstanceKlass* super,TRAPS); 18.442 + 18.443 + ClassType* at_depth(int i) const; 18.444 + 18.445 +#ifndef PRODUCT 18.446 + void print_on(outputStream* str) const; 18.447 +#endif 18.448 +}; 18.449 + 18.450 +/** 18.451 + * Contains a cache of descriptors for classes and methods so they can be 18.452 + * looked-up instead of reparsing each time they are needed. 18.453 + */ 18.454 +class DescriptorCache : public ResourceObj { 18.455 + private: 18.456 + ResourceHashtable<InstanceKlass*, ClassDescriptor*> _class_descriptors; 18.457 + ResourceHashtable<Method*, MethodDescriptor*> _method_descriptors; 18.458 + 18.459 + public: 18.460 + ClassDescriptor* descriptor_for(InstanceKlass* ikh, TRAPS); 18.461 + 18.462 + MethodDescriptor* descriptor_for(Method* mh, ClassDescriptor* cd, TRAPS); 18.463 + // Class descriptor derived from method holder 18.464 + MethodDescriptor* descriptor_for(Method* mh, TRAPS); 18.465 +}; 18.466 + 18.467 +} // namespace generic 18.468 + 18.469 +#endif // SHARE_VM_CLASSFILE_GENERICSIGNATURES_HPP 18.470 +
19.1 --- a/src/share/vm/classfile/javaClasses.cpp Mon Nov 05 19:33:44 2012 -0500 19.2 +++ b/src/share/vm/classfile/javaClasses.cpp Wed Nov 07 16:09:20 2012 -0800 19.3 @@ -1156,7 +1156,7 @@ 19.4 // Print stack trace element to resource allocated buffer 19.5 char* java_lang_Throwable::print_stack_element_to_buffer(Method* method, int bci) { 19.6 // Get strings and string lengths 19.7 - InstanceKlass* klass = InstanceKlass::cast(method->method_holder()); 19.8 + InstanceKlass* klass = method->method_holder(); 19.9 const char* klass_name = klass->external_name(); 19.10 int buf_len = (int)strlen(klass_name); 19.11 char* source_file_name; 19.12 @@ -1747,14 +1747,14 @@ 19.13 Handle element = ik->allocate_instance_handle(CHECK_0); 19.14 // Fill in class name 19.15 ResourceMark rm(THREAD); 19.16 - const char* str = InstanceKlass::cast(method->method_holder())->external_name(); 19.17 + const char* str = method->method_holder()->external_name(); 19.18 oop classname = StringTable::intern((char*) str, CHECK_0); 19.19 java_lang_StackTraceElement::set_declaringClass(element(), classname); 19.20 // Fill in method name 19.21 oop methodname = StringTable::intern(method->name(), CHECK_0); 19.22 java_lang_StackTraceElement::set_methodName(element(), methodname); 19.23 // Fill in source file name 19.24 - Symbol* source = InstanceKlass::cast(method->method_holder())->source_file_name(); 19.25 + Symbol* source = method->method_holder()->source_file_name(); 19.26 if (ShowHiddenFrames && source == NULL) 19.27 source = vmSymbols::unknown_class_name(); 19.28 oop filename = StringTable::intern(source, CHECK_0);
20.1 --- a/src/share/vm/classfile/systemDictionary.hpp Mon Nov 05 19:33:44 2012 -0500 20.2 +++ b/src/share/vm/classfile/systemDictionary.hpp Wed Nov 07 16:09:20 2012 -0800 20.3 @@ -137,6 +137,7 @@ 20.4 /* NOTE: needed too early in bootstrapping process to have checks based on JDK version */ \ 20.5 /* Universe::is_gte_jdk14x_version() is not set up by this point. */ \ 20.6 /* It's okay if this turns out to be NULL in non-1.4 JDKs. */ \ 20.7 + do_klass(lambda_MagicLambdaImpl_klass, java_lang_invoke_MagicLambdaImpl, Opt ) \ 20.8 do_klass(reflect_MagicAccessorImpl_klass, sun_reflect_MagicAccessorImpl, Opt ) \ 20.9 do_klass(reflect_MethodAccessorImpl_klass, sun_reflect_MethodAccessorImpl, Opt_Only_JDK14NewRef) \ 20.10 do_klass(reflect_ConstructorAccessorImpl_klass, sun_reflect_ConstructorAccessorImpl, Opt_Only_JDK14NewRef) \
21.1 --- a/src/share/vm/classfile/verifier.cpp Mon Nov 05 19:33:44 2012 -0500 21.2 +++ b/src/share/vm/classfile/verifier.cpp Wed Nov 07 16:09:20 2012 -0800 21.3 @@ -446,7 +446,7 @@ 21.4 bytecode_name = "<illegal>"; 21.5 } 21.6 } 21.7 - InstanceKlass* ik = InstanceKlass::cast(method->method_holder()); 21.8 + InstanceKlass* ik = method->method_holder(); 21.9 ss->indent().print_cr("Location:"); 21.10 streamIndentor si2(ss); 21.11 ss->indent().print_cr("%s.%s%s @%d: %s", 21.12 @@ -555,9 +555,10 @@ 21.13 if (was_recursively_verified()) return; 21.14 21.15 Method* m = methods->at(index); 21.16 - if (m->is_native() || m->is_abstract()) { 21.17 + if (m->is_native() || m->is_abstract() || m->is_overpass()) { 21.18 // If m is native or abstract, skip it. It is checked in class file 21.19 - // parser that methods do not override a final method. 21.20 + // parser that methods do not override a final method. Overpass methods 21.21 + // are trusted since the VM generates them. 21.22 continue; 21.23 } 21.24 verify_method(methodHandle(THREAD, m), CHECK_VERIFY(this)); 21.25 @@ -1849,7 +1850,7 @@ 21.26 if ((index <= 0) || (index >= nconstants)) { 21.27 verify_error(ErrorContext::bad_cp_index(bci, index), 21.28 "Illegal constant pool index %d in class %s", 21.29 - index, InstanceKlass::cast(cp->pool_holder())->external_name()); 21.30 + index, cp->pool_holder()->external_name()); 21.31 return; 21.32 } 21.33 } 21.34 @@ -1868,7 +1869,7 @@ 21.35 if ((types & (1 << tag)) == 0) { 21.36 verify_error(ErrorContext::bad_cp_index(bci, index), 21.37 "Illegal type at constant pool entry %d in class %s", 21.38 - index, InstanceKlass::cast(cp->pool_holder())->external_name()); 21.39 + index, cp->pool_holder()->external_name()); 21.40 return; 21.41 } 21.42 } 21.43 @@ -1880,7 +1881,7 @@ 21.44 if (!tag.is_klass() && !tag.is_unresolved_klass()) { 21.45 verify_error(ErrorContext::bad_cp_index(bci, index), 21.46 "Illegal type at constant pool entry %d in class %s", 21.47 - index, InstanceKlass::cast(cp->pool_holder())->external_name()); 21.48 + index, cp->pool_holder()->external_name()); 21.49 return; 21.50 } 21.51 } 21.52 @@ -2304,11 +2305,21 @@ 21.53 // Make sure the constant pool item is the right type 21.54 u2 index = bcs->get_index_u2(); 21.55 Bytecodes::Code opcode = bcs->raw_code(); 21.56 - unsigned int types = (opcode == Bytecodes::_invokeinterface 21.57 - ? 1 << JVM_CONSTANT_InterfaceMethodref 21.58 - : opcode == Bytecodes::_invokedynamic 21.59 - ? 1 << JVM_CONSTANT_InvokeDynamic 21.60 - : 1 << JVM_CONSTANT_Methodref); 21.61 + unsigned int types; 21.62 + switch (opcode) { 21.63 + case Bytecodes::_invokeinterface: 21.64 + types = 1 << JVM_CONSTANT_InterfaceMethodref; 21.65 + break; 21.66 + case Bytecodes::_invokedynamic: 21.67 + types = 1 << JVM_CONSTANT_InvokeDynamic; 21.68 + break; 21.69 + case Bytecodes::_invokespecial: 21.70 + types = (1 << JVM_CONSTANT_InterfaceMethodref) | 21.71 + (1 << JVM_CONSTANT_Methodref); 21.72 + break; 21.73 + default: 21.74 + types = 1 << JVM_CONSTANT_Methodref; 21.75 + } 21.76 verify_cp_type(bcs->bci(), index, cp, types, CHECK_VERIFY(this)); 21.77 21.78 // Get method name and signature
22.1 --- a/src/share/vm/classfile/vmSymbols.cpp Mon Nov 05 19:33:44 2012 -0500 22.2 +++ b/src/share/vm/classfile/vmSymbols.cpp Wed Nov 07 16:09:20 2012 -0800 22.3 @@ -507,7 +507,7 @@ 22.4 } 22.5 22.6 void vmIntrinsics::verify_method(ID actual_id, Method* m) { 22.7 - Symbol* mk = Klass::cast(m->method_holder())->name(); 22.8 + Symbol* mk = m->method_holder()->name(); 22.9 ID declared_id = match_method_with_klass(m, mk); 22.10 22.11 if (declared_id == actual_id) return; // success
23.1 --- a/src/share/vm/classfile/vmSymbols.hpp Mon Nov 05 19:33:44 2012 -0500 23.2 +++ b/src/share/vm/classfile/vmSymbols.hpp Wed Nov 07 16:09:20 2012 -0800 23.3 @@ -259,6 +259,7 @@ 23.4 template(java_lang_invoke_DontInline_signature, "Ljava/lang/invoke/DontInline;") \ 23.5 template(java_lang_invoke_LambdaForm_Compiled_signature, "Ljava/lang/invoke/LambdaForm$Compiled;") \ 23.6 template(java_lang_invoke_LambdaForm_Hidden_signature, "Ljava/lang/invoke/LambdaForm$Hidden;") \ 23.7 + template(java_lang_invoke_MagicLambdaImpl, "java/lang/invoke/MagicLambdaImpl") \ 23.8 /* internal up-calls made only by the JVM, via class sun.invoke.MethodHandleNatives: */ \ 23.9 template(findMethodHandleType_name, "findMethodHandleType") \ 23.10 template(findMethodHandleType_signature, "(Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/invoke/MethodType;") \
24.1 --- a/src/share/vm/code/compiledIC.cpp Mon Nov 05 19:33:44 2012 -0500 24.2 +++ b/src/share/vm/code/compiledIC.cpp Wed Nov 07 16:09:20 2012 -0800 24.3 @@ -191,8 +191,8 @@ 24.4 int index = klassItable::compute_itable_index(call_info->resolved_method()()); 24.5 entry = VtableStubs::create_stub(false, index, method()); 24.6 assert(entry != NULL, "entry not computed"); 24.7 - Klass* k = call_info->resolved_method()->method_holder(); 24.8 - assert(Klass::cast(k)->is_interface(), "sanity check"); 24.9 + InstanceKlass* k = call_info->resolved_method()->method_holder(); 24.10 + assert(k->is_interface(), "sanity check"); 24.11 InlineCacheBuffer::create_transition_stub(this, k, entry); 24.12 } else { 24.13 // Can be different than method->vtable_index(), due to package-private etc.
25.1 --- a/src/share/vm/code/dependencies.cpp Mon Nov 05 19:33:44 2012 -0500 25.2 +++ b/src/share/vm/code/dependencies.cpp Wed Nov 07 16:09:20 2012 -0800 25.3 @@ -829,7 +829,7 @@ 25.4 } 25.5 if ( !Dependencies::is_concrete_method(lm) 25.6 && !Dependencies::is_concrete_method(m) 25.7 - && Klass::cast(lm->method_holder())->is_subtype_of(m->method_holder())) 25.8 + && lm->method_holder()->is_subtype_of(m->method_holder())) 25.9 // Method m is overridden by lm, but both are non-concrete. 25.10 return true; 25.11 } 25.12 @@ -1160,7 +1160,11 @@ 25.13 25.14 // We could also return false if m does not yet appear to be 25.15 // executed, if the VM version supports this distinction also. 25.16 - return !m->is_abstract(); 25.17 + return !m->is_abstract() && 25.18 + !InstanceKlass::cast(m->method_holder())->is_interface(); 25.19 + // TODO: investigate whether default methods should be 25.20 + // considered as "concrete" in this situation. For now they 25.21 + // are not. 25.22 } 25.23 25.24
26.1 --- a/src/share/vm/code/nmethod.cpp Mon Nov 05 19:33:44 2012 -0500 26.2 +++ b/src/share/vm/code/nmethod.cpp Wed Nov 07 16:09:20 2012 -0800 26.3 @@ -1263,7 +1263,7 @@ 26.4 assert(_entry_bci != InvocationEntryBci, "wrong kind of nmethod"); 26.5 // Remove from list of active nmethods 26.6 if (method() != NULL) 26.7 - InstanceKlass::cast(method()->method_holder())->remove_osr_nmethod(this); 26.8 + method()->method_holder()->remove_osr_nmethod(this); 26.9 // Set entry as invalid 26.10 _entry_bci = InvalidOSREntryBci; 26.11 }
27.1 --- a/src/share/vm/compiler/compileBroker.cpp Mon Nov 05 19:33:44 2012 -0500 27.2 +++ b/src/share/vm/compiler/compileBroker.cpp Wed Nov 07 16:09:20 2012 -0800 27.3 @@ -1051,7 +1051,7 @@ 27.4 guarantee(!method->is_abstract(), "cannot compile abstract methods"); 27.5 assert(method->method_holder()->oop_is_instance(), 27.6 "sanity check"); 27.7 - assert(!InstanceKlass::cast(method->method_holder())->is_not_initialized(), 27.8 + assert(!method->method_holder()->is_not_initialized(), 27.9 "method holder must be initialized"); 27.10 assert(!method->is_method_handle_intrinsic(), "do not enqueue these guys"); 27.11 27.12 @@ -1206,7 +1206,7 @@ 27.13 assert(method->method_holder()->oop_is_instance(), "not an instance method"); 27.14 assert(osr_bci == InvocationEntryBci || (0 <= osr_bci && osr_bci < method->code_size()), "bci out of range"); 27.15 assert(!method->is_abstract() && (osr_bci == InvocationEntryBci || !method->is_native()), "cannot compile abstract/native methods"); 27.16 - assert(!InstanceKlass::cast(method->method_holder())->is_not_initialized(), "method holder must be initialized"); 27.17 + assert(!method->method_holder()->is_not_initialized(), "method holder must be initialized"); 27.18 27.19 if (!TieredCompilation) { 27.20 comp_level = CompLevel_highest_tier;
28.1 --- a/src/share/vm/compiler/compilerOracle.cpp Mon Nov 05 19:33:44 2012 -0500 28.2 +++ b/src/share/vm/compiler/compilerOracle.cpp Wed Nov 07 16:09:20 2012 -0800 28.3 @@ -67,7 +67,7 @@ 28.4 28.5 // utility method 28.6 MethodMatcher* find(methodHandle method) { 28.7 - Symbol* class_name = Klass::cast(method->method_holder())->name(); 28.8 + Symbol* class_name = method->method_holder()->name(); 28.9 Symbol* method_name = method->name(); 28.10 for (MethodMatcher* current = this; current != NULL; current = current->_next) { 28.11 if (match(class_name, current->class_name(), current->_class_mode) && 28.12 @@ -624,7 +624,7 @@ 28.13 assert(has_command_file(), "command file must be specified"); 28.14 fileStream stream(fopen(cc_file(), "at")); 28.15 stream.print("exclude "); 28.16 - Klass::cast(method->method_holder())->name()->print_symbol_on(&stream); 28.17 + method->method_holder()->name()->print_symbol_on(&stream); 28.18 stream.print("."); 28.19 method->name()->print_symbol_on(&stream); 28.20 method->signature()->print_symbol_on(&stream);
29.1 --- a/src/share/vm/compiler/disassembler.cpp Mon Nov 05 19:33:44 2012 -0500 29.2 +++ b/src/share/vm/compiler/disassembler.cpp Wed Nov 07 16:09:20 2012 -0800 29.3 @@ -55,16 +55,18 @@ 29.4 bool Disassembler::_tried_to_load_library = false; 29.5 29.6 // This routine is in the shared library: 29.7 +Disassembler::decode_func_virtual Disassembler::_decode_instructions_virtual = NULL; 29.8 Disassembler::decode_func Disassembler::_decode_instructions = NULL; 29.9 29.10 static const char hsdis_library_name[] = "hsdis-"HOTSPOT_LIB_ARCH; 29.11 -static const char decode_instructions_name[] = "decode_instructions_virtual"; 29.12 - 29.13 +static const char decode_instructions_virtual_name[] = "decode_instructions_virtual"; 29.14 +static const char decode_instructions_name[] = "decode_instructions"; 29.15 +static bool use_new_version = true; 29.16 #define COMMENT_COLUMN 40 LP64_ONLY(+8) /*could be an option*/ 29.17 #define BYTES_COMMENT ";..." /* funky byte display comment */ 29.18 29.19 bool Disassembler::load_library() { 29.20 - if (_decode_instructions != NULL) { 29.21 + if (_decode_instructions_virtual != NULL || _decode_instructions != NULL) { 29.22 // Already succeeded. 29.23 return true; 29.24 } 29.25 @@ -123,11 +125,19 @@ 29.26 _library = os::dll_load(buf, ebuf, sizeof ebuf); 29.27 } 29.28 if (_library != NULL) { 29.29 + _decode_instructions_virtual = CAST_TO_FN_PTR(Disassembler::decode_func_virtual, 29.30 + os::dll_lookup(_library, decode_instructions_virtual_name)); 29.31 + } 29.32 + if (_decode_instructions_virtual == NULL) { 29.33 + // could not spot in new version, try old version 29.34 _decode_instructions = CAST_TO_FN_PTR(Disassembler::decode_func, 29.35 os::dll_lookup(_library, decode_instructions_name)); 29.36 + use_new_version = false; 29.37 + } else { 29.38 + use_new_version = true; 29.39 } 29.40 _tried_to_load_library = true; 29.41 - if (_decode_instructions == NULL) { 29.42 + if (_decode_instructions_virtual == NULL && _decode_instructions == NULL) { 29.43 tty->print_cr("Could not load %s; %s; %s", buf, 29.44 ((_library != NULL) 29.45 ? "entry point is missing" 29.46 @@ -450,17 +460,31 @@ 29.47 // This is mainly for debugging the library itself. 29.48 FILE* out = stdout; 29.49 FILE* xmlout = (_print_raw > 1 ? out : NULL); 29.50 - return (address) 29.51 - (*Disassembler::_decode_instructions)((uintptr_t)start, (uintptr_t)end, 29.52 - start, end - start, 29.53 + return use_new_version ? 29.54 + (address) 29.55 + (*Disassembler::_decode_instructions_virtual)((uintptr_t)start, (uintptr_t)end, 29.56 + start, end - start, 29.57 + NULL, (void*) xmlout, 29.58 + NULL, (void*) out, 29.59 + options(), 0/*nice new line*/) 29.60 + : 29.61 + (address) 29.62 + (*Disassembler::_decode_instructions)(start, end, 29.63 NULL, (void*) xmlout, 29.64 NULL, (void*) out, 29.65 options()); 29.66 } 29.67 29.68 - return (address) 29.69 - (*Disassembler::_decode_instructions)((uintptr_t)start, (uintptr_t)end, 29.70 - start, end - start, 29.71 + return use_new_version ? 29.72 + (address) 29.73 + (*Disassembler::_decode_instructions_virtual)((uintptr_t)start, (uintptr_t)end, 29.74 + start, end - start, 29.75 + &event_to_env, (void*) this, 29.76 + &printf_to_env, (void*) this, 29.77 + options(), 0/*nice new line*/) 29.78 + : 29.79 + (address) 29.80 + (*Disassembler::_decode_instructions)(start, end, 29.81 &event_to_env, (void*) this, 29.82 &printf_to_env, (void*) this, 29.83 options());
30.1 --- a/src/share/vm/compiler/disassembler.hpp Mon Nov 05 19:33:44 2012 -0500 30.2 +++ b/src/share/vm/compiler/disassembler.hpp Wed Nov 07 16:09:20 2012 -0800 30.3 @@ -49,18 +49,27 @@ 30.4 friend class decode_env; 30.5 private: 30.6 // this is the type of the dll entry point: 30.7 - typedef void* (*decode_func)(uintptr_t start_va, uintptr_t end_va, 30.8 + typedef void* (*decode_func_virtual)(uintptr_t start_va, uintptr_t end_va, 30.9 unsigned char* buffer, uintptr_t length, 30.10 void* (*event_callback)(void*, const char*, void*), 30.11 void* event_stream, 30.12 int (*printf_callback)(void*, const char*, ...), 30.13 void* printf_stream, 30.14 + const char* options, 30.15 + int newline); 30.16 + // this is the type of the dll entry point for old version: 30.17 + typedef void* (*decode_func)(void* start_va, void* end_va, 30.18 + void* (*event_callback)(void*, const char*, void*), 30.19 + void* event_stream, 30.20 + int (*printf_callback)(void*, const char*, ...), 30.21 + void* printf_stream, 30.22 const char* options); 30.23 // points to the library. 30.24 static void* _library; 30.25 // bailout 30.26 static bool _tried_to_load_library; 30.27 // points to the decode function. 30.28 + static decode_func_virtual _decode_instructions_virtual; 30.29 static decode_func _decode_instructions; 30.30 // tries to load library and return whether it succedded. 30.31 static bool load_library(); 30.32 @@ -85,7 +94,9 @@ 30.33 30.34 public: 30.35 static bool can_decode() { 30.36 - return (_decode_instructions != NULL) || load_library(); 30.37 + return (_decode_instructions_virtual != NULL) || 30.38 + (_decode_instructions != NULL) || 30.39 + load_library(); 30.40 } 30.41 static void decode(CodeBlob *cb, outputStream* st = NULL); 30.42 static void decode(nmethod* nm, outputStream* st = NULL);
31.1 --- a/src/share/vm/interpreter/linkResolver.cpp Mon Nov 05 19:33:44 2012 -0500 31.2 +++ b/src/share/vm/interpreter/linkResolver.cpp Wed Nov 07 16:09:20 2012 -0800 31.3 @@ -23,6 +23,7 @@ 31.4 */ 31.5 31.6 #include "precompiled.hpp" 31.7 +#include "classfile/defaultMethods.hpp" 31.8 #include "classfile/systemDictionary.hpp" 31.9 #include "classfile/vmSymbols.hpp" 31.10 #include "compiler/compileBroker.hpp" 31.11 @@ -132,7 +133,7 @@ 31.12 // don't force compilation, resolve was on behalf of compiler 31.13 return; 31.14 } 31.15 - if (InstanceKlass::cast(selected_method->method_holder())->is_not_initialized()) { 31.16 + if (selected_method->method_holder()->is_not_initialized()) { 31.17 // 'is_not_initialized' means not only '!is_initialized', but also that 31.18 // initialization has not been started yet ('!being_initialized') 31.19 // Do not force compilation of methods in uninitialized classes. 31.20 @@ -404,21 +405,13 @@ 31.21 Symbol* method_name, Symbol* method_signature, 31.22 KlassHandle current_klass, bool check_access, TRAPS) { 31.23 31.24 - // 1. check if klass is not interface 31.25 - if (resolved_klass->is_interface()) { 31.26 - ResourceMark rm(THREAD); 31.27 - char buf[200]; 31.28 - jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected", Klass::cast(resolved_klass())->external_name()); 31.29 - THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); 31.30 - } 31.31 - 31.32 Handle nested_exception; 31.33 31.34 - // 2. lookup method in resolved klass and its super klasses 31.35 + // 1. lookup method in resolved klass and its super klasses 31.36 lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK); 31.37 31.38 if (resolved_method.is_null()) { // not found in the class hierarchy 31.39 - // 3. lookup method in all the interfaces implemented by the resolved klass 31.40 + // 2. lookup method in all the interfaces implemented by the resolved klass 31.41 lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK); 31.42 31.43 if (resolved_method.is_null()) { 31.44 @@ -432,7 +425,7 @@ 31.45 } 31.46 31.47 if (resolved_method.is_null()) { 31.48 - // 4. method lookup failed 31.49 + // 3. method lookup failed 31.50 ResourceMark rm(THREAD); 31.51 THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(), 31.52 Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()), 31.53 @@ -442,6 +435,15 @@ 31.54 } 31.55 } 31.56 31.57 + // 4. check if klass is not interface 31.58 + if (resolved_klass->is_interface() && resolved_method->is_abstract()) { 31.59 + ResourceMark rm(THREAD); 31.60 + char buf[200]; 31.61 + jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected", 31.62 + resolved_klass()->external_name()); 31.63 + THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); 31.64 + } 31.65 + 31.66 // 5. check if method is concrete 31.67 if (resolved_method->is_abstract() && !resolved_klass->is_abstract()) { 31.68 ResourceMark rm(THREAD); 31.69 @@ -464,7 +466,7 @@ 31.70 31.71 // check loader constraints 31.72 Handle loader (THREAD, InstanceKlass::cast(current_klass())->class_loader()); 31.73 - Handle class_loader (THREAD, InstanceKlass::cast(resolved_method->method_holder())->class_loader()); 31.74 + Handle class_loader (THREAD, resolved_method->method_holder()->class_loader()); 31.75 { 31.76 ResourceMark rm(THREAD); 31.77 char* failed_type_name = 31.78 @@ -526,7 +528,7 @@ 31.79 if (check_access) { 31.80 HandleMark hm(THREAD); 31.81 Handle loader (THREAD, InstanceKlass::cast(current_klass())->class_loader()); 31.82 - Handle class_loader (THREAD, InstanceKlass::cast(resolved_method->method_holder())->class_loader()); 31.83 + Handle class_loader (THREAD, resolved_method->method_holder()->class_loader()); 31.84 { 31.85 ResourceMark rm(THREAD); 31.86 char* failed_type_name = 31.87 @@ -743,6 +745,27 @@ 31.88 Symbol* method_name, Symbol* method_signature, 31.89 KlassHandle current_klass, bool check_access, TRAPS) { 31.90 31.91 + if (resolved_klass->is_interface() && current_klass() != NULL) { 31.92 + // If the target class is a direct interface, treat this as a "super" 31.93 + // default call. 31.94 + // 31.95 + // If the current method is an overpass that happens to call a direct 31.96 + // super-interface's method, then we'll end up rerunning the default method 31.97 + // analysis even though we don't need to, but that's ok since it will end 31.98 + // up with the same answer. 31.99 + InstanceKlass* ik = InstanceKlass::cast(current_klass()); 31.100 + Array<Klass*>* interfaces = ik->local_interfaces(); 31.101 + int num_interfaces = interfaces->length(); 31.102 + for (int index = 0; index < num_interfaces; index++) { 31.103 + if (interfaces->at(index) == resolved_klass()) { 31.104 + Method* method = DefaultMethods::find_super_default(current_klass(), 31.105 + resolved_klass(), method_name, method_signature, CHECK); 31.106 + resolved_method = methodHandle(THREAD, method); 31.107 + return; 31.108 + } 31.109 + } 31.110 + } 31.111 + 31.112 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); 31.113 31.114 // check if method name is <init>, that it is found in same klass as static type 31.115 @@ -784,11 +807,17 @@ 31.116 { KlassHandle method_klass = KlassHandle(THREAD, 31.117 resolved_method->method_holder()); 31.118 31.119 - if (check_access && 31.120 + const bool direct_calling_default_method = 31.121 + resolved_klass() != NULL && resolved_method() != NULL && 31.122 + resolved_klass->is_interface() && !resolved_method->is_abstract(); 31.123 + 31.124 + if (!direct_calling_default_method && 31.125 + check_access && 31.126 // a) check if ACC_SUPER flag is set for the current class 31.127 current_klass->is_super() && 31.128 // b) check if the method class is a superclass of the current class (superclass relation is not reflexive!) 31.129 - current_klass->is_subtype_of(method_klass()) && current_klass() != method_klass() && 31.130 + current_klass->is_subtype_of(method_klass()) && 31.131 + current_klass() != method_klass() && 31.132 // c) check if the method is not <init> 31.133 resolved_method->name() != vmSymbols::object_initializer_name()) { 31.134 // Lookup super method 31.135 @@ -881,12 +910,12 @@ 31.136 31.137 // Virtual methods cannot be resolved before its klass has been linked, for otherwise the Method*'s 31.138 // has not been rewritten, and the vtable initialized. 31.139 - assert(InstanceKlass::cast(resolved_method->method_holder())->is_linked(), "must be linked"); 31.140 + assert(resolved_method->method_holder()->is_linked(), "must be linked"); 31.141 31.142 // Virtual methods cannot be resolved before its klass has been linked, for otherwise the Method*'s 31.143 // has not been rewritten, and the vtable initialized. Make sure to do this after the nullcheck, since 31.144 // a missing receiver might result in a bogus lookup. 31.145 - assert(InstanceKlass::cast(resolved_method->method_holder())->is_linked(), "must be linked"); 31.146 + assert(resolved_method->method_holder()->is_linked(), "must be linked"); 31.147 31.148 // do lookup based on receiver klass using the vtable index 31.149 if (resolved_method->method_holder()->is_interface()) { // miranda method
32.1 --- a/src/share/vm/oops/constMethod.cpp Mon Nov 05 19:33:44 2012 -0500 32.2 +++ b/src/share/vm/oops/constMethod.cpp Wed Nov 07 16:09:20 2012 -0800 32.3 @@ -34,29 +34,30 @@ 32.4 const u2 ConstMethod::UNSET_IDNUM = 0xFFFF; 32.5 32.6 ConstMethod* ConstMethod::allocate(ClassLoaderData* loader_data, 32.7 - int byte_code_size, 32.8 - int compressed_line_number_size, 32.9 - int localvariable_table_length, 32.10 - int exception_table_length, 32.11 - int checked_exceptions_length, 32.12 - TRAPS) { 32.13 + int byte_code_size, 32.14 + int compressed_line_number_size, 32.15 + int localvariable_table_length, 32.16 + int exception_table_length, 32.17 + int checked_exceptions_length, 32.18 + MethodType method_type, 32.19 + TRAPS) { 32.20 int size = ConstMethod::size(byte_code_size, 32.21 compressed_line_number_size, 32.22 localvariable_table_length, 32.23 exception_table_length, 32.24 checked_exceptions_length); 32.25 return new (loader_data, size, true, THREAD) ConstMethod( 32.26 - byte_code_size, compressed_line_number_size, 32.27 - localvariable_table_length, exception_table_length, 32.28 - checked_exceptions_length, size); 32.29 + byte_code_size, compressed_line_number_size, localvariable_table_length, 32.30 + exception_table_length, checked_exceptions_length, method_type, size); 32.31 } 32.32 32.33 ConstMethod::ConstMethod(int byte_code_size, 32.34 - int compressed_line_number_size, 32.35 - int localvariable_table_length, 32.36 - int exception_table_length, 32.37 - int checked_exceptions_length, 32.38 - int size) { 32.39 + int compressed_line_number_size, 32.40 + int localvariable_table_length, 32.41 + int exception_table_length, 32.42 + int checked_exceptions_length, 32.43 + MethodType method_type, 32.44 + int size) { 32.45 32.46 No_Safepoint_Verifier no_safepoint; 32.47 set_interpreter_kind(Interpreter::invalid); 32.48 @@ -69,6 +70,7 @@ 32.49 compressed_line_number_size, 32.50 localvariable_table_length, 32.51 exception_table_length); 32.52 + set_method_type(method_type); 32.53 assert(this->size() == size, "wrong size for object"); 32.54 } 32.55 32.56 @@ -111,8 +113,7 @@ 32.57 } 32.58 32.59 Method* ConstMethod::method() const { 32.60 - return InstanceKlass::cast(_constants->pool_holder())->method_with_idnum( 32.61 - _method_idnum); 32.62 + return _constants->pool_holder()->method_with_idnum(_method_idnum); 32.63 } 32.64 32.65 // linenumber table - note that length is unknown until decompression,
33.1 --- a/src/share/vm/oops/constMethod.hpp Mon Nov 05 19:33:44 2012 -0500 33.2 +++ b/src/share/vm/oops/constMethod.hpp Wed Nov 07 16:09:20 2012 -0800 33.3 @@ -108,12 +108,17 @@ 33.4 33.5 class ConstMethod : public MetaspaceObj { 33.6 friend class VMStructs; 33.7 + 33.8 +public: 33.9 + typedef enum { NORMAL, OVERPASS } MethodType; 33.10 + 33.11 private: 33.12 enum { 33.13 _has_linenumber_table = 1, 33.14 _has_checked_exceptions = 2, 33.15 _has_localvariable_table = 4, 33.16 - _has_exception_table = 8 33.17 + _has_exception_table = 8, 33.18 + _is_overpass = 16 33.19 }; 33.20 33.21 // Bit vector of signature 33.22 @@ -145,19 +150,22 @@ 33.23 33.24 // Constructor 33.25 ConstMethod(int byte_code_size, 33.26 - int compressed_line_number_size, 33.27 - int localvariable_table_length, 33.28 - int exception_table_length, 33.29 - int checked_exceptions_length, 33.30 - int size); 33.31 + int compressed_line_number_size, 33.32 + int localvariable_table_length, 33.33 + int exception_table_length, 33.34 + int checked_exceptions_length, 33.35 + MethodType is_overpass, 33.36 + int size); 33.37 public: 33.38 + 33.39 static ConstMethod* allocate(ClassLoaderData* loader_data, 33.40 - int byte_code_size, 33.41 - int compressed_line_number_size, 33.42 - int localvariable_table_length, 33.43 - int exception_table_length, 33.44 - int checked_exceptions_length, 33.45 - TRAPS); 33.46 + int byte_code_size, 33.47 + int compressed_line_number_size, 33.48 + int localvariable_table_length, 33.49 + int exception_table_length, 33.50 + int checked_exceptions_length, 33.51 + MethodType mt, 33.52 + TRAPS); 33.53 33.54 bool is_constMethod() const { return true; } 33.55 33.56 @@ -179,6 +187,19 @@ 33.57 bool has_exception_handler() const 33.58 { return (_flags & _has_exception_table) != 0; } 33.59 33.60 + MethodType method_type() const { 33.61 + return ((_flags & _is_overpass) == 0) ? NORMAL : OVERPASS; 33.62 + } 33.63 + 33.64 + void set_method_type(MethodType mt) { 33.65 + if (mt == NORMAL) { 33.66 + _flags &= ~(_is_overpass); 33.67 + } else { 33.68 + _flags |= _is_overpass; 33.69 + } 33.70 + } 33.71 + 33.72 + 33.73 void set_interpreter_kind(int kind) { _interpreter_kind = kind; } 33.74 int interpreter_kind(void) const { return _interpreter_kind; } 33.75
34.1 --- a/src/share/vm/oops/constantPool.cpp Mon Nov 05 19:33:44 2012 -0500 34.2 +++ b/src/share/vm/oops/constantPool.cpp Wed Nov 07 16:09:20 2012 -0800 34.3 @@ -228,7 +228,7 @@ 34.4 } else { 34.5 do_resolve = true; 34.6 name = this_oop->unresolved_klass_at(which); 34.7 - loader = Handle(THREAD, InstanceKlass::cast(this_oop->pool_holder())->class_loader()); 34.8 + loader = Handle(THREAD, this_oop->pool_holder()->class_loader()); 34.9 } 34.10 } 34.11 } // unlocking constantPool 34.12 @@ -247,7 +247,7 @@ 34.13 34.14 if (do_resolve) { 34.15 // this_oop must be unlocked during resolve_or_fail 34.16 - oop protection_domain = Klass::cast(this_oop->pool_holder())->protection_domain(); 34.17 + oop protection_domain = this_oop->pool_holder()->protection_domain(); 34.18 Handle h_prot (THREAD, protection_domain); 34.19 Klass* k_oop = SystemDictionary::resolve_or_fail(name, loader, h_prot, true, THREAD); 34.20 KlassHandle k; 34.21 @@ -315,7 +315,7 @@ 34.22 vframeStream vfst(JavaThread::current()); 34.23 if (!vfst.at_end()) { 34.24 line_number = vfst.method()->line_number_from_bci(vfst.bci()); 34.25 - Symbol* s = InstanceKlass::cast(vfst.method()->method_holder())->source_file_name(); 34.26 + Symbol* s = vfst.method()->method_holder()->source_file_name(); 34.27 if (s != NULL) { 34.28 source_file = s->as_C_string(); 34.29 } 34.30 @@ -325,11 +325,11 @@ 34.31 // only print something if the classes are different 34.32 if (source_file != NULL) { 34.33 tty->print("RESOLVE %s %s %s:%d\n", 34.34 - InstanceKlass::cast(this_oop->pool_holder())->external_name(), 34.35 + this_oop->pool_holder()->external_name(), 34.36 InstanceKlass::cast(k())->external_name(), source_file, line_number); 34.37 } else { 34.38 tty->print("RESOLVE %s %s\n", 34.39 - InstanceKlass::cast(this_oop->pool_holder())->external_name(), 34.40 + this_oop->pool_holder()->external_name(), 34.41 InstanceKlass::cast(k())->external_name()); 34.42 } 34.43 } 34.44 @@ -339,7 +339,7 @@ 34.45 // Only updated constant pool - if it is resolved. 34.46 do_resolve = this_oop->tag_at(which).is_unresolved_klass(); 34.47 if (do_resolve) { 34.48 - ClassLoaderData* this_key = InstanceKlass::cast(this_oop->pool_holder())->class_loader_data(); 34.49 + ClassLoaderData* this_key = this_oop->pool_holder()->class_loader_data(); 34.50 if (!this_key->is_the_null_class_loader_data()) { 34.51 this_key->record_dependency(k(), CHECK_NULL); // Can throw OOM 34.52 } 34.53 @@ -367,8 +367,8 @@ 34.54 assert(entry.is_unresolved(), "must be either symbol or klass"); 34.55 Thread *thread = Thread::current(); 34.56 Symbol* name = entry.get_symbol(); 34.57 - oop loader = InstanceKlass::cast(this_oop->pool_holder())->class_loader(); 34.58 - oop protection_domain = Klass::cast(this_oop->pool_holder())->protection_domain(); 34.59 + oop loader = this_oop->pool_holder()->class_loader(); 34.60 + oop protection_domain = this_oop->pool_holder()->protection_domain(); 34.61 Handle h_prot (thread, protection_domain); 34.62 Handle h_loader (thread, loader); 34.63 Klass* k = SystemDictionary::find(name, h_loader, h_prot, thread); 34.64 @@ -409,8 +409,8 @@ 34.65 } else { 34.66 assert(entry.is_unresolved(), "must be either symbol or klass"); 34.67 Symbol* name = entry.get_symbol(); 34.68 - oop loader = InstanceKlass::cast(this_oop->pool_holder())->class_loader(); 34.69 - oop protection_domain = Klass::cast(this_oop->pool_holder())->protection_domain(); 34.70 + oop loader = this_oop->pool_holder()->class_loader(); 34.71 + oop protection_domain = this_oop->pool_holder()->protection_domain(); 34.72 Handle h_loader(THREAD, loader); 34.73 Handle h_prot (THREAD, protection_domain); 34.74 KlassHandle k(THREAD, SystemDictionary::find(name, h_loader, h_prot, THREAD)); 34.75 @@ -1143,16 +1143,21 @@ 34.76 int from_oplen = operand_array_length(from_cp->operands()); 34.77 int old_oplen = operand_array_length(to_cp->operands()); 34.78 if (from_oplen != 0) { 34.79 + ClassLoaderData* loader_data = to_cp->pool_holder()->class_loader_data(); 34.80 // append my operands to the target's operands array 34.81 if (old_oplen == 0) { 34.82 - to_cp->set_operands(from_cp->operands()); // reuse; do not merge 34.83 + // Can't just reuse from_cp's operand list because of deallocation issues 34.84 + int len = from_cp->operands()->length(); 34.85 + Array<u2>* new_ops = MetadataFactory::new_array<u2>(loader_data, len, CHECK); 34.86 + Copy::conjoint_memory_atomic( 34.87 + from_cp->operands()->adr_at(0), new_ops->adr_at(0), len * sizeof(u2)); 34.88 + to_cp->set_operands(new_ops); 34.89 } else { 34.90 int old_len = to_cp->operands()->length(); 34.91 int from_len = from_cp->operands()->length(); 34.92 int old_off = old_oplen * sizeof(u2); 34.93 int from_off = from_oplen * sizeof(u2); 34.94 // Use the metaspace for the destination constant pool 34.95 - ClassLoaderData* loader_data = to_cp->pool_holder()->class_loader_data(); 34.96 Array<u2>* new_operands = MetadataFactory::new_array<u2>(loader_data, old_len + from_len, CHECK); 34.97 int fillp = 0, len = 0; 34.98 // first part of dest 34.99 @@ -1785,7 +1790,7 @@ 34.100 assert(cp_patches->at(index).is_null(), 34.101 err_msg("Unused constant pool patch at %d in class file %s", 34.102 index, 34.103 - InstanceKlass::cast(pool_holder())->external_name())); 34.104 + pool_holder()->external_name())); 34.105 } 34.106 #endif // ASSERT 34.107 } 34.108 @@ -1943,7 +1948,7 @@ 34.109 st->print(" for "); 34.110 pool_holder()->print_value_on(st); 34.111 if (pool_holder() != NULL) { 34.112 - bool extra = (InstanceKlass::cast(pool_holder())->constants() != this); 34.113 + bool extra = (pool_holder()->constants() != this); 34.114 if (extra) st->print(" (extra)"); 34.115 } 34.116 if (cache() != NULL) {
35.1 --- a/src/share/vm/oops/constantPool.hpp Mon Nov 05 19:33:44 2012 -0500 35.2 +++ b/src/share/vm/oops/constantPool.hpp Wed Nov 07 16:09:20 2012 -0800 35.3 @@ -86,8 +86,8 @@ 35.4 friend class Universe; // For null constructor 35.5 private: 35.6 Array<u1>* _tags; // the tag array describing the constant pool's contents 35.7 - ConstantPoolCache* _cache; // the cache holding interpreter runtime information 35.8 - Klass* _pool_holder; // the corresponding class 35.9 + ConstantPoolCache* _cache; // the cache holding interpreter runtime information 35.10 + InstanceKlass* _pool_holder; // the corresponding class 35.11 Array<u2>* _operands; // for variable-sized (InvokeDynamic) nodes, usually empty 35.12 35.13 // Array of resolved objects from the constant pool and map from resolved 35.14 @@ -193,9 +193,9 @@ 35.15 void set_on_stack(const bool value); 35.16 35.17 // Klass holding pool 35.18 - Klass* pool_holder() const { return _pool_holder; } 35.19 - void set_pool_holder(Klass* k) { _pool_holder = k; } 35.20 - Klass** pool_holder_addr() { return &_pool_holder; } 35.21 + InstanceKlass* pool_holder() const { return _pool_holder; } 35.22 + void set_pool_holder(InstanceKlass* k) { _pool_holder = k; } 35.23 + InstanceKlass** pool_holder_addr() { return &_pool_holder; } 35.24 35.25 // Interpreter runtime support 35.26 ConstantPoolCache* cache() const { return _cache; }
36.1 --- a/src/share/vm/oops/cpCache.cpp Mon Nov 05 19:33:44 2012 -0500 36.2 +++ b/src/share/vm/oops/cpCache.cpp Wed Nov 07 16:09:20 2012 -0800 36.3 @@ -231,8 +231,8 @@ 36.4 36.5 36.6 void ConstantPoolCacheEntry::set_interface_call(methodHandle method, int index) { 36.7 - Klass* interf = method->method_holder(); 36.8 - assert(InstanceKlass::cast(interf)->is_interface(), "must be an interface"); 36.9 + InstanceKlass* interf = method->method_holder(); 36.10 + assert(interf->is_interface(), "must be an interface"); 36.11 assert(!method->is_final_method(), "interfaces do not have final methods; cannot link to one here"); 36.12 set_f1(interf); 36.13 set_f2(index); 36.14 @@ -421,7 +421,7 @@ 36.15 if (!(*trace_name_printed)) { 36.16 // RC_TRACE_MESG macro has an embedded ResourceMark 36.17 RC_TRACE_MESG(("adjust: name=%s", 36.18 - Klass::cast(old_method->method_holder())->external_name())); 36.19 + old_method->method_holder()->external_name())); 36.20 *trace_name_printed = true; 36.21 } 36.22 // RC_TRACE macro has an embedded ResourceMark 36.23 @@ -449,7 +449,7 @@ 36.24 if (!(*trace_name_printed)) { 36.25 // RC_TRACE_MESG macro has an embedded ResourceMark 36.26 RC_TRACE_MESG(("adjust: name=%s", 36.27 - Klass::cast(old_method->method_holder())->external_name())); 36.28 + old_method->method_holder()->external_name())); 36.29 *trace_name_printed = true; 36.30 } 36.31 // RC_TRACE macro has an embedded ResourceMark
37.1 --- a/src/share/vm/oops/instanceKlass.cpp Mon Nov 05 19:33:44 2012 -0500 37.2 +++ b/src/share/vm/oops/instanceKlass.cpp Wed Nov 07 16:09:20 2012 -0800 37.3 @@ -743,6 +743,35 @@ 37.4 } 37.5 } 37.6 37.7 + if (this_oop->has_default_methods()) { 37.8 + // Step 7.5: initialize any interfaces which have default methods 37.9 + for (int i = 0; i < this_oop->local_interfaces()->length(); ++i) { 37.10 + Klass* iface = this_oop->local_interfaces()->at(i); 37.11 + InstanceKlass* ik = InstanceKlass::cast(iface); 37.12 + if (ik->has_default_methods() && ik->should_be_initialized()) { 37.13 + ik->initialize(THREAD); 37.14 + 37.15 + if (HAS_PENDING_EXCEPTION) { 37.16 + Handle e(THREAD, PENDING_EXCEPTION); 37.17 + CLEAR_PENDING_EXCEPTION; 37.18 + { 37.19 + EXCEPTION_MARK; 37.20 + // Locks object, set state, and notify all waiting threads 37.21 + this_oop->set_initialization_state_and_notify( 37.22 + initialization_error, THREAD); 37.23 + 37.24 + // ignore any exception thrown, superclass initialization error is 37.25 + // thrown below 37.26 + CLEAR_PENDING_EXCEPTION; 37.27 + } 37.28 + DTRACE_CLASSINIT_PROBE_WAIT( 37.29 + super__failed, InstanceKlass::cast(this_oop()), -1, wait); 37.30 + THROW_OOP(e()); 37.31 + } 37.32 + } 37.33 + } 37.34 + } 37.35 + 37.36 // Step 8 37.37 { 37.38 assert(THREAD->is_Java_thread(), "non-JavaThread in initialize_impl"); 37.39 @@ -1252,11 +1281,7 @@ 37.40 } 37.41 #endif 37.42 37.43 -Method* InstanceKlass::find_method(Symbol* name, Symbol* signature) const { 37.44 - return InstanceKlass::find_method(methods(), name, signature); 37.45 -} 37.46 - 37.47 -Method* InstanceKlass::find_method(Array<Method*>* methods, Symbol* name, Symbol* signature) { 37.48 +static int binary_search(Array<Method*>* methods, Symbol* name) { 37.49 int len = methods->length(); 37.50 // methods are sorted, so do binary search 37.51 int l = 0; 37.52 @@ -1267,43 +1292,70 @@ 37.53 assert(m->is_method(), "must be method"); 37.54 int res = m->name()->fast_compare(name); 37.55 if (res == 0) { 37.56 - // found matching name; do linear search to find matching signature 37.57 - // first, quick check for common case 37.58 - if (m->signature() == signature) return m; 37.59 - // search downwards through overloaded methods 37.60 - int i; 37.61 - for (i = mid - 1; i >= l; i--) { 37.62 - Method* m = methods->at(i); 37.63 - assert(m->is_method(), "must be method"); 37.64 - if (m->name() != name) break; 37.65 - if (m->signature() == signature) return m; 37.66 - } 37.67 - // search upwards 37.68 - for (i = mid + 1; i <= h; i++) { 37.69 - Method* m = methods->at(i); 37.70 - assert(m->is_method(), "must be method"); 37.71 - if (m->name() != name) break; 37.72 - if (m->signature() == signature) return m; 37.73 - } 37.74 - // not found 37.75 -#ifdef ASSERT 37.76 - int index = linear_search(methods, name, signature); 37.77 - assert(index == -1, err_msg("binary search should have found entry %d", index)); 37.78 -#endif 37.79 - return NULL; 37.80 + return mid; 37.81 } else if (res < 0) { 37.82 l = mid + 1; 37.83 } else { 37.84 h = mid - 1; 37.85 } 37.86 } 37.87 + return -1; 37.88 +} 37.89 + 37.90 +Method* InstanceKlass::find_method(Symbol* name, Symbol* signature) const { 37.91 + return InstanceKlass::find_method(methods(), name, signature); 37.92 +} 37.93 + 37.94 +Method* InstanceKlass::find_method( 37.95 + Array<Method*>* methods, Symbol* name, Symbol* signature) { 37.96 + int hit = binary_search(methods, name); 37.97 + if (hit != -1) { 37.98 + Method* m = methods->at(hit); 37.99 + // Do linear search to find matching signature. First, quick check 37.100 + // for common case 37.101 + if (m->signature() == signature) return m; 37.102 + // search downwards through overloaded methods 37.103 + int i; 37.104 + for (i = hit - 1; i >= 0; --i) { 37.105 + Method* m = methods->at(i); 37.106 + assert(m->is_method(), "must be method"); 37.107 + if (m->name() != name) break; 37.108 + if (m->signature() == signature) return m; 37.109 + } 37.110 + // search upwards 37.111 + for (i = hit + 1; i < methods->length(); ++i) { 37.112 + Method* m = methods->at(i); 37.113 + assert(m->is_method(), "must be method"); 37.114 + if (m->name() != name) break; 37.115 + if (m->signature() == signature) return m; 37.116 + } 37.117 + // not found 37.118 #ifdef ASSERT 37.119 - int index = linear_search(methods, name, signature); 37.120 - assert(index == -1, err_msg("binary search should have found entry %d", index)); 37.121 + int index = linear_search(methods, name, signature); 37.122 + assert(index == -1, err_msg("binary search should have found entry %d", index)); 37.123 #endif 37.124 + } 37.125 return NULL; 37.126 } 37.127 37.128 +int InstanceKlass::find_method_by_name(Symbol* name, int* end) { 37.129 + return find_method_by_name(methods(), name, end); 37.130 +} 37.131 + 37.132 +int InstanceKlass::find_method_by_name( 37.133 + Array<Method*>* methods, Symbol* name, int* end_ptr) { 37.134 + assert(end_ptr != NULL, "just checking"); 37.135 + int start = binary_search(methods, name); 37.136 + int end = start + 1; 37.137 + if (start != -1) { 37.138 + while (start - 1 >= 0 && (methods->at(start - 1))->name() == name) --start; 37.139 + while (end < methods->length() && (methods->at(end))->name() == name) ++end; 37.140 + *end_ptr = end; 37.141 + return start; 37.142 + } 37.143 + return -1; 37.144 +} 37.145 + 37.146 Method* InstanceKlass::uncached_lookup_method(Symbol* name, Symbol* signature) const { 37.147 Klass* klass = const_cast<InstanceKlass*>(this); 37.148 while (klass != NULL) {
38.1 --- a/src/share/vm/oops/instanceKlass.hpp Mon Nov 05 19:33:44 2012 -0500 38.2 +++ b/src/share/vm/oops/instanceKlass.hpp Wed Nov 07 16:09:20 2012 -0800 38.3 @@ -245,6 +245,10 @@ 38.4 unsigned char * _cached_class_file_bytes; // JVMTI: cached class file, before retransformable agent modified it in CFLH 38.5 jint _cached_class_file_len; // JVMTI: length of above 38.6 JvmtiCachedClassFieldMap* _jvmti_cached_class_field_map; // JVMTI: used during heap iteration 38.7 + 38.8 + // true if class, superclass, or implemented interfaces have default methods 38.9 + bool _has_default_methods; 38.10 + 38.11 volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change 38.12 // Method array. 38.13 Array<Method*>* _methods; 38.14 @@ -492,6 +496,13 @@ 38.15 // (returns NULL if not found) 38.16 Method* lookup_method_in_all_interfaces(Symbol* name, Symbol* signature) const; 38.17 38.18 + // Find method indices by name. If a method with the specified name is 38.19 + // found the index to the first method is returned, and 'end' is filled in 38.20 + // with the index of first non-name-matching method. If no method is found 38.21 + // -1 is returned. 38.22 + int find_method_by_name(Symbol* name, int* end); 38.23 + static int find_method_by_name(Array<Method*>* methods, Symbol* name, int* end); 38.24 + 38.25 // constant pool 38.26 ConstantPool* constants() const { return _constants; } 38.27 void set_constants(ConstantPool* c) { _constants = c; } 38.28 @@ -592,6 +603,9 @@ 38.29 return _jvmti_cached_class_field_map; 38.30 } 38.31 38.32 + bool has_default_methods() const { return _has_default_methods; } 38.33 + void set_has_default_methods(bool b) { _has_default_methods = b; } 38.34 + 38.35 // for adding methods, ConstMethod::UNSET_IDNUM means no more ids available 38.36 inline u2 next_method_idnum(); 38.37 void set_initial_method_idnum(u2 value) { _idnum_allocated_count = value; } 38.38 @@ -728,7 +742,6 @@ 38.39 GrowableArray<Klass*>* compute_secondary_supers(int num_extra_slots); 38.40 bool compute_is_subtype_of(Klass* k); 38.41 bool can_be_primary_super_slow() const; 38.42 - Klass* java_super() const { return super(); } 38.43 int oop_size(oop obj) const { return size_helper(); } 38.44 bool oop_is_instance_slow() const { return true; } 38.45 38.46 @@ -750,6 +763,10 @@ 38.47 return (InstanceKlass*) k; 38.48 } 38.49 38.50 + InstanceKlass* java_super() const { 38.51 + return (super() == NULL) ? NULL : cast(super()); 38.52 + } 38.53 + 38.54 // Sizing (in words) 38.55 static int header_size() { return align_object_offset(sizeof(InstanceKlass)/HeapWordSize); } 38.56 static int size(int vtable_length, int itable_length,
39.1 --- a/src/share/vm/oops/klassVtable.cpp Mon Nov 05 19:33:44 2012 -0500 39.2 +++ b/src/share/vm/oops/klassVtable.cpp Wed Nov 07 16:09:20 2012 -0800 39.3 @@ -54,22 +54,16 @@ 39.4 // the same name and signature as m), then m is a Miranda method which is 39.5 // entered as a public abstract method in C's vtable. From then on it should 39.6 // treated as any other public method in C for method over-ride purposes. 39.7 -void klassVtable::compute_vtable_size_and_num_mirandas(int &vtable_length, 39.8 - int &num_miranda_methods, 39.9 - Klass* super, 39.10 - Array<Method*>* methods, 39.11 - AccessFlags class_flags, 39.12 - Handle classloader, 39.13 - Symbol* classname, 39.14 - Array<Klass*>* local_interfaces, 39.15 - TRAPS 39.16 - ) { 39.17 - 39.18 +void klassVtable::compute_vtable_size_and_num_mirandas( 39.19 + int* vtable_length_ret, int* num_new_mirandas, 39.20 + GrowableArray<Method*>* all_mirandas, Klass* super, 39.21 + Array<Method*>* methods, AccessFlags class_flags, 39.22 + Handle classloader, Symbol* classname, Array<Klass*>* local_interfaces, 39.23 + TRAPS) { 39.24 No_Safepoint_Verifier nsv; 39.25 39.26 // set up default result values 39.27 - vtable_length = 0; 39.28 - num_miranda_methods = 0; 39.29 + int vtable_length = 0; 39.30 39.31 // start off with super's vtable length 39.32 InstanceKlass* sk = (InstanceKlass*)super; 39.33 @@ -86,9 +80,12 @@ 39.34 } 39.35 } 39.36 39.37 + GrowableArray<Method*> new_mirandas(20); 39.38 // compute the number of mirandas methods that must be added to the end 39.39 - num_miranda_methods = get_num_mirandas(super, methods, local_interfaces); 39.40 - vtable_length += (num_miranda_methods * vtableEntry::size()); 39.41 + get_mirandas(&new_mirandas, all_mirandas, super, methods, local_interfaces); 39.42 + *num_new_mirandas = new_mirandas.length(); 39.43 + 39.44 + vtable_length += *num_new_mirandas * vtableEntry::size(); 39.45 39.46 if (Universe::is_bootstrapping() && vtable_length == 0) { 39.47 // array classes don't have their superclass set correctly during 39.48 @@ -109,6 +106,8 @@ 39.49 "bad vtable size for class Object"); 39.50 assert(vtable_length % vtableEntry::size() == 0, "bad vtable length"); 39.51 assert(vtable_length >= Universe::base_vtable_size(), "vtable too small"); 39.52 + 39.53 + *vtable_length_ret = vtable_length; 39.54 } 39.55 39.56 int klassVtable::index_of(Method* m, int len) const { 39.57 @@ -191,7 +190,7 @@ 39.58 } 39.59 39.60 // add miranda methods; it will also update the value of initialized 39.61 - fill_in_mirandas(initialized); 39.62 + fill_in_mirandas(&initialized); 39.63 39.64 // In class hierarchies where the accessibility is not increasing (i.e., going from private -> 39.65 // package_private -> publicprotected), the vtable might actually be smaller than our initial 39.66 @@ -249,6 +248,11 @@ 39.67 return superk; 39.68 } 39.69 39.70 +// Methods that are "effectively" final don't need vtable entries. 39.71 +bool method_is_effectively_final( 39.72 + AccessFlags klass_flags, methodHandle target) { 39.73 + return target->is_final() || klass_flags.is_final() && !target->is_overpass(); 39.74 +} 39.75 39.76 // Update child's copy of super vtable for overrides 39.77 // OR return true if a new vtable entry is required 39.78 @@ -269,7 +273,7 @@ 39.79 return false; 39.80 } 39.81 39.82 - if (klass->is_final() || target_method()->is_final()) { 39.83 + if (method_is_effectively_final(klass->access_flags(), target_method)) { 39.84 // a final method never needs a new entry; final methods can be statically 39.85 // resolved and they have to be present in the vtable only if they override 39.86 // a super's method, in which case they re-use its entry 39.87 @@ -303,7 +307,7 @@ 39.88 if (super_method->name() == name && super_method->signature() == signature) { 39.89 39.90 // get super_klass for method_holder for the found method 39.91 - InstanceKlass* super_klass = InstanceKlass::cast(super_method->method_holder()); 39.92 + InstanceKlass* super_klass = super_method->method_holder(); 39.93 39.94 if ((super_klass->is_override(super_method, target_loader, target_classname, THREAD)) || 39.95 ((klass->major_version() >= VTABLE_TRANSITIVE_OVERRIDE_VERSION) 39.96 @@ -406,7 +410,8 @@ 39.97 Symbol* classname, 39.98 AccessFlags class_flags, 39.99 TRAPS) { 39.100 - if ((class_flags.is_final() || target_method()->is_final()) || 39.101 + 39.102 + if (method_is_effectively_final(class_flags, target_method) || 39.103 // a final method never needs a new entry; final methods can be statically 39.104 // resolved and they have to be present in the vtable only if they override 39.105 // a super's method, in which case they re-use its entry 39.106 @@ -447,7 +452,7 @@ 39.107 } 39.108 // get the class holding the matching method 39.109 // make sure you use that class for is_override 39.110 - InstanceKlass* superk = InstanceKlass::cast(super_method->method_holder()); 39.111 + InstanceKlass* superk = super_method->method_holder(); 39.112 // we want only instance method matches 39.113 // pretend private methods are not in the super vtable 39.114 // since we do override around them: e.g. a.m pub/b.m private/c.m pub, 39.115 @@ -502,7 +507,7 @@ 39.116 39.117 // miranda methods are interface methods in a class's vtable 39.118 if (mhk->is_interface()) { 39.119 - assert(m->is_public() && m->is_abstract(), "should be public and abstract"); 39.120 + assert(m->is_public(), "should be public"); 39.121 assert(ik()->implements_interface(method_holder) , "this class should implement the interface"); 39.122 assert(is_miranda(m, ik()->methods(), ik()->super()), "should be a miranda_method"); 39.123 return true; 39.124 @@ -532,19 +537,19 @@ 39.125 return false; 39.126 } 39.127 39.128 -void klassVtable::add_new_mirandas_to_list(GrowableArray<Method*>* list_of_current_mirandas, 39.129 - Array<Method*>* current_interface_methods, 39.130 - Array<Method*>* class_methods, 39.131 - Klass* super) { 39.132 +void klassVtable::add_new_mirandas_to_lists( 39.133 + GrowableArray<Method*>* new_mirandas, GrowableArray<Method*>* all_mirandas, 39.134 + Array<Method*>* current_interface_methods, Array<Method*>* class_methods, 39.135 + Klass* super) { 39.136 // iterate thru the current interface's method to see if it a miranda 39.137 int num_methods = current_interface_methods->length(); 39.138 for (int i = 0; i < num_methods; i++) { 39.139 Method* im = current_interface_methods->at(i); 39.140 bool is_duplicate = false; 39.141 - int num_of_current_mirandas = list_of_current_mirandas->length(); 39.142 + int num_of_current_mirandas = new_mirandas->length(); 39.143 // check for duplicate mirandas in different interfaces we implement 39.144 for (int j = 0; j < num_of_current_mirandas; j++) { 39.145 - Method* miranda = list_of_current_mirandas->at(j); 39.146 + Method* miranda = new_mirandas->at(j); 39.147 if ((im->name() == miranda->name()) && 39.148 (im->signature() == miranda->signature())) { 39.149 is_duplicate = true; 39.150 @@ -557,51 +562,47 @@ 39.151 InstanceKlass *sk = InstanceKlass::cast(super); 39.152 // check if it is a duplicate of a super's miranda 39.153 if (sk->lookup_method_in_all_interfaces(im->name(), im->signature()) == NULL) { 39.154 - list_of_current_mirandas->append(im); 39.155 + new_mirandas->append(im); 39.156 + } 39.157 + if (all_mirandas != NULL) { 39.158 + all_mirandas->append(im); 39.159 } 39.160 } 39.161 } 39.162 } 39.163 } 39.164 39.165 -void klassVtable::get_mirandas(GrowableArray<Method*>* mirandas, 39.166 +void klassVtable::get_mirandas(GrowableArray<Method*>* new_mirandas, 39.167 + GrowableArray<Method*>* all_mirandas, 39.168 Klass* super, Array<Method*>* class_methods, 39.169 Array<Klass*>* local_interfaces) { 39.170 - assert((mirandas->length() == 0) , "current mirandas must be 0"); 39.171 + assert((new_mirandas->length() == 0) , "current mirandas must be 0"); 39.172 39.173 // iterate thru the local interfaces looking for a miranda 39.174 int num_local_ifs = local_interfaces->length(); 39.175 for (int i = 0; i < num_local_ifs; i++) { 39.176 InstanceKlass *ik = InstanceKlass::cast(local_interfaces->at(i)); 39.177 - add_new_mirandas_to_list(mirandas, ik->methods(), class_methods, super); 39.178 + add_new_mirandas_to_lists(new_mirandas, all_mirandas, 39.179 + ik->methods(), class_methods, super); 39.180 // iterate thru each local's super interfaces 39.181 Array<Klass*>* super_ifs = ik->transitive_interfaces(); 39.182 int num_super_ifs = super_ifs->length(); 39.183 for (int j = 0; j < num_super_ifs; j++) { 39.184 InstanceKlass *sik = InstanceKlass::cast(super_ifs->at(j)); 39.185 - add_new_mirandas_to_list(mirandas, sik->methods(), class_methods, super); 39.186 + add_new_mirandas_to_lists(new_mirandas, all_mirandas, 39.187 + sik->methods(), class_methods, super); 39.188 } 39.189 } 39.190 } 39.191 39.192 -// get number of mirandas 39.193 -int klassVtable::get_num_mirandas(Klass* super, Array<Method*>* class_methods, Array<Klass*>* local_interfaces) { 39.194 - ResourceMark rm; 39.195 - GrowableArray<Method*>* mirandas = new GrowableArray<Method*>(20); 39.196 - get_mirandas(mirandas, super, class_methods, local_interfaces); 39.197 - return mirandas->length(); 39.198 -} 39.199 - 39.200 // fill in mirandas 39.201 -void klassVtable::fill_in_mirandas(int& initialized) { 39.202 - ResourceMark rm; 39.203 - GrowableArray<Method*>* mirandas = new GrowableArray<Method*>(20); 39.204 - InstanceKlass *this_ik = ik(); 39.205 - get_mirandas(mirandas, this_ik->super(), this_ik->methods(), this_ik->local_interfaces()); 39.206 - int num_mirandas = mirandas->length(); 39.207 - for (int i = 0; i < num_mirandas; i++) { 39.208 - put_method_at(mirandas->at(i), initialized); 39.209 - initialized++; 39.210 +void klassVtable::fill_in_mirandas(int* initialized) { 39.211 + GrowableArray<Method*> mirandas(20); 39.212 + get_mirandas(&mirandas, NULL, ik()->super(), ik()->methods(), 39.213 + ik()->local_interfaces()); 39.214 + for (int i = 0; i < mirandas.length(); i++) { 39.215 + put_method_at(mirandas.at(i), *initialized); 39.216 + ++(*initialized); 39.217 } 39.218 } 39.219 39.220 @@ -629,7 +630,7 @@ 39.221 if (!(*trace_name_printed)) { 39.222 // RC_TRACE_MESG macro has an embedded ResourceMark 39.223 RC_TRACE_MESG(("adjust: name=%s", 39.224 - Klass::cast(old_method->method_holder())->external_name())); 39.225 + old_method->method_holder()->external_name())); 39.226 *trace_name_printed = true; 39.227 } 39.228 // RC_TRACE macro has an embedded ResourceMark 39.229 @@ -744,7 +745,7 @@ 39.230 Method* target = klass->uncached_lookup_method(method_name, method_signature); 39.231 while (target != NULL && target->is_static()) { 39.232 // continue with recursive lookup through the superclass 39.233 - Klass* super = Klass::cast(target->method_holder())->super(); 39.234 + Klass* super = target->method_holder()->super(); 39.235 target = (super == NULL) ? (Method*)NULL : Klass::cast(super)->uncached_lookup_method(method_name, method_signature); 39.236 } 39.237 if (target == NULL || !target->is_public() || target->is_abstract()) { 39.238 @@ -754,7 +755,7 @@ 39.239 // if checkconstraints requested 39.240 methodHandle target_h (THREAD, target); // preserve across gc 39.241 if (checkconstraints) { 39.242 - Handle method_holder_loader (THREAD, InstanceKlass::cast(target->method_holder())->class_loader()); 39.243 + Handle method_holder_loader (THREAD, target->method_holder()->class_loader()); 39.244 if (method_holder_loader() != interface_loader()) { 39.245 ResourceMark rm(THREAD); 39.246 char* failed_type_name = 39.247 @@ -824,7 +825,7 @@ 39.248 if (!(*trace_name_printed)) { 39.249 // RC_TRACE_MESG macro has an embedded ResourceMark 39.250 RC_TRACE_MESG(("adjust: name=%s", 39.251 - Klass::cast(old_method->method_holder())->external_name())); 39.252 + old_method->method_holder()->external_name())); 39.253 *trace_name_printed = true; 39.254 } 39.255 // RC_TRACE macro has an embedded ResourceMark 39.256 @@ -959,9 +960,9 @@ 39.257 39.258 // m must be a method in an interface 39.259 int klassItable::compute_itable_index(Method* m) { 39.260 - Klass* intf = m->method_holder(); 39.261 - assert(InstanceKlass::cast(intf)->is_interface(), "sanity check"); 39.262 - Array<Method*>* methods = InstanceKlass::cast(intf)->methods(); 39.263 + InstanceKlass* intf = m->method_holder(); 39.264 + assert(intf->is_interface(), "sanity check"); 39.265 + Array<Method*>* methods = intf->methods(); 39.266 int index = 0; 39.267 while(methods->at(index) != m) { 39.268 index++;
40.1 --- a/src/share/vm/oops/klassVtable.hpp Mon Nov 05 19:33:44 2012 -0500 40.2 +++ b/src/share/vm/oops/klassVtable.hpp Wed Nov 07 16:09:20 2012 -0800 40.3 @@ -84,11 +84,11 @@ 40.4 bool is_initialized(); 40.5 40.6 // computes vtable length (in words) and the number of miranda methods 40.7 - static void compute_vtable_size_and_num_mirandas(int &vtable_length, int &num_miranda_methods, 40.8 - Klass* super, Array<Method*>* methods, 40.9 - AccessFlags class_flags, Handle classloader, 40.10 - Symbol* classname, Array<Klass*>* local_interfaces, 40.11 - TRAPS); 40.12 + static void compute_vtable_size_and_num_mirandas( 40.13 + int* vtable_length, int* num_new_mirandas, 40.14 + GrowableArray<Method*>* all_mirandas, Klass* super, 40.15 + Array<Method*>* methods, AccessFlags class_flags, Handle classloader, 40.16 + Symbol* classname, Array<Klass*>* local_interfaces, TRAPS); 40.17 40.18 // RedefineClasses() API support: 40.19 // If any entry of this vtable points to any of old_methods, 40.20 @@ -125,12 +125,17 @@ 40.21 40.22 // support for miranda methods 40.23 bool is_miranda_entry_at(int i); 40.24 - void fill_in_mirandas(int& initialized); 40.25 + void fill_in_mirandas(int* initialized); 40.26 static bool is_miranda(Method* m, Array<Method*>* class_methods, Klass* super); 40.27 - static void add_new_mirandas_to_list(GrowableArray<Method*>* list_of_current_mirandas, Array<Method*>* current_interface_methods, Array<Method*>* class_methods, Klass* super); 40.28 - static void get_mirandas(GrowableArray<Method*>* mirandas, Klass* super, Array<Method*>* class_methods, Array<Klass*>* local_interfaces); 40.29 - static int get_num_mirandas(Klass* super, Array<Method*>* class_methods, Array<Klass*>* local_interfaces); 40.30 - 40.31 + static void add_new_mirandas_to_lists( 40.32 + GrowableArray<Method*>* new_mirandas, 40.33 + GrowableArray<Method*>* all_mirandas, 40.34 + Array<Method*>* current_interface_methods, Array<Method*>* class_methods, 40.35 + Klass* super); 40.36 + static void get_mirandas( 40.37 + GrowableArray<Method*>* new_mirandas, 40.38 + GrowableArray<Method*>* all_mirandas, Klass* super, 40.39 + Array<Method*>* class_methods, Array<Klass*>* local_interfaces); 40.40 40.41 void verify_against(outputStream* st, klassVtable* vt, int index); 40.42 inline InstanceKlass* ik() const;
41.1 --- a/src/share/vm/oops/method.cpp Mon Nov 05 19:33:44 2012 -0500 41.2 +++ b/src/share/vm/oops/method.cpp Wed Nov 07 16:09:20 2012 -0800 41.3 @@ -35,6 +35,7 @@ 41.4 #include "memory/generation.hpp" 41.5 #include "memory/metadataFactory.hpp" 41.6 #include "memory/oopFactory.hpp" 41.7 +#include "oops/constMethod.hpp" 41.8 #include "oops/methodData.hpp" 41.9 #include "oops/method.hpp" 41.10 #include "oops/oop.inline.hpp" 41.11 @@ -57,22 +58,24 @@ 41.12 // Implementation of Method 41.13 41.14 Method* Method::allocate(ClassLoaderData* loader_data, 41.15 - int byte_code_size, 41.16 - AccessFlags access_flags, 41.17 - int compressed_line_number_size, 41.18 - int localvariable_table_length, 41.19 - int exception_table_length, 41.20 - int checked_exceptions_length, 41.21 - TRAPS) { 41.22 + int byte_code_size, 41.23 + AccessFlags access_flags, 41.24 + int compressed_line_number_size, 41.25 + int localvariable_table_length, 41.26 + int exception_table_length, 41.27 + int checked_exceptions_length, 41.28 + ConstMethod::MethodType method_type, 41.29 + TRAPS) { 41.30 assert(!access_flags.is_native() || byte_code_size == 0, 41.31 "native methods should not contain byte codes"); 41.32 ConstMethod* cm = ConstMethod::allocate(loader_data, 41.33 - byte_code_size, 41.34 - compressed_line_number_size, 41.35 - localvariable_table_length, 41.36 - exception_table_length, 41.37 - checked_exceptions_length, 41.38 - CHECK_NULL); 41.39 + byte_code_size, 41.40 + compressed_line_number_size, 41.41 + localvariable_table_length, 41.42 + exception_table_length, 41.43 + checked_exceptions_length, 41.44 + method_type, 41.45 + CHECK_NULL); 41.46 41.47 int size = Method::size(access_flags.is_native()); 41.48 41.49 @@ -240,12 +243,12 @@ 41.50 warning("oopmap should only be accessed by the " 41.51 "VM, GC task or CMS threads (or during debugging)"); 41.52 InterpreterOopMap local_mask; 41.53 - InstanceKlass::cast(method_holder())->mask_for(h_this, bci, &local_mask); 41.54 + method_holder()->mask_for(h_this, bci, &local_mask); 41.55 local_mask.print(); 41.56 } 41.57 } 41.58 #endif 41.59 - InstanceKlass::cast(method_holder())->mask_for(h_this, bci, mask); 41.60 + method_holder()->mask_for(h_this, bci, mask); 41.61 return; 41.62 } 41.63 41.64 @@ -520,7 +523,7 @@ 41.65 bool Method::is_final_method() const { 41.66 // %%% Should return true for private methods also, 41.67 // since there is no way to override them. 41.68 - return is_final() || Klass::cast(method_holder())->is_final(); 41.69 + return is_final() || method_holder()->is_final(); 41.70 } 41.71 41.72 41.73 @@ -552,7 +555,7 @@ 41.74 41.75 bool Method::has_valid_initializer_flags() const { 41.76 return (is_static() || 41.77 - InstanceKlass::cast(method_holder())->major_version() < 51); 41.78 + method_holder()->major_version() < 51); 41.79 } 41.80 41.81 bool Method::is_static_initializer() const { 41.82 @@ -614,7 +617,7 @@ 41.83 if( constants()->tag_at(klass_index).is_unresolved_klass() ) { 41.84 Thread *thread = Thread::current(); 41.85 Symbol* klass_name = constants()->klass_name_at(klass_index); 41.86 - Handle loader(thread, InstanceKlass::cast(method_holder())->class_loader()); 41.87 + Handle loader(thread, method_holder()->class_loader()); 41.88 Handle prot (thread, Klass::cast(method_holder())->protection_domain()); 41.89 return SystemDictionary::find(klass_name, loader, prot, thread) != NULL; 41.90 } else { 41.91 @@ -932,7 +935,7 @@ 41.92 41.93 // If method is an interface, we skip it - except if it 41.94 // is a miranda method 41.95 - if (InstanceKlass::cast(method_holder())->is_interface()) { 41.96 + if (method_holder()->is_interface()) { 41.97 // Check that method is not a miranda method 41.98 if (ik->lookup_method(name(), signature()) == NULL) { 41.99 // No implementation exist - so miranda method 41.100 @@ -1017,7 +1020,7 @@ 41.101 ConstantPool* cp_oop = ConstantPool::allocate(loader_data, cp_length, CHECK_(empty)); 41.102 cp = constantPoolHandle(THREAD, cp_oop); 41.103 } 41.104 - cp->set_pool_holder(holder()); 41.105 + cp->set_pool_holder(InstanceKlass::cast(holder())); 41.106 cp->symbol_at_put(_imcp_invoke_name, name); 41.107 cp->symbol_at_put(_imcp_invoke_signature, signature); 41.108 cp->set_preresolution(); 41.109 @@ -1031,7 +1034,7 @@ 41.110 methodHandle m; 41.111 { 41.112 Method* m_oop = Method::allocate(loader_data, 0, accessFlags_from(flags_bits), 41.113 - 0, 0, 0, 0, CHECK_(empty)); 41.114 + 0, 0, 0, 0, ConstMethod::NORMAL, CHECK_(empty)); 41.115 m = methodHandle(THREAD, m_oop); 41.116 } 41.117 m->set_constants(cp()); 41.118 @@ -1083,15 +1086,16 @@ 41.119 int localvariable_len = m->localvariable_table_length(); 41.120 int exception_table_len = m->exception_table_length(); 41.121 41.122 - ClassLoaderData* loader_data = m()->method_holder()->class_loader_data(); 41.123 + ClassLoaderData* loader_data = m->method_holder()->class_loader_data(); 41.124 Method* newm_oop = Method::allocate(loader_data, 41.125 - new_code_length, 41.126 - flags, 41.127 - new_compressed_linenumber_size, 41.128 - localvariable_len, 41.129 - exception_table_len, 41.130 - checked_exceptions_len, 41.131 - CHECK_(methodHandle())); 41.132 + new_code_length, 41.133 + flags, 41.134 + new_compressed_linenumber_size, 41.135 + localvariable_len, 41.136 + exception_table_len, 41.137 + checked_exceptions_len, 41.138 + m->method_type(), 41.139 + CHECK_(methodHandle())); 41.140 methodHandle newm (THREAD, newm_oop); 41.141 int new_method_size = newm->method_size(); 41.142 41.143 @@ -1233,8 +1237,8 @@ 41.144 return false; 41.145 } 41.146 bool sig_is_loaded = true; 41.147 - Handle class_loader(THREAD, InstanceKlass::cast(m->method_holder())->class_loader()); 41.148 - Handle protection_domain(THREAD, Klass::cast(m->method_holder())->protection_domain()); 41.149 + Handle class_loader(THREAD, m->method_holder()->class_loader()); 41.150 + Handle protection_domain(THREAD, m->method_holder()->protection_domain()); 41.151 ResourceMark rm(THREAD); 41.152 Symbol* signature = m->signature(); 41.153 for(SignatureStream ss(signature); !ss.is_done(); ss.next()) { 41.154 @@ -1260,8 +1264,8 @@ 41.155 } 41.156 41.157 bool Method::has_unloaded_classes_in_signature(methodHandle m, TRAPS) { 41.158 - Handle class_loader(THREAD, InstanceKlass::cast(m->method_holder())->class_loader()); 41.159 - Handle protection_domain(THREAD, Klass::cast(m->method_holder())->protection_domain()); 41.160 + Handle class_loader(THREAD, m->method_holder()->class_loader()); 41.161 + Handle protection_domain(THREAD, m->method_holder()->protection_domain()); 41.162 ResourceMark rm(THREAD); 41.163 Symbol* signature = m->signature(); 41.164 for(SignatureStream ss(signature); !ss.is_done(); ss.next()) { 41.165 @@ -1468,7 +1472,7 @@ 41.166 41.167 41.168 Bytecodes::Code Method::orig_bytecode_at(int bci) const { 41.169 - BreakpointInfo* bp = InstanceKlass::cast(method_holder())->breakpoints(); 41.170 + BreakpointInfo* bp = method_holder()->breakpoints(); 41.171 for (; bp != NULL; bp = bp->next()) { 41.172 if (bp->match(this, bci)) { 41.173 return bp->orig_bytecode(); 41.174 @@ -1480,7 +1484,7 @@ 41.175 41.176 void Method::set_orig_bytecode_at(int bci, Bytecodes::Code code) { 41.177 assert(code != Bytecodes::_breakpoint, "cannot patch breakpoints this way"); 41.178 - BreakpointInfo* bp = InstanceKlass::cast(method_holder())->breakpoints(); 41.179 + BreakpointInfo* bp = method_holder()->breakpoints(); 41.180 for (; bp != NULL; bp = bp->next()) { 41.181 if (bp->match(this, bci)) { 41.182 bp->set_orig_bytecode(code); 41.183 @@ -1490,7 +1494,7 @@ 41.184 } 41.185 41.186 void Method::set_breakpoint(int bci) { 41.187 - InstanceKlass* ik = InstanceKlass::cast(method_holder()); 41.188 + InstanceKlass* ik = method_holder(); 41.189 BreakpointInfo *bp = new BreakpointInfo(this, bci); 41.190 bp->set_next(ik->breakpoints()); 41.191 ik->set_breakpoints(bp); 41.192 @@ -1499,7 +1503,7 @@ 41.193 } 41.194 41.195 static void clear_matches(Method* m, int bci) { 41.196 - InstanceKlass* ik = InstanceKlass::cast(m->method_holder()); 41.197 + InstanceKlass* ik = m->method_holder(); 41.198 BreakpointInfo* prev_bp = NULL; 41.199 BreakpointInfo* next_bp; 41.200 for (BreakpointInfo* bp = ik->breakpoints(); bp != NULL; bp = next_bp) { 41.201 @@ -1782,7 +1786,7 @@ 41.202 bool Method::is_method_id(jmethodID mid) { 41.203 Method* m = resolve_jmethod_id(mid); 41.204 assert(m != NULL, "should be called with non-null method"); 41.205 - InstanceKlass* ik = InstanceKlass::cast(m->method_holder()); 41.206 + InstanceKlass* ik = m->method_holder(); 41.207 ClassLoaderData* cld = ik->class_loader_data(); 41.208 if (cld->jmethod_ids() == NULL) return false; 41.209 return (cld->jmethod_ids()->contains((Method**)mid));
42.1 --- a/src/share/vm/oops/method.hpp Mon Nov 05 19:33:44 2012 -0500 42.2 +++ b/src/share/vm/oops/method.hpp Wed Nov 07 16:09:20 2012 -0800 42.3 @@ -30,7 +30,6 @@ 42.4 #include "compiler/oopMap.hpp" 42.5 #include "interpreter/invocationCounter.hpp" 42.6 #include "oops/annotations.hpp" 42.7 -#include "oops/constMethod.hpp" 42.8 #include "oops/constantPool.hpp" 42.9 #include "oops/instanceKlass.hpp" 42.10 #include "oops/oop.hpp" 42.11 @@ -104,6 +103,7 @@ 42.12 class LocalVariableTableElement; 42.13 class AdapterHandlerEntry; 42.14 class MethodData; 42.15 +class ConstMethod; 42.16 42.17 class Method : public Metadata { 42.18 friend class VMStructs; 42.19 @@ -158,14 +158,16 @@ 42.20 // Constructor 42.21 Method(ConstMethod* xconst, AccessFlags access_flags, int size); 42.22 public: 42.23 + 42.24 static Method* allocate(ClassLoaderData* loader_data, 42.25 - int byte_code_size, 42.26 - AccessFlags access_flags, 42.27 - int compressed_line_number_size, 42.28 - int localvariable_table_length, 42.29 - int exception_table_length, 42.30 - int checked_exceptions_length, 42.31 - TRAPS); 42.32 + int byte_code_size, 42.33 + AccessFlags access_flags, 42.34 + int compressed_line_number_size, 42.35 + int localvariable_table_length, 42.36 + int exception_table_length, 42.37 + int checked_exceptions_length, 42.38 + ConstMethod::MethodType method_type, 42.39 + TRAPS); 42.40 42.41 Method() { assert(DumpSharedSpaces || UseSharedSpaces, "only for CDS"); } 42.42 42.43 @@ -207,21 +209,21 @@ 42.44 42.45 // annotations support 42.46 AnnotationArray* annotations() const { 42.47 - InstanceKlass* ik = InstanceKlass::cast(method_holder()); 42.48 + InstanceKlass* ik = method_holder(); 42.49 if (ik->annotations() == NULL) { 42.50 return NULL; 42.51 } 42.52 return ik->annotations()->get_method_annotations_of(method_idnum()); 42.53 } 42.54 AnnotationArray* parameter_annotations() const { 42.55 - InstanceKlass* ik = InstanceKlass::cast(method_holder()); 42.56 + InstanceKlass* ik = method_holder(); 42.57 if (ik->annotations() == NULL) { 42.58 return NULL; 42.59 } 42.60 return ik->annotations()->get_method_parameter_annotations_of(method_idnum()); 42.61 } 42.62 AnnotationArray* annotation_default() const { 42.63 - InstanceKlass* ik = InstanceKlass::cast(method_holder()); 42.64 + InstanceKlass* ik = method_holder(); 42.65 if (ik->annotations() == NULL) { 42.66 return NULL; 42.67 } 42.68 @@ -494,7 +496,7 @@ 42.69 { return constMethod()->compressed_linenumber_table(); } 42.70 42.71 // method holder (the Klass* holding this method) 42.72 - Klass* method_holder() const { return constants()->pool_holder(); } 42.73 + InstanceKlass* method_holder() const { return constants()->pool_holder(); } 42.74 42.75 void compute_size_of_parameters(Thread *thread); // word size of parameters (receiver if any + arguments) 42.76 Symbol* klass_name() const; // returns the name of the method holder 42.77 @@ -695,18 +697,18 @@ 42.78 42.79 // Get this method's jmethodID -- allocate if it doesn't exist 42.80 jmethodID jmethod_id() { methodHandle this_h(this); 42.81 - return InstanceKlass::get_jmethod_id(InstanceKlass::cast(method_holder()), this_h); } 42.82 + return InstanceKlass::get_jmethod_id(method_holder(), this_h); } 42.83 42.84 // Lookup the jmethodID for this method. Return NULL if not found. 42.85 // NOTE that this function can be called from a signal handler 42.86 // (see AsyncGetCallTrace support for Forte Analyzer) and this 42.87 // needs to be async-safe. No allocation should be done and 42.88 // so handles are not used to avoid deadlock. 42.89 - jmethodID find_jmethod_id_or_null() { return InstanceKlass::cast(method_holder())->jmethod_id_or_null(this); } 42.90 + jmethodID find_jmethod_id_or_null() { return method_holder()->jmethod_id_or_null(this); } 42.91 42.92 // JNI static invoke cached itable index accessors 42.93 - int cached_itable_index() { return InstanceKlass::cast(method_holder())->cached_itable_index(method_idnum()); } 42.94 - void set_cached_itable_index(int index) { InstanceKlass::cast(method_holder())->set_cached_itable_index(method_idnum(), index); } 42.95 + int cached_itable_index() { return method_holder()->cached_itable_index(method_idnum()); } 42.96 + void set_cached_itable_index(int index) { method_holder()->set_cached_itable_index(method_idnum(), index); } 42.97 42.98 // Support for inlining of intrinsic methods 42.99 vmIntrinsics::ID intrinsic_id() const { return (vmIntrinsics::ID) _intrinsic_id; } 42.100 @@ -725,14 +727,18 @@ 42.101 void set_dont_inline(bool x) { _dont_inline = x; } 42.102 bool is_hidden() { return _hidden; } 42.103 void set_hidden(bool x) { _hidden = x; } 42.104 + ConstMethod::MethodType method_type() const { 42.105 + return _constMethod->method_type(); 42.106 + } 42.107 + bool is_overpass() const { return method_type() == ConstMethod::OVERPASS; } 42.108 42.109 // On-stack replacement support 42.110 bool has_osr_nmethod(int level, bool match_level) { 42.111 - return InstanceKlass::cast(method_holder())->lookup_osr_nmethod(this, InvocationEntryBci, level, match_level) != NULL; 42.112 + return method_holder()->lookup_osr_nmethod(this, InvocationEntryBci, level, match_level) != NULL; 42.113 } 42.114 42.115 nmethod* lookup_osr_nmethod_for(int bci, int level, bool match_level) { 42.116 - return InstanceKlass::cast(method_holder())->lookup_osr_nmethod(this, bci, level, match_level); 42.117 + return method_holder()->lookup_osr_nmethod(this, bci, level, match_level); 42.118 } 42.119 42.120 // Inline cache support
43.1 --- a/src/share/vm/prims/jni.cpp Mon Nov 05 19:33:44 2012 -0500 43.2 +++ b/src/share/vm/prims/jni.cpp Wed Nov 07 16:09:20 2012 -0800 43.3 @@ -2985,7 +2985,7 @@ 43.4 } 43.5 43.6 // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass* 43.7 - JNIid* id = InstanceKlass::cast(fd.field_holder())->jni_id_for(fd.offset()); 43.8 + JNIid* id = fd.field_holder()->jni_id_for(fd.offset()); 43.9 debug_only(id->set_is_static_field_id();) 43.10 43.11 debug_only(id->verify(fd.field_holder())); 43.12 @@ -4016,7 +4016,7 @@ 43.13 if (PrintJNIResolving) { 43.14 ResourceMark rm(THREAD); 43.15 tty->print_cr("[Registering JNI native method %s.%s]", 43.16 - Klass::cast(method->method_holder())->external_name(), 43.17 + method->method_holder()->external_name(), 43.18 method->name()->as_C_string()); 43.19 } 43.20 return true;
44.1 --- a/src/share/vm/prims/jvm.cpp Mon Nov 05 19:33:44 2012 -0500 44.2 +++ b/src/share/vm/prims/jvm.cpp Wed Nov 07 16:09:20 2012 -0800 44.3 @@ -125,7 +125,7 @@ 44.4 int line_number = -1; 44.5 const char * source_file = NULL; 44.6 const char * trace = "explicit"; 44.7 - Klass* caller = NULL; 44.8 + InstanceKlass* caller = NULL; 44.9 JavaThread* jthread = JavaThread::current(); 44.10 if (jthread->has_last_Java_frame()) { 44.11 vframeStream vfst(jthread); 44.12 @@ -153,17 +153,17 @@ 44.13 // that caller, otherwise keep quiet since this should be picked up elsewhere. 44.14 bool found_it = false; 44.15 if (!vfst.at_end() && 44.16 - InstanceKlass::cast(vfst.method()->method_holder())->name() == vmSymbols::java_lang_Class() && 44.17 + vfst.method()->method_holder()->name() == vmSymbols::java_lang_Class() && 44.18 vfst.method()->name() == vmSymbols::forName0_name()) { 44.19 vfst.next(); 44.20 if (!vfst.at_end() && 44.21 - InstanceKlass::cast(vfst.method()->method_holder())->name() == vmSymbols::java_lang_Class() && 44.22 + vfst.method()->method_holder()->name() == vmSymbols::java_lang_Class() && 44.23 vfst.method()->name() == vmSymbols::forName_name()) { 44.24 vfst.next(); 44.25 found_it = true; 44.26 } 44.27 } else if (last_caller != NULL && 44.28 - InstanceKlass::cast(last_caller->method_holder())->name() == 44.29 + last_caller->method_holder()->name() == 44.30 vmSymbols::java_lang_ClassLoader() && 44.31 (last_caller->name() == vmSymbols::loadClassInternal_name() || 44.32 last_caller->name() == vmSymbols::loadClass_name())) { 44.33 @@ -182,7 +182,7 @@ 44.34 // show method name if it's a native method 44.35 trace = vfst.method()->name_and_sig_as_C_string(); 44.36 } 44.37 - Symbol* s = InstanceKlass::cast(caller)->source_file_name(); 44.38 + Symbol* s = caller->source_file_name(); 44.39 if (s != NULL) { 44.40 source_file = s->as_C_string(); 44.41 } 44.42 @@ -190,8 +190,8 @@ 44.43 } 44.44 if (caller != NULL) { 44.45 if (to_class != caller) { 44.46 - const char * from = Klass::cast(caller)->external_name(); 44.47 - const char * to = Klass::cast(to_class)->external_name(); 44.48 + const char * from = caller->external_name(); 44.49 + const char * to = to_class->external_name(); 44.50 // print in a single call to reduce interleaving between threads 44.51 if (source_file != NULL) { 44.52 tty->print("RESOLVE %s %s %s:%d (%s)\n", from, to, source_file, line_number, trace); 44.53 @@ -1228,7 +1228,7 @@ 44.54 privileged_context = Handle(thread, thread->privileged_stack_top()->privileged_context()); 44.55 protection_domain = thread->privileged_stack_top()->protection_domain(); 44.56 } else { 44.57 - protection_domain = InstanceKlass::cast(method->method_holder())->protection_domain(); 44.58 + protection_domain = method->method_holder()->protection_domain(); 44.59 } 44.60 44.61 if ((previous_protection_domain != protection_domain) && (protection_domain != NULL)) { 44.62 @@ -3048,10 +3048,10 @@ 44.63 44.64 Method* m = vfst.method(); 44.65 if (!m->is_native()) { 44.66 - Klass* holder = m->method_holder(); 44.67 - oop loader = InstanceKlass::cast(holder)->class_loader(); 44.68 + InstanceKlass* holder = m->method_holder(); 44.69 + oop loader = holder->class_loader(); 44.70 if (loader != NULL && !java_lang_ClassLoader::is_trusted_loader(loader)) { 44.71 - return (jclass) JNIHandles::make_local(env, Klass::cast(holder)->java_mirror()); 44.72 + return (jclass) JNIHandles::make_local(env, holder->java_mirror()); 44.73 } 44.74 } 44.75 } 44.76 @@ -3071,9 +3071,9 @@ 44.77 44.78 Method* m = vfst.method(); 44.79 if (!m->is_native()) { 44.80 - Klass* holder = m->method_holder(); 44.81 + InstanceKlass* holder = m->method_holder(); 44.82 assert(holder->is_klass(), "just checking"); 44.83 - oop loader = InstanceKlass::cast(holder)->class_loader(); 44.84 + oop loader = holder->class_loader(); 44.85 if (loader != NULL && !java_lang_ClassLoader::is_trusted_loader(loader)) { 44.86 return JNIHandles::make_local(env, loader); 44.87 } 44.88 @@ -3148,9 +3148,9 @@ 44.89 44.90 for(vframeStream vfst(thread); !vfst.at_end(); vfst.next()) { 44.91 if (!vfst.method()->is_native()) { 44.92 - Klass* holder = vfst.method()->method_holder(); 44.93 + InstanceKlass* holder = vfst.method()->method_holder(); 44.94 assert(holder->is_klass(), "just checking"); 44.95 - if (InstanceKlass::cast(holder)->name() == class_name_sym) { 44.96 + if (holder->name() == class_name_sym) { 44.97 return depth; 44.98 } 44.99 depth++; 44.100 @@ -3171,9 +3171,9 @@ 44.101 44.102 Method* m = vfst.method(); 44.103 if (!m->is_native()) { 44.104 - Klass* holder = m->method_holder(); 44.105 + InstanceKlass* holder = m->method_holder(); 44.106 assert(holder->is_klass(), "just checking"); 44.107 - oop loader = InstanceKlass::cast(holder)->class_loader(); 44.108 + oop loader = holder->class_loader(); 44.109 if (loader != NULL && !java_lang_ClassLoader::is_trusted_loader(loader)) { 44.110 return depth; 44.111 } 44.112 @@ -3322,8 +3322,7 @@ 44.113 for (vframeStream vfst(thread); !vfst.at_end(); vfst.next()) { 44.114 // UseNewReflection 44.115 vfst.skip_reflection_related_frames(); // Only needed for 1.4 reflection 44.116 - Klass* holder = vfst.method()->method_holder(); 44.117 - oop loader = InstanceKlass::cast(holder)->class_loader(); 44.118 + oop loader = vfst.method()->method_holder()->class_loader(); 44.119 if (loader != NULL) { 44.120 return JNIHandles::make_local(env, loader); 44.121 } 44.122 @@ -3365,9 +3364,9 @@ 44.123 !vfst.at_end() && loader == NULL; 44.124 vfst.next()) { 44.125 if (!vfst.method()->is_native()) { 44.126 - Klass* holder = vfst.method()->method_holder(); 44.127 - loader = InstanceKlass::cast(holder)->class_loader(); 44.128 - protection_domain = InstanceKlass::cast(holder)->protection_domain(); 44.129 + InstanceKlass* holder = vfst.method()->method_holder(); 44.130 + loader = holder->class_loader(); 44.131 + protection_domain = holder->protection_domain(); 44.132 } 44.133 } 44.134 } else {
45.1 --- a/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Mon Nov 05 19:33:44 2012 -0500 45.2 +++ b/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Wed Nov 07 16:09:20 2012 -0800 45.3 @@ -753,7 +753,7 @@ 45.4 45.5 unsigned char* p = bytecodes; 45.6 Bytecodes::Code code; 45.7 - bool is_rewritten = InstanceKlass::cast(mh->method_holder())->is_rewritten(); 45.8 + bool is_rewritten = mh->method_holder()->is_rewritten(); 45.9 45.10 while ((code = bs.next()) >= 0) { 45.11 assert(Bytecodes::is_java_code(code), "sanity check");
46.1 --- a/src/share/vm/prims/jvmtiEnv.cpp Mon Nov 05 19:33:44 2012 -0500 46.2 +++ b/src/share/vm/prims/jvmtiEnv.cpp Wed Nov 07 16:09:20 2012 -0800 46.3 @@ -2822,7 +2822,7 @@ 46.4 JavaThread* current_thread = JavaThread::current(); 46.5 46.6 // does the klass have any local variable information? 46.7 - InstanceKlass* ik = InstanceKlass::cast(method_oop->method_holder()); 46.8 + InstanceKlass* ik = method_oop->method_holder(); 46.9 if (!ik->access_flags().has_localvariable_table()) { 46.10 return (JVMTI_ERROR_ABSENT_INFORMATION); 46.11 }
47.1 --- a/src/share/vm/prims/methodHandles.cpp Mon Nov 05 19:33:44 2012 -0500 47.2 +++ b/src/share/vm/prims/methodHandles.cpp Wed Nov 07 16:09:20 2012 -0800 47.3 @@ -233,7 +233,7 @@ 47.4 methodHandle m = info.resolved_method(); 47.5 KlassHandle defc = info.resolved_klass(); 47.6 int vmindex = -1; 47.7 - if (defc->is_interface() && Klass::cast(m->method_holder())->is_interface()) { 47.8 + if (defc->is_interface() && m->method_holder()->is_interface()) { 47.9 // LinkResolver does not report itable indexes! (fix this?) 47.10 vmindex = klassItable::compute_itable_index(m()); 47.11 } else if (m->can_be_statically_bound()) { 47.12 @@ -749,8 +749,8 @@ 47.13 DEBUG_ONLY(vmtarget = NULL); // safety 47.14 if (m.is_null()) break; 47.15 if (!have_defc) { 47.16 - Klass* defc = m->method_holder(); 47.17 - java_lang_invoke_MemberName::set_clazz(mname(), Klass::cast(defc)->java_mirror()); 47.18 + InstanceKlass* defc = m->method_holder(); 47.19 + java_lang_invoke_MemberName::set_clazz(mname(), defc->java_mirror()); 47.20 } 47.21 if (!have_name) { 47.22 //not java_lang_String::create_from_symbol; let's intern member names
48.1 --- a/src/share/vm/prims/nativeLookup.cpp Mon Nov 05 19:33:44 2012 -0500 48.2 +++ b/src/share/vm/prims/nativeLookup.cpp Wed Nov 07 16:09:20 2012 -0800 48.3 @@ -165,8 +165,7 @@ 48.4 // Note: It is critical for bootstrapping that Java_java_lang_ClassLoader_00024NativeLibrary_find 48.5 // gets found the first time around - otherwise an infinite loop can occure. This is 48.6 // another VM/library dependency 48.7 - Handle loader(THREAD, 48.8 - InstanceKlass::cast(method->method_holder())->class_loader()); 48.9 + Handle loader(THREAD, method->method_holder()->class_loader()); 48.10 if (loader.is_null()) { 48.11 entry = lookup_special_native(jni_name); 48.12 if (entry == NULL) { 48.13 @@ -393,7 +392,7 @@ 48.14 if (PrintJNIResolving) { 48.15 ResourceMark rm(THREAD); 48.16 tty->print_cr("[Dynamic-linking native method %s.%s ... JNI]", 48.17 - Klass::cast(method->method_holder())->external_name(), 48.18 + method->method_holder()->external_name(), 48.19 method->name()->as_C_string()); 48.20 } 48.21 }
49.1 --- a/src/share/vm/runtime/compilationPolicy.cpp Mon Nov 05 19:33:44 2012 -0500 49.2 +++ b/src/share/vm/runtime/compilationPolicy.cpp Wed Nov 07 16:09:20 2012 -0800 49.3 @@ -627,7 +627,7 @@ 49.4 // negative filter: should send NOT be inlined? returns NULL (--> inline) or rejection msg 49.5 if (m->is_abstract()) return (_msg = "abstract method"); 49.6 // note: we allow ik->is_abstract() 49.7 - if (!InstanceKlass::cast(m->method_holder())->is_initialized()) return (_msg = "method holder not initialized"); 49.8 + if (!m->method_holder()->is_initialized()) return (_msg = "method holder not initialized"); 49.9 if (m->is_native()) return (_msg = "native method"); 49.10 nmethod* m_code = m->code(); 49.11 if (m_code != NULL && m_code->code_size() > InlineSmallCode)
50.1 --- a/src/share/vm/runtime/deoptimization.cpp Mon Nov 05 19:33:44 2012 -0500 50.2 +++ b/src/share/vm/runtime/deoptimization.cpp Wed Nov 07 16:09:20 2012 -0800 50.3 @@ -1191,12 +1191,12 @@ 50.4 50.5 if (!constant_pool->tag_at(index).is_symbol()) return; 50.6 50.7 - Handle class_loader (THREAD, InstanceKlass::cast(constant_pool->pool_holder())->class_loader()); 50.8 + Handle class_loader (THREAD, constant_pool->pool_holder()->class_loader()); 50.9 Symbol* symbol = constant_pool->symbol_at(index); 50.10 50.11 // class name? 50.12 if (symbol->byte_at(0) != '(') { 50.13 - Handle protection_domain (THREAD, Klass::cast(constant_pool->pool_holder())->protection_domain()); 50.14 + Handle protection_domain (THREAD, constant_pool->pool_holder()->protection_domain()); 50.15 SystemDictionary::resolve_or_null(symbol, class_loader, protection_domain, CHECK); 50.16 return; 50.17 } 50.18 @@ -1206,7 +1206,7 @@ 50.19 for (SignatureStream ss(symbol); !ss.is_done(); ss.next()) { 50.20 if (ss.is_object()) { 50.21 Symbol* class_name = ss.as_symbol(CHECK); 50.22 - Handle protection_domain (THREAD, Klass::cast(constant_pool->pool_holder())->protection_domain()); 50.23 + Handle protection_domain (THREAD, constant_pool->pool_holder()->protection_domain()); 50.24 SystemDictionary::resolve_or_null(class_name, class_loader, protection_domain, CHECK); 50.25 } 50.26 }
51.1 --- a/src/share/vm/runtime/fieldDescriptor.cpp Mon Nov 05 19:33:44 2012 -0500 51.2 +++ b/src/share/vm/runtime/fieldDescriptor.cpp Wed Nov 07 16:09:20 2012 -0800 51.3 @@ -36,7 +36,7 @@ 51.4 51.5 51.6 oop fieldDescriptor::loader() const { 51.7 - return InstanceKlass::cast(_cp->pool_holder())->class_loader(); 51.8 + return _cp->pool_holder()->class_loader(); 51.9 } 51.10 51.11 Symbol* fieldDescriptor::generic_signature() const { 51.12 @@ -45,7 +45,7 @@ 51.13 } 51.14 51.15 int idx = 0; 51.16 - InstanceKlass* ik = InstanceKlass::cast(field_holder()); 51.17 + InstanceKlass* ik = field_holder(); 51.18 for (AllFieldStream fs(ik); !fs.done(); fs.next()) { 51.19 if (idx == _index) { 51.20 return fs.generic_signature(); 51.21 @@ -58,7 +58,7 @@ 51.22 } 51.23 51.24 AnnotationArray* fieldDescriptor::annotations() const { 51.25 - InstanceKlass* ik = InstanceKlass::cast(field_holder()); 51.26 + InstanceKlass* ik = field_holder(); 51.27 Array<AnnotationArray*>* md = ik->fields_annotations(); 51.28 if (md == NULL) 51.29 return NULL;
52.1 --- a/src/share/vm/runtime/fieldDescriptor.hpp Mon Nov 05 19:33:44 2012 -0500 52.2 +++ b/src/share/vm/runtime/fieldDescriptor.hpp Wed Nov 07 16:09:20 2012 -0800 52.3 @@ -43,12 +43,12 @@ 52.4 52.5 // update the access_flags for the field in the klass 52.6 void update_klass_field_access_flag() { 52.7 - InstanceKlass* ik = InstanceKlass::cast(field_holder()); 52.8 + InstanceKlass* ik = field_holder(); 52.9 ik->field(index())->set_access_flags(_access_flags.as_short()); 52.10 } 52.11 52.12 FieldInfo* field() const { 52.13 - InstanceKlass* ik = InstanceKlass::cast(field_holder()); 52.14 + InstanceKlass* ik = field_holder(); 52.15 return ik->field(_index); 52.16 } 52.17 52.18 @@ -59,46 +59,46 @@ 52.19 Symbol* signature() const { 52.20 return field()->signature(_cp); 52.21 } 52.22 - Klass* field_holder() const { return _cp->pool_holder(); } 52.23 - ConstantPool* constants() const { return _cp(); } 52.24 - AccessFlags access_flags() const { return _access_flags; } 52.25 - oop loader() const; 52.26 + InstanceKlass* field_holder() const { return _cp->pool_holder(); } 52.27 + ConstantPool* constants() const { return _cp(); } 52.28 + AccessFlags access_flags() const { return _access_flags; } 52.29 + oop loader() const; 52.30 // Offset (in words) of field from start of instanceOop / Klass* 52.31 - int offset() const { return field()->offset(); } 52.32 - Symbol* generic_signature() const; 52.33 - int index() const { return _index; } 52.34 - AnnotationArray* annotations() const; 52.35 + int offset() const { return field()->offset(); } 52.36 + Symbol* generic_signature() const; 52.37 + int index() const { return _index; } 52.38 + AnnotationArray* annotations() const; 52.39 52.40 // Initial field value 52.41 - bool has_initial_value() const { return field()->initval_index() != 0; } 52.42 - int initial_value_index() const { return field()->initval_index(); } 52.43 + bool has_initial_value() const { return field()->initval_index() != 0; } 52.44 + int initial_value_index() const { return field()->initval_index(); } 52.45 constantTag initial_value_tag() const; // The tag will return true on one of is_int(), is_long(), is_single(), is_double() 52.46 - jint int_initial_value() const; 52.47 - jlong long_initial_value() const; 52.48 - jfloat float_initial_value() const; 52.49 - jdouble double_initial_value() const; 52.50 - oop string_initial_value(TRAPS) const; 52.51 + jint int_initial_value() const; 52.52 + jlong long_initial_value() const; 52.53 + jfloat float_initial_value() const; 52.54 + jdouble double_initial_value() const; 52.55 + oop string_initial_value(TRAPS) const; 52.56 52.57 // Field signature type 52.58 - BasicType field_type() const { return FieldType::basic_type(signature()); } 52.59 + BasicType field_type() const { return FieldType::basic_type(signature()); } 52.60 52.61 // Access flags 52.62 - bool is_public() const { return access_flags().is_public(); } 52.63 - bool is_private() const { return access_flags().is_private(); } 52.64 - bool is_protected() const { return access_flags().is_protected(); } 52.65 - bool is_package_private() const { return !is_public() && !is_private() && !is_protected(); } 52.66 + bool is_public() const { return access_flags().is_public(); } 52.67 + bool is_private() const { return access_flags().is_private(); } 52.68 + bool is_protected() const { return access_flags().is_protected(); } 52.69 + bool is_package_private() const { return !is_public() && !is_private() && !is_protected(); } 52.70 52.71 - bool is_static() const { return access_flags().is_static(); } 52.72 - bool is_final() const { return access_flags().is_final(); } 52.73 - bool is_volatile() const { return access_flags().is_volatile(); } 52.74 - bool is_transient() const { return access_flags().is_transient(); } 52.75 + bool is_static() const { return access_flags().is_static(); } 52.76 + bool is_final() const { return access_flags().is_final(); } 52.77 + bool is_volatile() const { return access_flags().is_volatile(); } 52.78 + bool is_transient() const { return access_flags().is_transient(); } 52.79 52.80 - bool is_synthetic() const { return access_flags().is_synthetic(); } 52.81 + bool is_synthetic() const { return access_flags().is_synthetic(); } 52.82 52.83 - bool is_field_access_watched() const { return access_flags().is_field_access_watched(); } 52.84 + bool is_field_access_watched() const { return access_flags().is_field_access_watched(); } 52.85 bool is_field_modification_watched() const 52.86 - { return access_flags().is_field_modification_watched(); } 52.87 - bool has_generic_signature() const { return access_flags().field_has_generic_signature(); } 52.88 + { return access_flags().is_field_modification_watched(); } 52.89 + bool has_generic_signature() const { return access_flags().field_has_generic_signature(); } 52.90 52.91 void set_is_field_access_watched(const bool value) { 52.92 _access_flags.set_is_field_access_watched(value);
53.1 --- a/src/share/vm/runtime/globals.hpp Mon Nov 05 19:33:44 2012 -0500 53.2 +++ b/src/share/vm/runtime/globals.hpp Wed Nov 07 16:09:20 2012 -0800 53.3 @@ -3596,6 +3596,15 @@ 53.4 product(uintx, StringTableSize, 1009, \ 53.5 "Number of buckets in the interned String table") \ 53.6 \ 53.7 + develop(bool, TraceDefaultMethods, false, \ 53.8 + "Trace the default method processing steps") \ 53.9 + \ 53.10 + develop(bool, ParseAllGenericSignatures, false, \ 53.11 + "Parse all generic signatures while classloading") \ 53.12 + \ 53.13 + develop(bool, VerifyGenericSignatures, false, \ 53.14 + "Abort VM on erroneous or inconsistent generic signatures") \ 53.15 + \ 53.16 product(bool, UseVMInterruptibleIO, false, \ 53.17 "(Unstable, Solaris-specific) Thread interrupt before or with " \ 53.18 "EINTR for I/O operations results in OS_INTRPT. The default value"\
54.1 --- a/src/share/vm/runtime/javaCalls.cpp Mon Nov 05 19:33:44 2012 -0500 54.2 +++ b/src/share/vm/runtime/javaCalls.cpp Wed Nov 07 16:09:20 2012 -0800 54.3 @@ -189,7 +189,7 @@ 54.4 assert(method->name() == vmSymbols::object_initializer_name(), "Should only be called for default constructor"); 54.5 assert(method->signature() == vmSymbols::void_method_signature(), "Should only be called for default constructor"); 54.6 54.7 - InstanceKlass* ik = InstanceKlass::cast(method->method_holder()); 54.8 + InstanceKlass* ik = method->method_holder(); 54.9 if (ik->is_initialized() && ik->has_vanilla_constructor()) { 54.10 // safe to skip constructor call 54.11 } else { 54.12 @@ -344,11 +344,11 @@ 54.13 54.14 54.15 #ifdef ASSERT 54.16 - { Klass* holder = method->method_holder(); 54.17 + { InstanceKlass* holder = method->method_holder(); 54.18 // A klass might not be initialized since JavaCall's might be used during the executing of 54.19 // the <clinit>. For example, a Thread.start might start executing on an object that is 54.20 // not fully initialized! (bad Java programming style) 54.21 - assert(InstanceKlass::cast(holder)->is_linked(), "rewritting must have taken place"); 54.22 + assert(holder->is_linked(), "rewritting must have taken place"); 54.23 } 54.24 #endif 54.25
55.1 --- a/src/share/vm/runtime/mutexLocker.cpp Mon Nov 05 19:33:44 2012 -0500 55.2 +++ b/src/share/vm/runtime/mutexLocker.cpp Wed Nov 07 16:09:20 2012 -0800 55.3 @@ -140,6 +140,7 @@ 55.4 Monitor* JfrMsg_lock = NULL; 55.5 Mutex* JfrBuffer_lock = NULL; 55.6 Mutex* JfrStream_lock = NULL; 55.7 +Monitor* PeriodicTask_lock = NULL; 55.8 55.9 #define MAX_NUM_MUTEX 128 55.10 static Monitor * _mutex_array[MAX_NUM_MUTEX]; 55.11 @@ -285,6 +286,7 @@ 55.12 def(JfrMsg_lock , Monitor, nonleaf+2, true); 55.13 def(JfrBuffer_lock , Mutex, nonleaf+3, true); 55.14 def(JfrStream_lock , Mutex, nonleaf+4, true); 55.15 + def(PeriodicTask_lock , Monitor, nonleaf+5, true); 55.16 } 55.17 55.18 GCMutexLocker::GCMutexLocker(Monitor * mutex) {
56.1 --- a/src/share/vm/runtime/mutexLocker.hpp Mon Nov 05 19:33:44 2012 -0500 56.2 +++ b/src/share/vm/runtime/mutexLocker.hpp Wed Nov 07 16:09:20 2012 -0800 56.3 @@ -142,6 +142,7 @@ 56.4 extern Monitor* JfrMsg_lock; // protects JFR messaging 56.5 extern Mutex* JfrBuffer_lock; // protects JFR buffer operations 56.6 extern Mutex* JfrStream_lock; // protects JFR stream access 56.7 +extern Monitor* PeriodicTask_lock; // protects the periodic task structure 56.8 56.9 // A MutexLocker provides mutual exclusion with respect to a given mutex 56.10 // for the scope which contains the locker. The lock is an OS lock, not
57.1 --- a/src/share/vm/runtime/reflection.cpp Mon Nov 05 19:33:44 2012 -0500 57.2 +++ b/src/share/vm/runtime/reflection.cpp Wed Nov 07 16:09:20 2012 -0800 57.3 @@ -56,14 +56,14 @@ 57.4 vframeStream vfst(jthread); 57.5 // skip over any frames belonging to java.lang.Class 57.6 while (!vfst.at_end() && 57.7 - InstanceKlass::cast(vfst.method()->method_holder())->name() == vmSymbols::java_lang_Class()) { 57.8 + vfst.method()->method_holder()->name() == vmSymbols::java_lang_Class()) { 57.9 vfst.next(); 57.10 } 57.11 if (!vfst.at_end()) { 57.12 // this frame is a likely suspect 57.13 caller = vfst.method()->method_holder(); 57.14 line_number = vfst.method()->line_number_from_bci(vfst.bci()); 57.15 - Symbol* s = InstanceKlass::cast(vfst.method()->method_holder())->source_file_name(); 57.16 + Symbol* s = vfst.method()->method_holder()->source_file_name(); 57.17 if (s != NULL) { 57.18 source_file = s->as_C_string(); 57.19 } 57.20 @@ -472,6 +472,12 @@ 57.21 return true; 57.22 } 57.23 57.24 + // Also allow all accesses from 57.25 + // java/lang/invoke/MagicLambdaImpl subclasses to succeed trivially. 57.26 + if (current_class->is_subclass_of(SystemDictionary::lambda_MagicLambdaImpl_klass())) { 57.27 + return true; 57.28 + } 57.29 + 57.30 return can_relax_access_check_for(current_class, new_class, classloader_only); 57.31 } 57.32 57.33 @@ -564,6 +570,12 @@ 57.34 return true; 57.35 } 57.36 57.37 + // Also allow all accesses from 57.38 + // java/lang/invoke/MagicLambdaImpl subclasses to succeed trivially. 57.39 + if (current_class->is_subclass_of(SystemDictionary::lambda_MagicLambdaImpl_klass())) { 57.40 + return true; 57.41 + } 57.42 + 57.43 return can_relax_access_check_for( 57.44 current_class, field_class, classloader_only); 57.45 } 57.46 @@ -630,8 +642,8 @@ 57.47 case T_OBJECT: 57.48 case T_ARRAY: 57.49 Symbol* name = ss->as_symbol(CHECK_NULL); 57.50 - oop loader = InstanceKlass::cast(method->method_holder())->class_loader(); 57.51 - oop protection_domain = InstanceKlass::cast(method->method_holder())->protection_domain(); 57.52 + oop loader = method->method_holder()->class_loader(); 57.53 + oop protection_domain = method->method_holder()->protection_domain(); 57.54 Klass* k = SystemDictionary::resolve_or_fail( 57.55 name, 57.56 Handle(THREAD, loader), 57.57 @@ -702,7 +714,7 @@ 57.58 assert(!method()->is_initializer() || 57.59 (for_constant_pool_access && method()->is_static()) || 57.60 (method()->name() == vmSymbols::class_initializer_name() 57.61 - && Klass::cast(method()->method_holder())->is_interface() && JDK_Version::is_jdk12x_version()), "should call new_constructor instead"); 57.62 + && method()->method_holder()->is_interface() && JDK_Version::is_jdk12x_version()), "should call new_constructor instead"); 57.63 instanceKlassHandle holder (THREAD, method->method_holder()); 57.64 int slot = method->method_idnum(); 57.65 57.66 @@ -820,7 +832,7 @@ 57.67 Handle type = new_type(signature, holder, CHECK_NULL); 57.68 Handle rh = java_lang_reflect_Field::create(CHECK_NULL); 57.69 57.70 - java_lang_reflect_Field::set_clazz(rh(), Klass::cast(fd->field_holder())->java_mirror()); 57.71 + java_lang_reflect_Field::set_clazz(rh(), fd->field_holder()->java_mirror()); 57.72 java_lang_reflect_Field::set_slot(rh(), fd->index()); 57.73 java_lang_reflect_Field::set_name(rh(), name()); 57.74 java_lang_reflect_Field::set_type(rh(), type()); 57.75 @@ -888,7 +900,7 @@ 57.76 method = reflected_method; 57.77 } else { 57.78 // resolve based on the receiver 57.79 - if (InstanceKlass::cast(reflected_method->method_holder())->is_interface()) { 57.80 + if (reflected_method->method_holder()->is_interface()) { 57.81 // resolve interface call 57.82 if (ReflectionWrapResolutionErrors) { 57.83 // new default: 6531596
58.1 --- a/src/share/vm/runtime/task.cpp Mon Nov 05 19:33:44 2012 -0500 58.2 +++ b/src/share/vm/runtime/task.cpp Wed Nov 07 16:09:20 2012 -0800 58.3 @@ -61,7 +61,7 @@ 58.4 } 58.5 #endif 58.6 58.7 -void PeriodicTask::real_time_tick(size_t delay_time) { 58.8 +void PeriodicTask::real_time_tick(int delay_time) { 58.9 #ifndef PRODUCT 58.10 if (ProfilerCheckIntervals) { 58.11 _ticks++; 58.12 @@ -73,19 +73,39 @@ 58.13 _intervalHistogram[ms]++; 58.14 } 58.15 #endif 58.16 - int orig_num_tasks = _num_tasks; 58.17 - for(int index = 0; index < _num_tasks; index++) { 58.18 - _tasks[index]->execute_if_pending(delay_time); 58.19 - if (_num_tasks < orig_num_tasks) { // task dis-enrolled itself 58.20 - index--; // re-do current slot as it has changed 58.21 - orig_num_tasks = _num_tasks; 58.22 + 58.23 + { 58.24 + MutexLockerEx ml(PeriodicTask_lock, Mutex::_no_safepoint_check_flag); 58.25 + int orig_num_tasks = _num_tasks; 58.26 + 58.27 + for(int index = 0; index < _num_tasks; index++) { 58.28 + _tasks[index]->execute_if_pending(delay_time); 58.29 + if (_num_tasks < orig_num_tasks) { // task dis-enrolled itself 58.30 + index--; // re-do current slot as it has changed 58.31 + orig_num_tasks = _num_tasks; 58.32 + } 58.33 } 58.34 } 58.35 } 58.36 58.37 +int PeriodicTask::time_to_wait() { 58.38 + MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ? 58.39 + NULL : PeriodicTask_lock, Mutex::_no_safepoint_check_flag); 58.40 + 58.41 + if (_num_tasks == 0) { 58.42 + return 0; // sleep until shutdown or a task is enrolled 58.43 + } 58.44 + 58.45 + int delay = _tasks[0]->time_to_next_interval(); 58.46 + for (int index = 1; index < _num_tasks; index++) { 58.47 + delay = MIN2(delay, _tasks[index]->time_to_next_interval()); 58.48 + } 58.49 + return delay; 58.50 +} 58.51 + 58.52 58.53 PeriodicTask::PeriodicTask(size_t interval_time) : 58.54 - _counter(0), _interval(interval_time) { 58.55 + _counter(0), _interval((int) interval_time) { 58.56 // Sanity check the interval time 58.57 assert(_interval >= PeriodicTask::min_interval && 58.58 _interval <= PeriodicTask::max_interval && 58.59 @@ -94,33 +114,40 @@ 58.60 } 58.61 58.62 PeriodicTask::~PeriodicTask() { 58.63 - if (is_enrolled()) 58.64 - disenroll(); 58.65 -} 58.66 - 58.67 -bool PeriodicTask::is_enrolled() const { 58.68 - for(int index = 0; index < _num_tasks; index++) 58.69 - if (_tasks[index] == this) return true; 58.70 - return false; 58.71 + disenroll(); 58.72 } 58.73 58.74 void PeriodicTask::enroll() { 58.75 - assert(WatcherThread::watcher_thread() == NULL, "dynamic enrollment of tasks not yet supported"); 58.76 + MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ? 58.77 + NULL : PeriodicTask_lock, Mutex::_no_safepoint_check_flag); 58.78 58.79 - if (_num_tasks == PeriodicTask::max_tasks) 58.80 + if (_num_tasks == PeriodicTask::max_tasks) { 58.81 fatal("Overflow in PeriodicTask table"); 58.82 + } 58.83 _tasks[_num_tasks++] = this; 58.84 + 58.85 + WatcherThread* thread = WatcherThread::watcher_thread(); 58.86 + if (thread) { 58.87 + thread->unpark(); 58.88 + } else { 58.89 + WatcherThread::start(); 58.90 + } 58.91 } 58.92 58.93 void PeriodicTask::disenroll() { 58.94 - assert(WatcherThread::watcher_thread() == NULL || 58.95 - Thread::current() == WatcherThread::watcher_thread(), 58.96 - "dynamic disenrollment currently only handled from WatcherThread from within task() method"); 58.97 + MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ? 58.98 + NULL : PeriodicTask_lock, Mutex::_no_safepoint_check_flag); 58.99 58.100 int index; 58.101 - for(index = 0; index < _num_tasks && _tasks[index] != this; index++); 58.102 - if (index == _num_tasks) return; 58.103 + for(index = 0; index < _num_tasks && _tasks[index] != this; index++) 58.104 + ; 58.105 + 58.106 + if (index == _num_tasks) { 58.107 + return; 58.108 + } 58.109 + 58.110 _num_tasks--; 58.111 + 58.112 for (; index < _num_tasks; index++) { 58.113 _tasks[index] = _tasks[index+1]; 58.114 }
59.1 --- a/src/share/vm/runtime/task.hpp Mon Nov 05 19:33:44 2012 -0500 59.2 +++ b/src/share/vm/runtime/task.hpp Wed Nov 07 16:09:20 2012 -0800 59.3 @@ -49,12 +49,12 @@ 59.4 static int num_tasks() { return _num_tasks; } 59.5 59.6 private: 59.7 - size_t _counter; 59.8 - const size_t _interval; 59.9 + int _counter; 59.10 + const int _interval; 59.11 59.12 static int _num_tasks; 59.13 static PeriodicTask* _tasks[PeriodicTask::max_tasks]; 59.14 - static void real_time_tick(size_t delay_time); 59.15 + static void real_time_tick(int delay_time); 59.16 59.17 #ifndef PRODUCT 59.18 static elapsedTimer _timer; // measures time between ticks 59.19 @@ -69,51 +69,36 @@ 59.20 PeriodicTask(size_t interval_time); // interval is in milliseconds of elapsed time 59.21 ~PeriodicTask(); 59.22 59.23 - // Tells whether is enrolled 59.24 - bool is_enrolled() const; 59.25 - 59.26 // Make the task active 59.27 - // NOTE: this may only be called before the WatcherThread has been started 59.28 + // For dynamic enrollment at the time T, the task will execute somewhere 59.29 + // between T and T + interval_time. 59.30 void enroll(); 59.31 59.32 // Make the task deactive 59.33 - // NOTE: this may only be called either while the WatcherThread is 59.34 - // inactive or by a task from within its task() method. One-shot or 59.35 - // several-shot tasks may be implemented this way. 59.36 void disenroll(); 59.37 59.38 - void execute_if_pending(size_t delay_time) { 59.39 - _counter += delay_time; 59.40 - if (_counter >= _interval) { 59.41 + void execute_if_pending(int delay_time) { 59.42 + // make sure we don't overflow 59.43 + jlong tmp = (jlong) _counter + (jlong) delay_time; 59.44 + 59.45 + if (tmp >= (jlong) _interval) { 59.46 _counter = 0; 59.47 task(); 59.48 + } else { 59.49 + _counter += delay_time; 59.50 } 59.51 } 59.52 59.53 // Returns how long (time in milliseconds) before the next time we should 59.54 // execute this task. 59.55 - size_t time_to_next_interval() const { 59.56 + int time_to_next_interval() const { 59.57 assert(_interval > _counter, "task counter greater than interval?"); 59.58 return _interval - _counter; 59.59 } 59.60 59.61 // Calculate when the next periodic task will fire. 59.62 // Called by the WatcherThread's run method. 59.63 - // This assumes that periodic tasks aren't entering the system 59.64 - // dynamically, except for during startup. 59.65 - static size_t time_to_wait() { 59.66 - if (_num_tasks == 0) { 59.67 - // Don't wait any more; shut down the thread since we don't 59.68 - // currently support dynamic enrollment. 59.69 - return 0; 59.70 - } 59.71 - 59.72 - size_t delay = _tasks[0]->time_to_next_interval(); 59.73 - for (int index = 1; index < _num_tasks; index++) { 59.74 - delay = MIN2(delay, _tasks[index]->time_to_next_interval()); 59.75 - } 59.76 - return delay; 59.77 - } 59.78 + static int time_to_wait(); 59.79 59.80 // The task to perform at each period 59.81 virtual void task() = 0;
60.1 --- a/src/share/vm/runtime/thread.cpp Mon Nov 05 19:33:44 2012 -0500 60.2 +++ b/src/share/vm/runtime/thread.cpp Wed Nov 07 16:09:20 2012 -0800 60.3 @@ -1217,6 +1217,7 @@ 60.4 // timer interrupts exists on the platform. 60.5 60.6 WatcherThread* WatcherThread::_watcher_thread = NULL; 60.7 +bool WatcherThread::_startable = false; 60.8 volatile bool WatcherThread::_should_terminate = false; 60.9 60.10 WatcherThread::WatcherThread() : Thread() { 60.11 @@ -1237,6 +1238,55 @@ 60.12 } 60.13 } 60.14 60.15 +int WatcherThread::sleep() const { 60.16 + MutexLockerEx ml(PeriodicTask_lock, Mutex::_no_safepoint_check_flag); 60.17 + 60.18 + // remaining will be zero if there are no tasks, 60.19 + // causing the WatcherThread to sleep until a task is 60.20 + // enrolled 60.21 + int remaining = PeriodicTask::time_to_wait(); 60.22 + int time_slept = 0; 60.23 + 60.24 + // we expect this to timeout - we only ever get unparked when 60.25 + // we should terminate or when a new task has been enrolled 60.26 + OSThreadWaitState osts(this->osthread(), false /* not Object.wait() */); 60.27 + 60.28 + jlong time_before_loop = os::javaTimeNanos(); 60.29 + 60.30 + for (;;) { 60.31 + bool timedout = PeriodicTask_lock->wait(Mutex::_no_safepoint_check_flag, remaining); 60.32 + jlong now = os::javaTimeNanos(); 60.33 + 60.34 + if (remaining == 0) { 60.35 + // if we didn't have any tasks we could have waited for a long time 60.36 + // consider the time_slept zero and reset time_before_loop 60.37 + time_slept = 0; 60.38 + time_before_loop = now; 60.39 + } else { 60.40 + // need to recalulate since we might have new tasks in _tasks 60.41 + time_slept = (int) ((now - time_before_loop) / 1000000); 60.42 + } 60.43 + 60.44 + // Change to task list or spurious wakeup of some kind 60.45 + if (timedout || _should_terminate) { 60.46 + break; 60.47 + } 60.48 + 60.49 + remaining = PeriodicTask::time_to_wait(); 60.50 + if (remaining == 0) { 60.51 + // Last task was just disenrolled so loop around and wait until 60.52 + // another task gets enrolled 60.53 + continue; 60.54 + } 60.55 + 60.56 + remaining -= time_slept; 60.57 + if (remaining <= 0) 60.58 + break; 60.59 + } 60.60 + 60.61 + return time_slept; 60.62 +} 60.63 + 60.64 void WatcherThread::run() { 60.65 assert(this == watcher_thread(), "just checking"); 60.66 60.67 @@ -1249,26 +1299,7 @@ 60.68 60.69 // Calculate how long it'll be until the next PeriodicTask work 60.70 // should be done, and sleep that amount of time. 60.71 - size_t time_to_wait = PeriodicTask::time_to_wait(); 60.72 - 60.73 - // we expect this to timeout - we only ever get unparked when 60.74 - // we should terminate 60.75 - { 60.76 - OSThreadWaitState osts(this->osthread(), false /* not Object.wait() */); 60.77 - 60.78 - jlong prev_time = os::javaTimeNanos(); 60.79 - for (;;) { 60.80 - int res= _SleepEvent->park(time_to_wait); 60.81 - if (res == OS_TIMEOUT || _should_terminate) 60.82 - break; 60.83 - // spurious wakeup of some kind 60.84 - jlong now = os::javaTimeNanos(); 60.85 - time_to_wait -= (now - prev_time) / 1000000; 60.86 - if (time_to_wait <= 0) 60.87 - break; 60.88 - prev_time = now; 60.89 - } 60.90 - } 60.91 + int time_waited = sleep(); 60.92 60.93 if (is_error_reported()) { 60.94 // A fatal error has happened, the error handler(VMError::report_and_die) 60.95 @@ -1298,13 +1329,7 @@ 60.96 } 60.97 } 60.98 60.99 - PeriodicTask::real_time_tick(time_to_wait); 60.100 - 60.101 - // If we have no more tasks left due to dynamic disenrollment, 60.102 - // shut down the thread since we don't currently support dynamic enrollment 60.103 - if (PeriodicTask::num_tasks() == 0) { 60.104 - _should_terminate = true; 60.105 - } 60.106 + PeriodicTask::real_time_tick(time_waited); 60.107 } 60.108 60.109 // Signal that it is terminated 60.110 @@ -1319,22 +1344,33 @@ 60.111 } 60.112 60.113 void WatcherThread::start() { 60.114 - if (watcher_thread() == NULL) { 60.115 + assert(PeriodicTask_lock->owned_by_self(), "PeriodicTask_lock required"); 60.116 + 60.117 + if (watcher_thread() == NULL && _startable) { 60.118 _should_terminate = false; 60.119 // Create the single instance of WatcherThread 60.120 new WatcherThread(); 60.121 } 60.122 } 60.123 60.124 +void WatcherThread::make_startable() { 60.125 + assert(PeriodicTask_lock->owned_by_self(), "PeriodicTask_lock required"); 60.126 + _startable = true; 60.127 +} 60.128 + 60.129 void WatcherThread::stop() { 60.130 + { 60.131 + MutexLockerEx ml(PeriodicTask_lock, Mutex::_no_safepoint_check_flag); 60.132 + _should_terminate = true; 60.133 + OrderAccess::fence(); // ensure WatcherThread sees update in main loop 60.134 + 60.135 + WatcherThread* watcher = watcher_thread(); 60.136 + if (watcher != NULL) 60.137 + watcher->unpark(); 60.138 + } 60.139 + 60.140 // it is ok to take late safepoints here, if needed 60.141 MutexLocker mu(Terminator_lock); 60.142 - _should_terminate = true; 60.143 - OrderAccess::fence(); // ensure WatcherThread sees update in main loop 60.144 - 60.145 - Thread* watcher = watcher_thread(); 60.146 - if (watcher != NULL) 60.147 - watcher->_SleepEvent->unpark(); 60.148 60.149 while(watcher_thread() != NULL) { 60.150 // This wait should make safepoint checks, wait without a timeout, 60.151 @@ -1352,6 +1388,11 @@ 60.152 } 60.153 } 60.154 60.155 +void WatcherThread::unpark() { 60.156 + MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ? NULL : PeriodicTask_lock, Mutex::_no_safepoint_check_flag); 60.157 + PeriodicTask_lock->notify(); 60.158 +} 60.159 + 60.160 void WatcherThread::print_on(outputStream* st) const { 60.161 st->print("\"%s\" ", name()); 60.162 Thread::print_on(st); 60.163 @@ -3658,12 +3699,18 @@ 60.164 } 60.165 } 60.166 60.167 - // Start up the WatcherThread if there are any periodic tasks 60.168 - // NOTE: All PeriodicTasks should be registered by now. If they 60.169 - // aren't, late joiners might appear to start slowly (we might 60.170 - // take a while to process their first tick). 60.171 - if (PeriodicTask::num_tasks() > 0) { 60.172 - WatcherThread::start(); 60.173 + { 60.174 + MutexLockerEx ml(PeriodicTask_lock, Mutex::_no_safepoint_check_flag); 60.175 + // Make sure the watcher thread can be started by WatcherThread::start() 60.176 + // or by dynamic enrollment. 60.177 + WatcherThread::make_startable(); 60.178 + // Start up the WatcherThread if there are any periodic tasks 60.179 + // NOTE: All PeriodicTasks should be registered by now. If they 60.180 + // aren't, late joiners might appear to start slowly (we might 60.181 + // take a while to process their first tick). 60.182 + if (PeriodicTask::num_tasks() > 0) { 60.183 + WatcherThread::start(); 60.184 + } 60.185 } 60.186 60.187 // Give os specific code one last chance to start
61.1 --- a/src/share/vm/runtime/thread.hpp Mon Nov 05 19:33:44 2012 -0500 61.2 +++ b/src/share/vm/runtime/thread.hpp Wed Nov 07 16:09:20 2012 -0800 61.3 @@ -722,6 +722,7 @@ 61.4 private: 61.5 static WatcherThread* _watcher_thread; 61.6 61.7 + static bool _startable; 61.8 volatile static bool _should_terminate; // updated without holding lock 61.9 public: 61.10 enum SomeConstants { 61.11 @@ -738,6 +739,7 @@ 61.12 char* name() const { return (char*)"VM Periodic Task Thread"; } 61.13 void print_on(outputStream* st) const; 61.14 void print() const { print_on(tty); } 61.15 + void unpark(); 61.16 61.17 // Returns the single instance of WatcherThread 61.18 static WatcherThread* watcher_thread() { return _watcher_thread; } 61.19 @@ -745,6 +747,12 @@ 61.20 // Create and start the single instance of WatcherThread, or stop it on shutdown 61.21 static void start(); 61.22 static void stop(); 61.23 + // Only allow start once the VM is sufficiently initialized 61.24 + // Otherwise the first task to enroll will trigger the start 61.25 + static void make_startable(); 61.26 + 61.27 + private: 61.28 + int sleep() const; 61.29 }; 61.30 61.31
62.1 --- a/src/share/vm/runtime/vframe.cpp Mon Nov 05 19:33:44 2012 -0500 62.2 +++ b/src/share/vm/runtime/vframe.cpp Wed Nov 07 16:09:20 2012 -0800 62.3 @@ -161,7 +161,7 @@ 62.4 // If this is the first frame, and java.lang.Object.wait(...) then print out the receiver. 62.5 if (frame_count == 0) { 62.6 if (method()->name() == vmSymbols::wait_name() && 62.7 - InstanceKlass::cast(method()->method_holder())->name() == vmSymbols::java_lang_Object()) { 62.8 + method()->method_holder()->name() == vmSymbols::java_lang_Object()) { 62.9 StackValueCollection* locs = locals(); 62.10 if (!locs->is_empty()) { 62.11 StackValue* sv = locs->at(0); 62.12 @@ -407,7 +407,7 @@ 62.13 if (Universe::reflect_invoke_cache()->is_same_method(method())) { 62.14 // This is Method.invoke() -- skip it 62.15 } else if (use_new_reflection && 62.16 - Klass::cast(method()->method_holder()) 62.17 + method()->method_holder() 62.18 ->is_subclass_of(SystemDictionary::reflect_MethodAccessorImpl_klass())) { 62.19 // This is an auxilary frame -- skip it 62.20 } else if (method()->is_method_handle_intrinsic() || 62.21 @@ -471,8 +471,8 @@ 62.22 void vframeStreamCommon::skip_reflection_related_frames() { 62.23 while (!at_end() && 62.24 (JDK_Version::is_gte_jdk14x_version() && UseNewReflection && 62.25 - (Klass::cast(method()->method_holder())->is_subclass_of(SystemDictionary::reflect_MethodAccessorImpl_klass()) || 62.26 - Klass::cast(method()->method_holder())->is_subclass_of(SystemDictionary::reflect_ConstructorAccessorImpl_klass())))) { 62.27 + (method()->method_holder()->is_subclass_of(SystemDictionary::reflect_MethodAccessorImpl_klass()) || 62.28 + method()->method_holder()->is_subclass_of(SystemDictionary::reflect_ConstructorAccessorImpl_klass())))) { 62.29 next(); 62.30 } 62.31 } 62.32 @@ -547,13 +547,13 @@ 62.33 62.34 void javaVFrame::print_value() const { 62.35 Method* m = method(); 62.36 - Klass* k = m->method_holder(); 62.37 + InstanceKlass* k = m->method_holder(); 62.38 tty->print_cr("frame( sp=" INTPTR_FORMAT ", unextended_sp=" INTPTR_FORMAT ", fp=" INTPTR_FORMAT ", pc=" INTPTR_FORMAT ")", 62.39 _fr.sp(), _fr.unextended_sp(), _fr.fp(), _fr.pc()); 62.40 tty->print("%s.%s", Klass::cast(k)->internal_name(), m->name()->as_C_string()); 62.41 62.42 if (!m->is_native()) { 62.43 - Symbol* source_name = InstanceKlass::cast(k)->source_file_name(); 62.44 + Symbol* source_name = k->source_file_name(); 62.45 int line_number = m->line_number_from_bci(bci()); 62.46 if (source_name != NULL && (line_number != -1)) { 62.47 tty->print("(%s:%d)", source_name->as_C_string(), line_number);
63.1 --- a/src/share/vm/runtime/vmStructs.cpp Mon Nov 05 19:33:44 2012 -0500 63.2 +++ b/src/share/vm/runtime/vmStructs.cpp Wed Nov 07 16:09:20 2012 -0800 63.3 @@ -289,7 +289,7 @@ 63.4 nonstatic_field(CompiledICHolder, _holder_klass, Klass*) \ 63.5 nonstatic_field(ConstantPool, _tags, Array<u1>*) \ 63.6 nonstatic_field(ConstantPool, _cache, ConstantPoolCache*) \ 63.7 - nonstatic_field(ConstantPool, _pool_holder, Klass*) \ 63.8 + nonstatic_field(ConstantPool, _pool_holder, InstanceKlass*) \ 63.9 nonstatic_field(ConstantPool, _operands, Array<u2>*) \ 63.10 nonstatic_field(ConstantPool, _length, int) \ 63.11 nonstatic_field(ConstantPool, _resolved_references, jobject) \
64.1 --- a/src/share/vm/services/heapDumper.cpp Mon Nov 05 19:33:44 2012 -0500 64.2 +++ b/src/share/vm/services/heapDumper.cpp Wed Nov 07 16:09:20 2012 -0800 64.3 @@ -1117,8 +1117,8 @@ 64.4 writer->write_symbolID(m->name()); // method's name 64.5 writer->write_symbolID(m->signature()); // method's signature 64.6 64.7 - assert(Klass::cast(m->method_holder())->oop_is_instance(), "not InstanceKlass"); 64.8 - writer->write_symbolID(InstanceKlass::cast(m->method_holder())->source_file_name()); // source file name 64.9 + assert(m->method_holder()->oop_is_instance(), "not InstanceKlass"); 64.10 + writer->write_symbolID(m->method_holder()->source_file_name()); // source file name 64.11 writer->write_u4(class_serial_num); // class serial number 64.12 writer->write_u4((u4) line_number); // line number 64.13 }
65.1 --- a/src/share/vm/services/memPtr.hpp Mon Nov 05 19:33:44 2012 -0500 65.2 +++ b/src/share/vm/services/memPtr.hpp Wed Nov 07 16:09:20 2012 -0800 65.3 @@ -311,6 +311,17 @@ 65.4 inline bool contains_address(address add) const { 65.5 return (addr() <= add && addr() + size() > add); 65.6 } 65.7 + 65.8 + // if this memory region overlaps another region 65.9 + inline bool overlaps_region(const MemPointerRecord* other) const { 65.10 + assert(other != NULL, "Just check"); 65.11 + assert(size() > 0 && other->size() > 0, "empty range"); 65.12 + return contains_address(other->addr()) || 65.13 + contains_address(other->addr() + other->size() - 1) || // exclude end address 65.14 + other->contains_address(addr()) || 65.15 + other->contains_address(addr() + size() - 1); // exclude end address 65.16 + } 65.17 + 65.18 }; 65.19 65.20 // MemPointerRecordEx also records callsite pc, from where
66.1 --- a/src/share/vm/services/memSnapshot.cpp Mon Nov 05 19:33:44 2012 -0500 66.2 +++ b/src/share/vm/services/memSnapshot.cpp Wed Nov 07 16:09:20 2012 -0800 66.3 @@ -31,6 +31,69 @@ 66.4 #include "services/memSnapshot.hpp" 66.5 #include "services/memTracker.hpp" 66.6 66.7 +#ifdef ASSERT 66.8 + 66.9 +void decode_pointer_record(MemPointerRecord* rec) { 66.10 + tty->print("Pointer: [" PTR_FORMAT " - " PTR_FORMAT "] size = %d bytes", rec->addr(), 66.11 + rec->addr() + rec->size(), (int)rec->size()); 66.12 + tty->print(" type = %s", MemBaseline::type2name(FLAGS_TO_MEMORY_TYPE(rec->flags()))); 66.13 + if (rec->is_vm_pointer()) { 66.14 + if (rec->is_allocation_record()) { 66.15 + tty->print_cr(" (reserve)"); 66.16 + } else if (rec->is_commit_record()) { 66.17 + tty->print_cr(" (commit)"); 66.18 + } else if (rec->is_uncommit_record()) { 66.19 + tty->print_cr(" (uncommit)"); 66.20 + } else if (rec->is_deallocation_record()) { 66.21 + tty->print_cr(" (release)"); 66.22 + } else { 66.23 + tty->print_cr(" (tag)"); 66.24 + } 66.25 + } else { 66.26 + if (rec->is_arena_size_record()) { 66.27 + tty->print_cr(" (arena size)"); 66.28 + } else if (rec->is_allocation_record()) { 66.29 + tty->print_cr(" (malloc)"); 66.30 + } else { 66.31 + tty->print_cr(" (free)"); 66.32 + } 66.33 + } 66.34 + if (MemTracker::track_callsite()) { 66.35 + char buf[1024]; 66.36 + address pc = ((MemPointerRecordEx*)rec)->pc(); 66.37 + if (pc != NULL && os::dll_address_to_function_name(pc, buf, sizeof(buf), NULL)) { 66.38 + tty->print_cr("\tfrom %s", buf); 66.39 + } else { 66.40 + tty->print_cr("\tcould not decode pc = " PTR_FORMAT "", pc); 66.41 + } 66.42 + } 66.43 +} 66.44 + 66.45 +void decode_vm_region_record(VMMemRegion* rec) { 66.46 + tty->print("VM Region [" PTR_FORMAT " - " PTR_FORMAT "]", rec->addr(), 66.47 + rec->addr() + rec->size()); 66.48 + tty->print(" type = %s", MemBaseline::type2name(FLAGS_TO_MEMORY_TYPE(rec->flags()))); 66.49 + if (rec->is_allocation_record()) { 66.50 + tty->print_cr(" (reserved)"); 66.51 + } else if (rec->is_commit_record()) { 66.52 + tty->print_cr(" (committed)"); 66.53 + } else { 66.54 + ShouldNotReachHere(); 66.55 + } 66.56 + if (MemTracker::track_callsite()) { 66.57 + char buf[1024]; 66.58 + address pc = ((VMMemRegionEx*)rec)->pc(); 66.59 + if (pc != NULL && os::dll_address_to_function_name(pc, buf, sizeof(buf), NULL)) { 66.60 + tty->print_cr("\tfrom %s", buf); 66.61 + } else { 66.62 + tty->print_cr("\tcould not decode pc = " PTR_FORMAT "", pc); 66.63 + } 66.64 + 66.65 + } 66.66 +} 66.67 + 66.68 +#endif 66.69 + 66.70 66.71 bool VMMemPointerIterator::insert_record(MemPointerRecord* rec) { 66.72 VMMemRegionEx new_rec; 66.73 @@ -73,52 +136,61 @@ 66.74 return true; 66.75 } 66.76 assert(cur->base() > rec->addr(), "Just check: locate()"); 66.77 - assert(rec->addr() + rec->size() <= cur->base(), "Can not overlap"); 66.78 + assert(!cur->overlaps_region(rec), "overlapping reserved regions"); 66.79 return insert_record(rec); 66.80 } 66.81 66.82 // we do consolidate committed regions 66.83 bool VMMemPointerIterator::add_committed_region(MemPointerRecord* rec) { 66.84 assert(rec->is_commit_record(), "Sanity check"); 66.85 - VMMemRegion* cur; 66.86 - cur = (VMMemRegion*)current(); 66.87 - assert(cur->is_reserved_region() && cur->contains_region(rec), 66.88 + VMMemRegion* reserved_rgn = (VMMemRegion*)current(); 66.89 + assert(reserved_rgn->is_reserved_region() && reserved_rgn->contains_region(rec), 66.90 "Sanity check"); 66.91 66.92 // thread's native stack is always marked as "committed", ignore 66.93 // the "commit" operation for creating stack guard pages 66.94 - if (FLAGS_TO_MEMORY_TYPE(cur->flags()) == mtThreadStack && 66.95 + if (FLAGS_TO_MEMORY_TYPE(reserved_rgn->flags()) == mtThreadStack && 66.96 FLAGS_TO_MEMORY_TYPE(rec->flags()) != mtThreadStack) { 66.97 return true; 66.98 } 66.99 66.100 - cur = (VMMemRegion*)next(); 66.101 - while (cur != NULL && cur->is_committed_region()) { 66.102 + // if the reserved region has any committed regions 66.103 + VMMemRegion* committed_rgn = (VMMemRegion*)next(); 66.104 + while (committed_rgn != NULL && committed_rgn->is_committed_region()) { 66.105 // duplicated commit records 66.106 - if(cur->contains_region(rec)) { 66.107 + if(committed_rgn->contains_region(rec)) { 66.108 return true; 66.109 - } 66.110 - if (cur->base() > rec->addr()) { 66.111 - // committed regions can not overlap 66.112 - assert(rec->addr() + rec->size() <= cur->base(), "Can not overlap"); 66.113 - if (rec->addr() + rec->size() == cur->base()) { 66.114 - cur->expand_region(rec->addr(), rec->size()); 66.115 - return true; 66.116 + } else if (committed_rgn->overlaps_region(rec)) { 66.117 + // overlaps front part 66.118 + if (rec->addr() < committed_rgn->addr()) { 66.119 + committed_rgn->expand_region(rec->addr(), 66.120 + committed_rgn->addr() - rec->addr()); 66.121 } else { 66.122 - return insert_record(rec); 66.123 + // overlaps tail part 66.124 + address committed_rgn_end = committed_rgn->addr() + 66.125 + committed_rgn->size(); 66.126 + assert(committed_rgn_end < rec->addr() + rec->size(), 66.127 + "overlap tail part"); 66.128 + committed_rgn->expand_region(committed_rgn_end, 66.129 + (rec->addr() + rec->size()) - committed_rgn_end); 66.130 } 66.131 - } else if (cur->base() + cur->size() == rec->addr()) { 66.132 - cur->expand_region(rec->addr(), rec->size()); 66.133 + } else if (committed_rgn->base() + committed_rgn->size() == rec->addr()) { 66.134 + // adjunct each other 66.135 + committed_rgn->expand_region(rec->addr(), rec->size()); 66.136 VMMemRegion* next_reg = (VMMemRegion*)next(); 66.137 // see if we can consolidate next committed region 66.138 if (next_reg != NULL && next_reg->is_committed_region() && 66.139 - next_reg->base() == cur->base() + cur->size()) { 66.140 - cur->expand_region(next_reg->base(), next_reg->size()); 66.141 + next_reg->base() == committed_rgn->base() + committed_rgn->size()) { 66.142 + committed_rgn->expand_region(next_reg->base(), next_reg->size()); 66.143 + // delete merged region 66.144 remove(); 66.145 } 66.146 return true; 66.147 + } else if (committed_rgn->base() > rec->addr()) { 66.148 + // found the location, insert this committed region 66.149 + return insert_record(rec); 66.150 } 66.151 - cur = (VMMemRegion*)next(); 66.152 + committed_rgn = (VMMemRegion*)next(); 66.153 } 66.154 return insert_record(rec); 66.155 }
67.1 --- a/src/share/vm/utilities/growableArray.hpp Mon Nov 05 19:33:44 2012 -0500 67.2 +++ b/src/share/vm/utilities/growableArray.hpp Wed Nov 07 16:09:20 2012 -0800 67.3 @@ -217,7 +217,12 @@ 67.4 return missed; 67.5 } 67.6 67.7 - E at(int i) const { 67.8 + E& at(int i) { 67.9 + assert(0 <= i && i < _len, "illegal index"); 67.10 + return _data[i]; 67.11 + } 67.12 + 67.13 + E const& at(int i) const { 67.14 assert(0 <= i && i < _len, "illegal index"); 67.15 return _data[i]; 67.16 }
68.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 68.2 +++ b/src/share/vm/utilities/pair.hpp Wed Nov 07 16:09:20 2012 -0800 68.3 @@ -0,0 +1,42 @@ 68.4 +/* 68.5 + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. 68.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 68.7 + * 68.8 + * This code is free software; you can redistribute it and/or modify it 68.9 + * under the terms of the GNU General Public License version 2 only, as 68.10 + * published by the Free Software Foundation. 68.11 + * 68.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 68.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 68.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 68.15 + * version 2 for more details (a copy is included in the LICENSE file that 68.16 + * accompanied this code). 68.17 + * 68.18 + * You should have received a copy of the GNU General Public License version 68.19 + * 2 along with this work; if not, write to the Free Software Foundation, 68.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 68.21 + * 68.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 68.23 + * or visit www.oracle.com if you need additional information or have any 68.24 + * questions. 68.25 + * 68.26 + */ 68.27 + 68.28 +#ifndef SHARE_VM_UTILITIES_PAIR_HPP 68.29 +#define SHARE_VM_UTILITIES_PAIR_HPP 68.30 + 68.31 +#include "memory/allocation.hpp" 68.32 +#include "utilities/top.hpp" 68.33 + 68.34 +template<typename T, typename V, typename ALLOC_BASE = ResourceObj> 68.35 +class Pair : public ALLOC_BASE { 68.36 + public: 68.37 + T first; 68.38 + V second; 68.39 + 68.40 + Pair() {} 68.41 + Pair(T t, V v) : first(t), second(v) {} 68.42 +}; 68.43 + 68.44 + 68.45 +#endif // SHARE_VM_UTILITIES_PAIR_HPP
69.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 69.2 +++ b/src/share/vm/utilities/resourceHash.hpp Wed Nov 07 16:09:20 2012 -0800 69.3 @@ -0,0 +1,134 @@ 69.4 +/* 69.5 + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. 69.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 69.7 + * 69.8 + * This code is free software; you can redistribute it and/or modify it 69.9 + * under the terms of the GNU General Public License version 2 only, as 69.10 + * published by the Free Software Foundation. 69.11 + * 69.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 69.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 69.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 69.15 + * version 2 for more details (a copy is included in the LICENSE file that 69.16 + * accompanied this code). 69.17 + * 69.18 + * You should have received a copy of the GNU General Public License version 69.19 + * 2 along with this work; if not, write to the Free Software Foundation, 69.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 69.21 + * 69.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 69.23 + * or visit www.oracle.com if you need additional information or have any 69.24 + * questions. 69.25 + * 69.26 + */ 69.27 + 69.28 +#ifndef SHARE_VM_UTILITIES_RESOURCEHASH_HPP 69.29 +#define SHARE_VM_UTILITIES_RESOURCEHASH_HPP 69.30 + 69.31 +#include "memory/allocation.hpp" 69.32 +#include "utilities/top.hpp" 69.33 + 69.34 +template<typename K> struct ResourceHashtableFns { 69.35 + typedef unsigned (*hash_fn)(K const&); 69.36 + typedef bool (*equals_fn)(K const&, K const&); 69.37 +}; 69.38 + 69.39 +template<typename K> unsigned primitive_hash(const K& k) { 69.40 + unsigned hash = (unsigned)((uintptr_t)k); 69.41 + return hash ^ (hash > 3); // just in case we're dealing with aligned ptrs 69.42 +} 69.43 + 69.44 +template<typename K> bool primitive_equals(const K& k0, const K& k1) { 69.45 + return k0 == k1; 69.46 +} 69.47 + 69.48 +template< 69.49 + typename K, typename V, 69.50 + typename ResourceHashtableFns<K>::hash_fn HASH = primitive_hash<K>, 69.51 + typename ResourceHashtableFns<K>::equals_fn EQUALS = primitive_equals<K>, 69.52 + unsigned SIZE = 256 69.53 + > 69.54 +class ResourceHashtable : public ResourceObj { 69.55 + private: 69.56 + 69.57 + class Node : public ResourceObj { 69.58 + public: 69.59 + unsigned _hash; 69.60 + K _key; 69.61 + V _value; 69.62 + Node* _next; 69.63 + 69.64 + Node(unsigned hash, K const& key, V const& value) : 69.65 + _hash(hash), _key(key), _value(value), _next(NULL) {} 69.66 + }; 69.67 + 69.68 + Node* _table[SIZE]; 69.69 + 69.70 + // Returns a pointer to where the node where the value would reside if 69.71 + // it's in the table. 69.72 + Node** lookup_node(unsigned hash, K const& key) { 69.73 + unsigned index = hash % SIZE; 69.74 + Node** ptr = &_table[index]; 69.75 + while (*ptr != NULL) { 69.76 + Node* node = *ptr; 69.77 + if (node->_hash == hash && EQUALS(key, node->_key)) { 69.78 + break; 69.79 + } 69.80 + ptr = &(node->_next); 69.81 + } 69.82 + return ptr; 69.83 + } 69.84 + 69.85 + Node const** lookup_node(unsigned hash, K const& key) const { 69.86 + return const_cast<Node const**>( 69.87 + const_cast<ResourceHashtable*>(this)->lookup_node(hash, key)); 69.88 + } 69.89 + 69.90 + public: 69.91 + ResourceHashtable() { memset(_table, 0, SIZE * sizeof(Node*)); } 69.92 + 69.93 + bool contains(K const& key) const { 69.94 + return get(key) != NULL; 69.95 + } 69.96 + 69.97 + V* get(K const& key) const { 69.98 + unsigned hv = HASH(key); 69.99 + Node const** ptr = lookup_node(hv, key); 69.100 + if (*ptr != NULL) { 69.101 + return const_cast<V*>(&(*ptr)->_value); 69.102 + } else { 69.103 + return NULL; 69.104 + } 69.105 + } 69.106 + 69.107 + // Inserts or replaces a value in the table 69.108 + void put(K const& key, V const& value) { 69.109 + unsigned hv = HASH(key); 69.110 + Node** ptr = lookup_node(hv, key); 69.111 + if (*ptr != NULL) { 69.112 + (*ptr)->_value = value; 69.113 + } else { 69.114 + *ptr = new Node(hv, key, value); 69.115 + } 69.116 + } 69.117 + 69.118 + // ITER contains bool do_entry(K const&, V const&), which will be 69.119 + // called for each entry in the table. If do_entry() returns false, 69.120 + // the iteration is cancelled. 69.121 + template<class ITER> 69.122 + void iterate(ITER* iter) const { 69.123 + Node* const* bucket = _table; 69.124 + while (bucket < &_table[SIZE]) { 69.125 + Node* node = *bucket; 69.126 + while (node != NULL) { 69.127 + bool cont = iter->do_entry(node->_key, node->_value); 69.128 + if (!cont) { return; } 69.129 + node = node->_next; 69.130 + } 69.131 + ++bucket; 69.132 + } 69.133 + } 69.134 +}; 69.135 + 69.136 + 69.137 +#endif // SHARE_VM_UTILITIES_RESOURCEHASH_HPP