Mercurial > hg > truffle
diff src/share/vm/oops/constantPoolOop.cpp @ 1602:136b78722a08
6939203: JSR 292 needs method handle constants
Summary: Add new CP types CONSTANT_MethodHandle, CONSTANT_MethodType; extend 'ldc' bytecode.
Reviewed-by: twisti, never
author | jrose |
---|---|
date | Wed, 09 Jun 2010 18:50:45 -0700 |
parents | e9ff18c4ace7 |
children | 083fde3b838e |
line wrap: on
line diff
--- a/src/share/vm/oops/constantPoolOop.cpp Mon Jun 07 14:17:01 2010 -0700 +++ b/src/share/vm/oops/constantPoolOop.cpp Wed Jun 09 18:50:45 2010 -0700 @@ -358,6 +358,11 @@ return klass_at_noresolve(ref_index); } +symbolOop constantPoolOopDesc::uncached_klass_ref_at_noresolve(int which) { + jint ref_index = uncached_klass_ref_index_at(which); + return klass_at_noresolve(ref_index); +} + char* constantPoolOopDesc::string_at_noresolve(int which) { // Test entry type in case string is resolved while in here. oop entry = *(obj_at_addr(which)); @@ -384,6 +389,119 @@ } } +oop constantPoolOopDesc::resolve_constant_at_impl(constantPoolHandle this_oop, int index, int cache_index, TRAPS) { + oop result_oop = NULL; + if (cache_index >= 0) { + assert(index < 0, "only one kind of index at a time"); + ConstantPoolCacheEntry* cpc_entry = this_oop->cache()->entry_at(cache_index); + result_oop = cpc_entry->f1(); + if (result_oop != NULL) { + return result_oop; // that was easy... + } + index = cpc_entry->constant_pool_index(); + } + + int tag_value = this_oop->tag_at(index).value(); + switch (tag_value) { + + case JVM_CONSTANT_UnresolvedClass: + case JVM_CONSTANT_UnresolvedClassInError: + case JVM_CONSTANT_Class: + { + klassOop resolved = klass_at_impl(this_oop, index, CHECK_NULL); + // ldc wants the java mirror. + result_oop = resolved->klass_part()->java_mirror(); + break; + } + + case JVM_CONSTANT_String: + case JVM_CONSTANT_UnresolvedString: + if (this_oop->is_pseudo_string_at(index)) { + result_oop = this_oop->pseudo_string_at(index); + break; + } + result_oop = string_at_impl(this_oop, index, CHECK_NULL); + break; + + case JVM_CONSTANT_Object: + result_oop = this_oop->object_at(index); + break; + + case JVM_CONSTANT_MethodHandle: + { + int ref_kind = this_oop->method_handle_ref_kind_at(index); + int callee_index = this_oop->method_handle_klass_index_at(index); + symbolHandle name(THREAD, this_oop->method_handle_name_ref_at(index)); + symbolHandle signature(THREAD, this_oop->method_handle_signature_ref_at(index)); + if (PrintMiscellaneous) + tty->print_cr("resolve JVM_CONSTANT_MethodHandle:%d [%d/%d/%d] %s.%s", + ref_kind, index, this_oop->method_handle_index_at(index), + callee_index, name->as_C_string(), signature->as_C_string()); + KlassHandle callee; + { klassOop k = klass_at_impl(this_oop, callee_index, CHECK_NULL); + callee = KlassHandle(THREAD, k); + } + KlassHandle klass(THREAD, this_oop->pool_holder()); + Handle value = SystemDictionary::link_method_handle_constant(klass, ref_kind, + callee, name, signature, + CHECK_NULL); + result_oop = value(); + // FIXME: Uniquify errors, using SystemDictionary::find_resolution_error. + break; + } + + case JVM_CONSTANT_MethodType: + { + symbolHandle signature(THREAD, this_oop->method_type_signature_at(index)); + if (PrintMiscellaneous) + tty->print_cr("resolve JVM_CONSTANT_MethodType [%d/%d] %s", + index, this_oop->method_type_index_at(index), + signature->as_C_string()); + KlassHandle klass(THREAD, this_oop->pool_holder()); + bool ignore_is_on_bcp = false; + Handle value = SystemDictionary::find_method_handle_type(signature, + klass, + ignore_is_on_bcp, + CHECK_NULL); + result_oop = value(); + // FIXME: Uniquify errors, using SystemDictionary::find_resolution_error. + break; + } + + /* maybe some day + case JVM_CONSTANT_Integer: + case JVM_CONSTANT_Float: + case JVM_CONSTANT_Long: + case JVM_CONSTANT_Double: + result_oop = java_lang_boxing_object::create(...); + break; + */ + + default: + DEBUG_ONLY( tty->print_cr("*** %p: tag at CP[%d/%d] = %d", + this_oop(), index, cache_index, tag_value) ); + assert(false, "unexpected constant tag"); + break; + } + + if (cache_index >= 0) { + // Cache the oop here also. + Handle result(THREAD, result_oop); + result_oop = NULL; // safety + ObjectLocker ol(this_oop, THREAD); + ConstantPoolCacheEntry* cpc_entry = this_oop->cache()->entry_at(cache_index); + oop result_oop2 = cpc_entry->f1(); + if (result_oop2 != NULL) { + // Race condition: May already be filled in while we were trying to lock. + return result_oop2; + } + cpc_entry->set_f1(result()); + return result(); + } else { + return result_oop; + } +} + oop constantPoolOopDesc::string_at_impl(constantPoolHandle this_oop, int which, TRAPS) { oop entry = *(this_oop->obj_at_addr(which)); if (entry->is_symbol()) { @@ -690,6 +808,28 @@ } } break; + case JVM_CONSTANT_MethodType: + { + int k1 = method_type_index_at(index1); + int k2 = cp2->method_type_index_at(index2); + if (k1 == k2) { + return true; + } + } break; + + case JVM_CONSTANT_MethodHandle: + { + int k1 = method_handle_ref_kind_at(index1); + int k2 = cp2->method_handle_ref_kind_at(index2); + if (k1 == k2) { + int i1 = method_handle_index_at(index1); + int i2 = cp2->method_handle_index_at(index2); + if (i1 == i2) { + return true; + } + } + } break; + case JVM_CONSTANT_UnresolvedString: { symbolOop s1 = unresolved_string_at(index1); @@ -863,6 +1003,19 @@ to_cp->symbol_at_put(to_i, s); } break; + case JVM_CONSTANT_MethodType: + { + jint k = method_type_index_at(from_i); + to_cp->method_type_index_at_put(to_i, k); + } break; + + case JVM_CONSTANT_MethodHandle: + { + int k1 = method_handle_ref_kind_at(from_i); + int k2 = method_handle_index_at(from_i); + to_cp->method_handle_index_at_put(to_i, k1, k2); + } break; + // Invalid is used as the tag for the second constant pool entry // occupied by JVM_CONSTANT_Double or JVM_CONSTANT_Long. It should // not be seen by itself. @@ -1066,8 +1219,12 @@ case JVM_CONSTANT_UnresolvedClassInError: case JVM_CONSTANT_StringIndex: case JVM_CONSTANT_UnresolvedString: + case JVM_CONSTANT_MethodType: return 3; + case JVM_CONSTANT_MethodHandle: + return 4; //tag, ref_kind, ref_index + case JVM_CONSTANT_Integer: case JVM_CONSTANT_Float: case JVM_CONSTANT_Fieldref: @@ -1271,6 +1428,22 @@ DBG(printf("JVM_CONSTANT_StringIndex: %hd", idx1)); break; } + case JVM_CONSTANT_MethodHandle: { + *bytes = JVM_CONSTANT_MethodHandle; + int kind = method_handle_ref_kind_at(idx); + idx1 = method_handle_index_at(idx); + *(bytes+1) = (unsigned char) kind; + Bytes::put_Java_u2((address) (bytes+2), idx1); + DBG(printf("JVM_CONSTANT_MethodHandle: %d %hd", kind, idx1)); + break; + } + case JVM_CONSTANT_MethodType: { + *bytes = JVM_CONSTANT_MethodType; + idx1 = method_type_index_at(idx); + Bytes::put_Java_u2((address) (bytes+1), idx1); + DBG(printf("JVM_CONSTANT_MethodType: %hd", idx1)); + break; + } } DBG(printf("\n")); bytes += ent_size;