Mercurial > hg > graal-jvmci-8
diff src/share/vm/interpreter/bytecodeTracer.cpp @ 6725:da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author | coleenp |
---|---|
date | Sat, 01 Sep 2012 13:25:18 -0400 |
parents | b20d64f83668 |
children | f16e75e0cf11 |
line wrap: on
line diff
--- a/src/share/vm/interpreter/bytecodeTracer.cpp Fri Aug 31 16:39:35 2012 -0700 +++ b/src/share/vm/interpreter/bytecodeTracer.cpp Sat Sep 01 13:25:18 2012 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -29,8 +29,8 @@ #include "interpreter/interpreter.hpp" #include "interpreter/interpreterRuntime.hpp" #include "memory/resourceArea.hpp" -#include "oops/methodDataOop.hpp" -#include "oops/methodOop.hpp" +#include "oops/methodData.hpp" +#include "oops/method.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/timer.hpp" @@ -46,7 +46,7 @@ // between critical sections. Use only pointer-comparison // operations on the pointer, except within a critical section. // (Also, ensure that occasional false positives are benign.) - methodOop _current_method; + Method* _current_method; bool _is_wide; Bytecodes::Code _code; address _next_pc; // current decoding position @@ -58,16 +58,19 @@ int get_index_u1() { return *(address)_next_pc++; } int get_index_u2() { int i=Bytes::get_Java_u2(_next_pc); _next_pc+=2; return i; } - int get_index_u1_cpcache() { return get_index_u1() + constantPoolOopDesc::CPCACHE_INDEX_TAG; } - int get_index_u2_cpcache() { int i=Bytes::get_native_u2(_next_pc); _next_pc+=2; return i + constantPoolOopDesc::CPCACHE_INDEX_TAG; } + int get_index_u1_cpcache() { return get_index_u1() + ConstantPool::CPCACHE_INDEX_TAG; } + int get_index_u2_cpcache() { int i=Bytes::get_native_u2(_next_pc); _next_pc+=2; return i + ConstantPool::CPCACHE_INDEX_TAG; } int get_index_u4() { int i=Bytes::get_native_u4(_next_pc); _next_pc+=4; return i; } int get_index_special() { return (is_wide()) ? get_index_u2() : get_index_u1(); } - methodOop method() { return _current_method; } + Method* method() { return _current_method; } bool is_wide() { return _is_wide; } Bytecodes::Code raw_code() { return Bytecodes::Code(_code); } bool check_index(int i, int& cp_index, outputStream* st = tty); + bool check_cp_cache_index(int i, int& cp_index, outputStream* st = tty); + bool check_obj_index(int i, int& cp_index, outputStream* st = tty); + bool check_invokedynamic_index(int i, int& cp_index, outputStream* st = tty); void print_constant(int i, outputStream* st = tty); void print_field_or_method(int i, outputStream* st = tty); void print_field_or_method(int orig_i, int i, outputStream* st = tty); @@ -122,7 +125,7 @@ _code = Bytecodes::_illegal; } - // Used for methodOop::print_codes(). The input bcp comes from + // Used for Method*::print_codes(). The input bcp comes from // BytecodeStream, which will skip wide bytecodes. void trace(methodHandle method, address bcp, outputStream* st) { _current_method = method(); @@ -152,7 +155,7 @@ // %%% This set_closure thing seems overly general, given that // nobody uses it. Also, if BytecodePrinter weren't hidden -// then methodOop could use instances of it directly and it +// then Method* could use instances of it directly and it // would be easier to remove races on _current_method and bcp. // Since this is not product functionality, we can defer cleanup. @@ -170,7 +173,7 @@ // The ttyLocker also prevents races between two threads // trying to use the single instance of BytecodePrinter. // Using the ttyLocker prevents the system from coming to - // a safepoint within this code, which is sensitive to methodOop + // a safepoint within this code, which is sensitive to Method* // movement. // // There used to be a leaf mutex here, but the ttyLocker will @@ -217,56 +220,59 @@ } bool BytecodePrinter::check_index(int i, int& cp_index, outputStream* st) { - constantPoolOop constants = method()->constants(); + ConstantPool* constants = method()->constants(); + int ilimit = constants->length(); + Bytecodes::Code code = raw_code(); + + ConstantPoolCache* cache = NULL; + if (Bytecodes::uses_cp_cache(code)) { + bool okay = true; + switch (code) { + case Bytecodes::_fast_aldc: + case Bytecodes::_fast_aldc_w: + okay = check_obj_index(i, cp_index, st); + break; + case Bytecodes::_invokedynamic: + okay = check_invokedynamic_index(i, cp_index, st); + break; + default: + okay = check_cp_cache_index(i, cp_index, st); + break; + } + if (!okay) return false; + } + + + // check cp index + if (cp_index >= 0 && cp_index < ilimit) { + if (WizardMode) st->print(" cp[%d]", cp_index); + return true; + } + + st->print_cr(" CP[%d] not in CP", cp_index); + return false; +} + +bool BytecodePrinter::check_cp_cache_index(int i, int& cp_index, outputStream* st) { + ConstantPool* constants = method()->constants(); int ilimit = constants->length(), climit = 0; Bytecodes::Code code = raw_code(); - constantPoolCacheOop cache = NULL; - if (Bytecodes::uses_cp_cache(code)) { - cache = constants->cache(); - if (cache != NULL) { - //climit = cache->length(); // %%% private! - size_t size = cache->size() * HeapWordSize; - size -= sizeof(constantPoolCacheOopDesc); - size /= sizeof(ConstantPoolCacheEntry); - climit = (int) size; - } - } - - if (cache != NULL && constantPoolCacheOopDesc::is_secondary_index(i)) { - i = constantPoolCacheOopDesc::decode_secondary_index(i); - st->print(" secondary cache[%d] of", i); - if (i >= 0 && i < climit) { - if (!cache->entry_at(i)->is_secondary_entry()) { - st->print_cr(" not secondary entry?", i); - return false; - } - i = cache->entry_at(i)->main_entry_index() + constantPoolOopDesc::CPCACHE_INDEX_TAG; - goto check_cache_index; - } else { - st->print_cr(" not in cache[*]?", i); - return false; - } - } - - if (cache != NULL) { - goto check_cache_index; - } - - check_cp_index: - if (i >= 0 && i < ilimit) { - if (WizardMode) st->print(" cp[%d]", i); + ConstantPoolCache* cache = constants->cache(); + // If rewriter hasn't run, the index is the cp_index + if (cache == NULL) { cp_index = i; return true; } + //climit = cache->length(); // %%% private! + size_t size = cache->size() * HeapWordSize; + size -= sizeof(ConstantPoolCache); + size /= sizeof(ConstantPoolCacheEntry); + climit = (int) size; - st->print_cr(" CP[%d] not in CP", i); - return false; - - check_cache_index: #ifdef ASSERT { - const int CPCACHE_INDEX_TAG = constantPoolOopDesc::CPCACHE_INDEX_TAG; + const int CPCACHE_INDEX_TAG = ConstantPool::CPCACHE_INDEX_TAG; if (i >= CPCACHE_INDEX_TAG && i < climit + CPCACHE_INDEX_TAG) { i -= CPCACHE_INDEX_TAG; } else { @@ -276,22 +282,42 @@ } #endif //ASSERT if (i >= 0 && i < climit) { - if (cache->entry_at(i)->is_secondary_entry()) { - st->print_cr(" secondary entry?"); + cp_index = cache->entry_at(i)->constant_pool_index(); + } else { + st->print_cr(" not in CP[*]?", i); return false; } - i = cache->entry_at(i)->constant_pool_index(); - goto check_cp_index; + return true; } - st->print_cr(" not in CP[*]?", i); + + +bool BytecodePrinter::check_obj_index(int i, int& cp_index, outputStream* st) { + ConstantPool* constants = method()->constants(); + i -= ConstantPool::CPCACHE_INDEX_TAG; + + if (i >= 0 && i < constants->resolved_references()->length()) { + cp_index = constants->object_to_cp_index(i); + return true; + } else { + st->print_cr(" not in OBJ[*]?", i); return false; } +} + + +bool BytecodePrinter::check_invokedynamic_index(int i, int& cp_index, outputStream* st) { + ConstantPool* constants = method()->constants(); + assert(ConstantPool::is_invokedynamic_index(i), "not secondary index?"); + i = ConstantPool::decode_invokedynamic_index(i) + ConstantPool::CPCACHE_INDEX_TAG; + + return check_cp_cache_index(i, cp_index, st); +} void BytecodePrinter::print_constant(int i, outputStream* st) { int orig_i = i; if (!check_index(orig_i, i, st)) return; - constantPoolOop constants = method()->constants(); + ConstantPool* constants = method()->constants(); constantTag tag = constants->tag_at(i); if (tag.is_int()) { @@ -303,13 +329,10 @@ } else if (tag.is_double()) { st->print_cr(" %f", constants->double_at(i)); } else if (tag.is_string()) { - oop string = constants->pseudo_string_at(i); - print_oop(string, st); - } else if (tag.is_unresolved_string()) { const char* string = constants->string_at_noresolve(i); st->print_cr(" %s", string); } else if (tag.is_klass()) { - st->print_cr(" %s", constants->resolved_klass_at(i)->klass_part()->external_name()); + st->print_cr(" %s", constants->resolved_klass_at(i)->external_name()); } else if (tag.is_unresolved_klass()) { st->print_cr(" <unresolved klass at %d>", i); } else if (tag.is_object()) { @@ -336,7 +359,7 @@ } void BytecodePrinter::print_field_or_method(int orig_i, int i, outputStream* st) { - constantPoolOop constants = method()->constants(); + ConstantPool* constants = method()->constants(); constantTag tag = constants->tag_at(i); bool has_klass = true; @@ -438,7 +461,7 @@ break; case Bytecodes::_anewarray: { int klass_index = get_index_u2(); - constantPoolOop constants = method()->constants(); + ConstantPool* constants = method()->constants(); Symbol* name = constants->klass_name_at(klass_index); st->print_cr(" %s ", name->as_C_string()); } @@ -446,7 +469,7 @@ case Bytecodes::_multianewarray: { int klass_index = get_index_u2(); int nof_dims = get_index_u1(); - constantPoolOop constants = method()->constants(); + ConstantPool* constants = method()->constants(); Symbol* name = constants->klass_name_at(klass_index); st->print_cr(" %s %d", name->as_C_string(), nof_dims); } @@ -552,7 +575,7 @@ case Bytecodes::_checkcast: case Bytecodes::_instanceof: { int i = get_index_u2(); - constantPoolOop constants = method()->constants(); + ConstantPool* constants = method()->constants(); Symbol* name = constants->klass_name_at(i); st->print_cr(" %d <%s>", i, name->as_C_string()); } @@ -570,7 +593,7 @@ void BytecodePrinter::bytecode_epilog(int bci, outputStream* st) { - methodDataOop mdo = method()->method_data(); + MethodData* mdo = method()->method_data(); if (mdo != NULL) { ProfileData* data = mdo->bci_to_data(bci); if (data != NULL) {