Mercurial > hg > truffle
diff src/share/vm/interpreter/rewriter.cpp @ 7066:7d815d842ee0
Merge.
author | Christian Haeubl <haeubl@ssw.jku.at> |
---|---|
date | Fri, 23 Nov 2012 11:50:27 +0100 |
parents | e522a00b91aa |
children | 5d0bb7d52783 |
line wrap: on
line diff
--- a/src/share/vm/interpreter/rewriter.cpp Fri Nov 23 11:40:17 2012 +0100 +++ b/src/share/vm/interpreter/rewriter.cpp Fri Nov 23 11:50:27 2012 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,7 @@ #include "interpreter/interpreter.hpp" #include "interpreter/rewriter.hpp" #include "memory/gcLocker.hpp" +#include "memory/metadataFactory.hpp" #include "memory/oopFactory.hpp" #include "memory/resourceArea.hpp" #include "oops/generateOopMap.hpp" @@ -41,7 +42,7 @@ // Marks entries in CP which require additional processing. void Rewriter::compute_index_maps() { const int length = _pool->length(); - init_cp_map(length); + init_maps(length); bool saw_mh_symbol = false; for (int i = 0; i < length; i++) { int tag = _pool->tag_at(i).value(); @@ -49,10 +50,13 @@ case JVM_CONSTANT_InterfaceMethodref: case JVM_CONSTANT_Fieldref : // fall through case JVM_CONSTANT_Methodref : // fall through + add_cp_cache_entry(i); + break; + case JVM_CONSTANT_String: + case JVM_CONSTANT_Object: case JVM_CONSTANT_MethodHandle : // fall through case JVM_CONSTANT_MethodType : // fall through - case JVM_CONSTANT_InvokeDynamic : // fall through - add_cp_cache_entry(i); + add_resolved_references_entry(i); break; case JVM_CONSTANT_Utf8: if (_pool->symbol_at(i) == vmSymbols::java_lang_invoke_MethodHandle()) @@ -61,6 +65,9 @@ } } + // Record limits of resolved reference map for constant pool cache indices + record_map_limits(); + guarantee((int)_cp_cache_map.length()-1 <= (int)((u2)-1), "all cp cache indexes fit in a u2"); @@ -73,7 +80,7 @@ int len = _methods->length(); for (int i = len-1; i >= 0; i--) { - methodOop method = (methodOop)_methods->obj_at(i); + Method* method = _methods->at(i); scan_method(method, true); } } @@ -81,10 +88,17 @@ // Creates a constant pool cache given a CPC map void Rewriter::make_constant_pool_cache(TRAPS) { const int length = _cp_cache_map.length(); - constantPoolCacheOop cache = - oopFactory::new_constantPoolCache(length, CHECK); + ClassLoaderData* loader_data = _pool->pool_holder()->class_loader_data(); + ConstantPoolCache* cache = + ConstantPoolCache::allocate(loader_data, length, CHECK); + + // initialize object cache in constant pool + _pool->initialize_resolved_references(loader_data, _resolved_references_map, + _resolved_reference_limit, + CHECK); + No_Safepoint_Verifier nsv; - cache->initialize(_cp_cache_map); + cache->initialize(_cp_cache_map, _invokedynamic_references_map); _pool->set_cache(cache); cache->set_constant_pool(_pool()); } @@ -142,19 +156,19 @@ int cache_index = cp_entry_to_cp_cache(cp_index); Bytes::put_native_u2(p, cache_index); if (!_method_handle_invokers.is_empty()) - maybe_rewrite_invokehandle(p - 1, cp_index, reverse); + maybe_rewrite_invokehandle(p - 1, cp_index, cache_index, reverse); } else { int cache_index = Bytes::get_native_u2(p); int pool_index = cp_cache_entry_pool_index(cache_index); Bytes::put_Java_u2(p, pool_index); if (!_method_handle_invokers.is_empty()) - maybe_rewrite_invokehandle(p - 1, pool_index, reverse); + maybe_rewrite_invokehandle(p - 1, pool_index, cache_index, reverse); } } // Adjust the invocation bytecode for a signature-polymorphic method (MethodHandle.invoke, etc.) -void Rewriter::maybe_rewrite_invokehandle(address opc, int cp_index, bool reverse) { +void Rewriter::maybe_rewrite_invokehandle(address opc, int cp_index, int cache_index, bool reverse) { if (!reverse) { if ((*opc) == (u1)Bytecodes::_invokevirtual || // allow invokespecial as an alias, although it would be very odd: @@ -167,10 +181,13 @@ if (status == 0) { if (_pool->klass_ref_at_noresolve(cp_index) == vmSymbols::java_lang_invoke_MethodHandle() && MethodHandles::is_signature_polymorphic_name(SystemDictionary::MethodHandle_klass(), - _pool->name_ref_at(cp_index))) + _pool->name_ref_at(cp_index))) { + // we may need a resolved_refs entry for the appendix + add_invokedynamic_resolved_references_entries(cp_index, cache_index); status = +1; - else + } else { status = -1; + } _method_handle_invokers[cp_index] = status; } // We use a special internal bytecode for such methods (if non-static). @@ -197,9 +214,8 @@ assert(p[-1] == Bytecodes::_invokedynamic, "not invokedynamic bytecode"); if (!reverse) { int cp_index = Bytes::get_Java_u2(p); - int cpc = maybe_add_cp_cache_entry(cp_index); // add lazily - int cpc2 = add_secondary_cp_cache_entry(cpc); - + int cache_index = add_invokedynamic_cp_cache_entry(cp_index); + add_invokedynamic_resolved_references_entries(cp_index, cache_index); // Replace the trailing four bytes with a CPC index for the dynamic // call site. Unlike other CPC entries, there is one per bytecode, // not just one per distinct CP entry. In other words, the @@ -208,17 +224,17 @@ // all these entries. That is the main reason invokedynamic // must have a five-byte instruction format. (Of course, other JVM // implementations can use the bytes for other purposes.) - Bytes::put_native_u4(p, constantPoolCacheOopDesc::encode_secondary_index(cpc2)); + Bytes::put_native_u4(p, ConstantPool::encode_invokedynamic_index(cache_index)); // Note: We use native_u4 format exclusively for 4-byte indexes. } else { - int cache_index = constantPoolCacheOopDesc::decode_secondary_index( + // callsite index + int cache_index = ConstantPool::decode_invokedynamic_index( Bytes::get_native_u4(p)); - int secondary_index = cp_cache_secondary_entry_main_index(cache_index); - int pool_index = cp_cache_entry_pool_index(secondary_index); - assert(_pool->tag_at(pool_index).is_invoke_dynamic(), "wrong index"); + int cp_index = cp_cache_entry_pool_index(cache_index); + assert(_pool->tag_at(cp_index).is_invoke_dynamic(), "wrong index"); // zero out 4 bytes Bytes::put_Java_u4(p, 0); - Bytes::put_Java_u2(p, pool_index); + Bytes::put_Java_u2(p, cp_index); } } @@ -231,16 +247,16 @@ address p = bcp + offset; int cp_index = is_wide ? Bytes::get_Java_u2(p) : (u1)(*p); constantTag tag = _pool->tag_at(cp_index).value(); - if (tag.is_method_handle() || tag.is_method_type()) { - int cache_index = cp_entry_to_cp_cache(cp_index); + if (tag.is_method_handle() || tag.is_method_type() || tag.is_string() || tag.is_object()) { + int ref_index = cp_entry_to_resolved_references(cp_index); if (is_wide) { (*bcp) = Bytecodes::_fast_aldc_w; - assert(cache_index == (u2)cache_index, "index overflow"); - Bytes::put_native_u2(p, cache_index); + assert(ref_index == (u2)ref_index, "index overflow"); + Bytes::put_native_u2(p, ref_index); } else { (*bcp) = Bytecodes::_fast_aldc; - assert(cache_index == (u1)cache_index, "index overflow"); - (*p) = (u1)cache_index; + assert(ref_index == (u1)ref_index, "index overflow"); + (*p) = (u1)ref_index; } } } else { @@ -248,8 +264,8 @@ (is_wide ? Bytecodes::_fast_aldc_w : Bytecodes::_fast_aldc); if ((*bcp) == rewritten_bc) { address p = bcp + offset; - int cache_index = is_wide ? Bytes::get_native_u2(p) : (u1)(*p); - int pool_index = cp_cache_entry_pool_index(cache_index); + int ref_index = is_wide ? Bytes::get_native_u2(p) : (u1)(*p); + int pool_index = resolved_references_entry_to_pool_index(ref_index); if (is_wide) { (*bcp) = Bytecodes::_ldc_w; assert(pool_index == (u2)pool_index, "index overflow"); @@ -265,14 +281,14 @@ // Rewrites a method given the index_map information -void Rewriter::scan_method(methodOop method, bool reverse) { +void Rewriter::scan_method(Method* method, bool reverse) { int nof_jsrs = 0; bool has_monitor_bytecodes = false; { // We cannot tolerate a GC in this block, because we've - // cached the bytecodes in 'code_base'. If the methodOop + // cached the bytecodes in 'code_base'. If the Method* // moves, the bytecodes will also move. No_Safepoint_Verifier nsv; Bytecodes::Code c; @@ -377,16 +393,6 @@ ResolveOopMapConflicts romc(method); methodHandle original_method = method; method = romc.do_potential_rewrite(CHECK_(methodHandle())); - if (method() != original_method()) { - // Insert invalid bytecode into original methodOop and set - // interpreter entrypoint, so that a executing this method - // will manifest itself in an easy recognizable form. - address bcp = original_method->bcp_from(0); - *bcp = (u1)Bytecodes::_shouldnotreachhere; - int kind = Interpreter::method_kind(original_method); - original_method->set_interpreter_kind(kind); - } - // Update monitor matching info. if (romc.monitor_safe()) { method->set_guaranteed_monitor_matching(); @@ -402,28 +408,28 @@ } -void Rewriter::rewrite(instanceKlassHandle klass, constantPoolHandle cpool, objArrayHandle methods, TRAPS) { +void Rewriter::rewrite(instanceKlassHandle klass, constantPoolHandle cpool, Array<Method*>* methods, TRAPS) { ResourceMark rm(THREAD); Rewriter rw(klass, cpool, methods, CHECK); // (That's all, folks.) } -Rewriter::Rewriter(instanceKlassHandle klass, constantPoolHandle cpool, objArrayHandle methods, TRAPS) +Rewriter::Rewriter(instanceKlassHandle klass, constantPoolHandle cpool, Array<Method*>* methods, TRAPS) : _klass(klass), _pool(cpool), _methods(methods) { assert(_pool->cache() == NULL, "constant pool cache must not be set yet"); - // determine index maps for methodOop rewriting + // determine index maps for Method* rewriting compute_index_maps(); if (RegisterFinalizersAtInit && _klass->name() == vmSymbols::java_lang_Object()) { bool did_rewrite = false; int i = _methods->length(); while (i-- > 0) { - methodOop method = (methodOop)_methods->obj_at(i); + Method* method = _methods->at(i); if (method->intrinsic_id() == vmIntrinsics::_Object_init) { // rewrite the return bytecodes of Object.<init> to register the // object for finalization if needed. @@ -440,7 +446,7 @@ int len = _methods->length(); for (int i = len-1; i >= 0; i--) { - methodOop method = (methodOop)_methods->obj_at(i); + Method* method = _methods->at(i); scan_method(method); } @@ -461,20 +467,19 @@ // Link and check jvmti dependencies while we're iterating over the methods. // JSR292 code calls with a different set of methods, so two entry points. void Rewriter::relocate_and_link(instanceKlassHandle this_oop, TRAPS) { - objArrayHandle methods(THREAD, this_oop->methods()); - relocate_and_link(this_oop, methods, THREAD); + relocate_and_link(this_oop, this_oop->methods(), THREAD); } void Rewriter::relocate_and_link(instanceKlassHandle this_oop, - objArrayHandle methods, TRAPS) { + Array<Method*>* methods, TRAPS) { int len = methods->length(); for (int i = len-1; i >= 0; i--) { - methodHandle m(THREAD, (methodOop)methods->obj_at(i)); + methodHandle m(THREAD, methods->at(i)); if (m->has_jsrs()) { m = rewrite_jsrs(m, CHECK); // Method might have gotten rewritten. - methods->obj_at_put(i, m()); + methods->at_put(i, m()); } // Set up method entry points for compiler and interpreter . @@ -487,7 +492,7 @@ for (int j = i; j >= 0 && j >= i-4; j--) { if ((++nmc % 1000) == 0) tty->print_cr("Have run MethodComparator %d times...", nmc); bool z = MethodComparator::methods_EMCP(m(), - (methodOop)methods->obj_at(j)); + methods->at(j)); if (j == i && !z) { tty->print("MethodComparator FAIL: "); m->print(); m->print_codes(); assert(z, "method must compare equal to itself");