# HG changeset patch # User ysr # Date 1263714710 28800 # Node ID c4d722788ed65bd3199b6b3bf50b2a596cb8fd6a # Parent 1fc01a2425ce796606211f758fcaad5413eb179a# Parent 09646c4656cabf1707f8038eda755908099388db Merge diff -r 09646c4656ca -r c4d722788ed6 src/cpu/sparc/vm/sparc.ad --- a/src/cpu/sparc/vm/sparc.ad Wed Jan 13 15:45:47 2010 -0800 +++ b/src/cpu/sparc/vm/sparc.ad Sat Jan 16 23:51:50 2010 -0800 @@ -1,5 +1,5 @@ // -// Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved. +// Copyright 1998-2010 Sun Microsystems, Inc. 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 @@ -6668,7 +6668,7 @@ ins_pipe(ialu_imm); %} -instruct cmovII_U_reg(cmpOpU cmp, flagsRegU icc, iRegI dst, iRegI src) %{ +instruct cmovIIu_reg(cmpOpU cmp, flagsRegU icc, iRegI dst, iRegI src) %{ match(Set dst (CMoveI (Binary cmp icc) (Binary dst src))); ins_cost(150); size(4); @@ -6677,7 +6677,7 @@ ins_pipe(ialu_reg); %} -instruct cmovII_U_imm(cmpOpU cmp, flagsRegU icc, iRegI dst, immI11 src) %{ +instruct cmovIIu_imm(cmpOpU cmp, flagsRegU icc, iRegI dst, immI11 src) %{ match(Set dst (CMoveI (Binary cmp icc) (Binary dst src))); ins_cost(140); size(4); @@ -6723,6 +6723,16 @@ ins_pipe(ialu_reg); %} +// This instruction also works with CmpN so we don't need cmovNN_reg. +instruct cmovNIu_reg(cmpOpU cmp, flagsRegU icc, iRegN dst, iRegN src) %{ + match(Set dst (CMoveN (Binary cmp icc) (Binary dst src))); + ins_cost(150); + size(4); + format %{ "MOV$cmp $icc,$src,$dst" %} + ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::icc)) ); + ins_pipe(ialu_reg); +%} + instruct cmovNF_reg(cmpOpF cmp, flagsRegF fcc, iRegN dst, iRegN src) %{ match(Set dst (CMoveN (Binary cmp fcc) (Binary dst src))); ins_cost(150); @@ -6760,6 +6770,16 @@ ins_pipe(ialu_reg); %} +instruct cmovPIu_reg(cmpOpU cmp, flagsRegU icc, iRegP dst, iRegP src) %{ + match(Set dst (CMoveP (Binary cmp icc) (Binary dst src))); + ins_cost(150); + + size(4); + format %{ "MOV$cmp $icc,$src,$dst\t! ptr" %} + ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::icc)) ); + ins_pipe(ialu_reg); +%} + instruct cmovPI_imm(cmpOp cmp, flagsReg icc, iRegP dst, immP0 src) %{ match(Set dst (CMoveP (Binary cmp icc) (Binary dst src))); ins_cost(140); @@ -6770,6 +6790,16 @@ ins_pipe(ialu_imm); %} +instruct cmovPIu_imm(cmpOpU cmp, flagsRegU icc, iRegP dst, immP0 src) %{ + match(Set dst (CMoveP (Binary cmp icc) (Binary dst src))); + ins_cost(140); + + size(4); + format %{ "MOV$cmp $icc,$src,$dst\t! ptr" %} + ins_encode( enc_cmov_imm(cmp,dst,src, (Assembler::icc)) ); + ins_pipe(ialu_imm); +%} + instruct cmovPF_reg(cmpOpF cmp, flagsRegF fcc, iRegP dst, iRegP src) %{ match(Set dst (CMoveP (Binary cmp fcc) (Binary dst src))); ins_cost(150); @@ -6809,6 +6839,17 @@ ins_pipe(int_conditional_float_move); %} +instruct cmovFIu_reg(cmpOpU cmp, flagsRegU icc, regF dst, regF src) %{ + match(Set dst (CMoveF (Binary cmp icc) (Binary dst src))); + ins_cost(150); + + size(4); + format %{ "FMOVS$cmp $icc,$src,$dst" %} + opcode(0x101); + ins_encode( enc_cmovf_reg(cmp,dst,src, (Assembler::icc)) ); + ins_pipe(int_conditional_float_move); +%} + // Conditional move, instruct cmovFF_reg(cmpOpF cmp, flagsRegF fcc, regF dst, regF src) %{ match(Set dst (CMoveF (Binary cmp fcc) (Binary dst src))); @@ -6842,6 +6883,17 @@ ins_pipe(int_conditional_double_move); %} +instruct cmovDIu_reg(cmpOpU cmp, flagsRegU icc, regD dst, regD src) %{ + match(Set dst (CMoveD (Binary cmp icc) (Binary dst src))); + ins_cost(150); + + size(4); + format %{ "FMOVD$cmp $icc,$src,$dst" %} + opcode(0x102); + ins_encode( enc_cmovf_reg(cmp,dst,src, (Assembler::icc)) ); + ins_pipe(int_conditional_double_move); +%} + // Conditional move, instruct cmovDF_reg(cmpOpF cmp, flagsRegF fcc, regD dst, regD src) %{ match(Set dst (CMoveD (Binary cmp fcc) (Binary dst src))); @@ -6881,6 +6933,17 @@ %} +instruct cmovLIu_reg(cmpOpU cmp, flagsRegU icc, iRegL dst, iRegL src) %{ + match(Set dst (CMoveL (Binary cmp icc) (Binary dst src))); + ins_cost(150); + + size(4); + format %{ "MOV$cmp $icc,$src,$dst\t! long" %} + ins_encode( enc_cmov_reg(cmp,dst,src, (Assembler::icc)) ); + ins_pipe(ialu_reg); +%} + + instruct cmovLF_reg(cmpOpF cmp, flagsRegF fcc, iRegL dst, iRegL src) %{ match(Set dst (CMoveL (Binary cmp fcc) (Binary dst src))); ins_cost(150); diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/ci/ciMethod.cpp --- a/src/share/vm/ci/ciMethod.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/ci/ciMethod.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -1,5 +1,5 @@ /* - * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2010 Sun Microsystems, Inc. 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 @@ -700,6 +700,12 @@ return flag; } +bool ciMethod::is_method_handle_adapter() const { + check_is_loaded(); + VM_ENTRY_MARK; + return get_methodOop()->is_method_handle_adapter(); +} + ciInstance* ciMethod::method_handle_type() { check_is_loaded(); VM_ENTRY_MARK; diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/ci/ciMethod.hpp --- a/src/share/vm/ci/ciMethod.hpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/ci/ciMethod.hpp Sat Jan 16 23:51:50 2010 -0800 @@ -1,5 +1,5 @@ /* - * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2010 Sun Microsystems, Inc. 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 @@ -215,7 +215,10 @@ bool check_call(int refinfo_index, bool is_static) const; void build_method_data(); // make sure it exists in the VM also int scale_count(int count, float prof_factor = 1.); // make MDO count commensurate with IIC - bool is_method_handle_invoke() const; + + // JSR 292 support + bool is_method_handle_invoke() const; + bool is_method_handle_adapter() const; ciInstance* method_handle_type(); // What kind of ciObject is this? diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/classfile/systemDictionary.hpp Sat Jan 16 23:51:50 2010 -0800 @@ -1,5 +1,5 @@ /* - * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2010 Sun Microsystems, Inc. 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 @@ -145,7 +145,7 @@ template(Linkage_klass, java_dyn_Linkage, Opt) \ template(CallSite_klass, java_dyn_CallSite, Opt) \ template(InvokeDynamic_klass, java_dyn_InvokeDynamic, Opt) \ - /* Note: MethodHandle must be first, and Dynamic last in group */ \ + /* Note: MethodHandle must be first, and InvokeDynamic last in group */ \ \ template(StringBuffer_klass, java_lang_StringBuffer, Pre) \ template(StringBuilder_klass, java_lang_StringBuilder, Pre) \ diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/code/codeBlob.hpp --- a/src/share/vm/code/codeBlob.hpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/code/codeBlob.hpp Sat Jan 16 23:51:50 2010 -0800 @@ -204,7 +204,8 @@ virtual void print_value_on(outputStream* st) const PRODUCT_RETURN; // Print the comment associated with offset on stream, if there is one - void print_block_comment(outputStream* stream, intptr_t offset) { + virtual void print_block_comment(outputStream* stream, address block_begin) { + intptr_t offset = (intptr_t)(block_begin - instructions_begin()); _comments.print_block_comment(stream, offset); } diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/code/nmethod.cpp --- a/src/share/vm/code/nmethod.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/code/nmethod.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -56,13 +56,13 @@ #endif bool nmethod::is_compiled_by_c1() const { + if (compiler() == NULL || method() == NULL) return false; // can happen during debug printing if (is_native_method()) return false; - assert(compiler() != NULL, "must be"); return compiler()->is_c1(); } bool nmethod::is_compiled_by_c2() const { + if (compiler() == NULL || method() == NULL) return false; // can happen during debug printing if (is_native_method()) return false; - assert(compiler() != NULL, "must be"); return compiler()->is_c2(); } @@ -2399,6 +2399,107 @@ return NULL; } +void nmethod::print_nmethod_labels(outputStream* stream, address block_begin) { + if (block_begin == entry_point()) stream->print_cr("[Entry Point]"); + if (block_begin == verified_entry_point()) stream->print_cr("[Verified Entry Point]"); + if (block_begin == exception_begin()) stream->print_cr("[Exception Handler]"); + if (block_begin == stub_begin()) stream->print_cr("[Stub Code]"); + if (block_begin == consts_begin()) stream->print_cr("[Constants]"); + if (block_begin == entry_point()) { + methodHandle m = method(); + if (m.not_null()) { + stream->print(" # "); + m->print_value_on(stream); + stream->cr(); + } + if (m.not_null() && !is_osr_method()) { + ResourceMark rm; + int sizeargs = m->size_of_parameters(); + BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, sizeargs); + VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair, sizeargs); + { + int sig_index = 0; + if (!m->is_static()) + sig_bt[sig_index++] = T_OBJECT; // 'this' + for (SignatureStream ss(m->signature()); !ss.at_return_type(); ss.next()) { + BasicType t = ss.type(); + sig_bt[sig_index++] = t; + if (type2size[t] == 2) { + sig_bt[sig_index++] = T_VOID; + } else { + assert(type2size[t] == 1, "size is 1 or 2"); + } + } + assert(sig_index == sizeargs, ""); + } + const char* spname = "sp"; // make arch-specific? + intptr_t out_preserve = SharedRuntime::java_calling_convention(sig_bt, regs, sizeargs, false); + int stack_slot_offset = this->frame_size() * wordSize; + int tab1 = 14, tab2 = 24; + int sig_index = 0; + int arg_index = (m->is_static() ? 0 : -1); + bool did_old_sp = false; + for (SignatureStream ss(m->signature()); !ss.at_return_type(); ) { + bool at_this = (arg_index == -1); + bool at_old_sp = false; + BasicType t = (at_this ? T_OBJECT : ss.type()); + assert(t == sig_bt[sig_index], "sigs in sync"); + if (at_this) + stream->print(" # this: "); + else + stream->print(" # parm%d: ", arg_index); + stream->move_to(tab1); + VMReg fst = regs[sig_index].first(); + VMReg snd = regs[sig_index].second(); + if (fst->is_reg()) { + stream->print("%s", fst->name()); + if (snd->is_valid()) { + stream->print(":%s", snd->name()); + } + } else if (fst->is_stack()) { + int offset = fst->reg2stack() * VMRegImpl::stack_slot_size + stack_slot_offset; + if (offset == stack_slot_offset) at_old_sp = true; + stream->print("[%s+0x%x]", spname, offset); + } else { + stream->print("reg%d:%d??", (int)(intptr_t)fst, (int)(intptr_t)snd); + } + stream->print(" "); + stream->move_to(tab2); + stream->print("= "); + if (at_this) { + m->method_holder()->print_value_on(stream); + } else { + bool did_name = false; + if (!at_this && ss.is_object()) { + symbolOop name = ss.as_symbol_or_null(); + if (name != NULL) { + name->print_value_on(stream); + did_name = true; + } + } + if (!did_name) + stream->print("%s", type2name(t)); + } + if (at_old_sp) { + stream->print(" (%s of caller)", spname); + did_old_sp = true; + } + stream->cr(); + sig_index += type2size[t]; + arg_index += 1; + if (!at_this) ss.next(); + } + if (!did_old_sp) { + stream->print(" # "); + stream->move_to(tab1); + stream->print("[%s+0x%x]", spname, stack_slot_offset); + stream->print(" (%s of caller)", spname); + stream->cr(); + } + } + } +} + void nmethod::print_code_comment_on(outputStream* st, int column, u_char* begin, u_char* end) { // First, find an oopmap in (begin, end]. // We use the odd half-closed interval so that oop maps and scope descs diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/code/nmethod.hpp --- a/src/share/vm/code/nmethod.hpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/code/nmethod.hpp Sat Jan 16 23:51:50 2010 -0800 @@ -576,6 +576,13 @@ void log_new_nmethod() const; void log_state_change() const; + // Prints block-level comments, including nmethod specific block labels: + virtual void print_block_comment(outputStream* stream, address block_begin) { + print_nmethod_labels(stream, block_begin); + CodeBlob::print_block_comment(stream, block_begin); + } + void print_nmethod_labels(outputStream* stream, address block_begin); + // Prints a comment for one native instruction (reloc info, pc desc) void print_code_comment_on(outputStream* st, int column, address begin, address end); static void print_statistics() PRODUCT_RETURN; diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/compiler/compilerOracle.cpp --- a/src/share/vm/compiler/compilerOracle.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/compiler/compilerOracle.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -392,18 +392,18 @@ }; static MethodMatcher::Mode check_mode(char name[], const char*& error_msg) { - if (strcmp(name, "*") == 0) return MethodMatcher::Any; - int match = MethodMatcher::Exact; - if (name[0] == '*') { + while (name[0] == '*') { match |= MethodMatcher::Suffix; strcpy(name, name + 1); } + if (strcmp(name, "*") == 0) return MethodMatcher::Any; + size_t len = strlen(name); - if (len > 0 && name[len - 1] == '*') { + while (len > 0 && name[len - 1] == '*') { match |= MethodMatcher::Prefix; - name[len - 1] = '\0'; + name[--len] = '\0'; } if (strstr(name, "*") != NULL) { @@ -610,6 +610,14 @@ CompilerOracle::parse_from_string(CompileCommand, CompilerOracle::parse_from_line); CompilerOracle::parse_from_string(CompileOnly, CompilerOracle::parse_compile_only); CompilerOracle::parse_from_file(); + if (lists[PrintCommand] != NULL) { + if (PrintAssembly) { + warning("CompileCommand and/or .hotspot_compiler file contains 'print' commands, but PrintAssembly is also enabled"); + } else if (FLAG_IS_DEFAULT(DebugNonSafepoints)) { + warning("printing of assembly code is enabled; turning on DebugNonSafepoints to gain additional output"); + DebugNonSafepoints = true; + } + } } diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/compiler/disassembler.cpp --- a/src/share/vm/compiler/disassembler.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/compiler/disassembler.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -151,8 +151,10 @@ outputStream* st = output(); if (_print_bytes && pc > pc0) print_insn_bytes(pc0, pc); - if (_nm != NULL) + if (_nm != NULL) { _nm->print_code_comment_on(st, COMMENT_COLUMN, pc0, pc); + // this calls reloc_string_for which calls oop::print_value_on + } // Output pc bucket ticks if we have any if (total_ticks() != 0) { @@ -273,8 +275,15 @@ oop obj; if (_nm != NULL && (obj = _nm->embeddedOop_at(cur_insn())) != NULL - && (address) obj == adr) { + && (address) obj == adr + && Universe::heap()->is_in(obj) + && Universe::heap()->is_in(obj->klass())) { + julong c = st->count(); obj->print_value_on(st); + if (st->count() == c) { + // No output. (Can happen in product builds.) + st->print("(a %s)", Klass::cast(obj->klass())->external_name()); + } return; } } @@ -286,17 +295,9 @@ void decode_env::print_insn_labels() { address p = cur_insn(); outputStream* st = output(); - nmethod* nm = _nm; - if (nm != NULL) { - if (p == nm->entry_point()) st->print_cr("[Entry Point]"); - if (p == nm->verified_entry_point()) st->print_cr("[Verified Entry Point]"); - if (p == nm->exception_begin()) st->print_cr("[Exception Handler]"); - if (p == nm->stub_begin()) st->print_cr("[Stub Code]"); - if (p == nm->consts_begin()) st->print_cr("[Constants]"); - } CodeBlob* cb = _code; if (cb != NULL) { - cb->print_block_comment(st, (intptr_t)(p - cb->instructions_begin())); + cb->print_block_comment(st, p); } if (_print_pc) { st->print(" " INTPTR_FORMAT ": ", (intptr_t) p); diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/includeDB_core --- a/src/share/vm/includeDB_core Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/includeDB_core Sat Jan 16 23:51:50 2010 -0800 @@ -1,5 +1,5 @@ // -// Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. +// Copyright 1997-2010 Sun Microsystems, Inc. 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 @@ -1525,6 +1525,7 @@ disassembler.cpp fprofiler.hpp disassembler.cpp handles.inline.hpp disassembler.cpp hpi.hpp +disassembler.cpp javaClasses.hpp disassembler.cpp stubCodeGenerator.hpp disassembler.cpp stubRoutines.hpp @@ -3503,6 +3504,7 @@ reflection.cpp javaClasses.hpp reflection.cpp jvm.h reflection.cpp linkResolver.hpp +reflection.cpp methodHandleWalk.hpp reflection.cpp objArrayKlass.hpp reflection.cpp objArrayOop.hpp reflection.cpp oopFactory.hpp diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/memory/genCollectedHeap.cpp --- a/src/share/vm/memory/genCollectedHeap.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/memory/genCollectedHeap.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -928,6 +928,8 @@ guarantee(VerifyBeforeGC || VerifyDuringGC || VerifyBeforeExit || + PrintAssembly || + tty->count() != 0 || // already printing VerifyAfterGC, "too expensive"); #endif // This might be sped up with a cache of the last generation that diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/arrayKlassKlass.cpp --- a/src/share/vm/oops/arrayKlassKlass.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/arrayKlassKlass.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -159,7 +159,7 @@ assert(obj->is_klass(), "must be klass"); klassKlass::oop_print_on(obj, st); } - +#endif //PRODUCT void arrayKlassKlass::oop_print_value_on(oop obj, outputStream* st) { assert(obj->is_klass(), "must be klass"); @@ -168,7 +168,6 @@ st->print("[]"); } } -#endif const char* arrayKlassKlass::internal_name() const { diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/arrayKlassKlass.hpp --- a/src/share/vm/oops/arrayKlassKlass.hpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/arrayKlassKlass.hpp Sat Jan 16 23:51:50 2010 -0800 @@ -55,14 +55,13 @@ int oop_oop_iterate(oop obj, OopClosure* blk); int oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr); -#ifndef PRODUCT public: // Printing + void oop_print_value_on(oop obj, outputStream* st); +#ifndef PRODUCT void oop_print_on(oop obj, outputStream* st); - void oop_print_value_on(oop obj, outputStream* st); -#endif +#endif //PRODUCT - public: // Verification const char* internal_name() const; void oop_verify_on(oop obj, outputStream* st); diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/compiledICHolderKlass.cpp --- a/src/share/vm/oops/compiledICHolderKlass.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/compiledICHolderKlass.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -166,12 +166,12 @@ st->print(" - klass: "); c->holder_klass()->print_value_on(st); st->cr(); } +#endif //PRODUCT void compiledICHolderKlass::oop_print_value_on(oop obj, outputStream* st) { assert(obj->is_compiledICHolder(), "must be compiledICHolder"); Klass::oop_print_value_on(obj, st); } -#endif const char* compiledICHolderKlass::internal_name() const { return "{compiledICHolder}"; diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/compiledICHolderKlass.hpp --- a/src/share/vm/oops/compiledICHolderKlass.hpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/compiledICHolderKlass.hpp Sat Jan 16 23:51:50 2010 -0800 @@ -68,14 +68,13 @@ int oop_oop_iterate(oop obj, OopClosure* blk); int oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr); -#ifndef PRODUCT public: // Printing + void oop_print_value_on(oop obj, outputStream* st); +#ifndef PRODUCT void oop_print_on (oop obj, outputStream* st); - void oop_print_value_on(oop obj, outputStream* st); -#endif +#endif //PRODUCT - public: // Verification const char* internal_name() const; void oop_verify_on(oop obj, outputStream* st); diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/constMethodKlass.cpp --- a/src/share/vm/oops/constMethodKlass.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/constMethodKlass.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -216,6 +216,7 @@ } } +#endif //PRODUCT // Short version of printing constMethodOop - just print the name of the // method it belongs to. @@ -226,8 +227,6 @@ m->method()->print_value_on(st); } -#endif // PRODUCT - const char* constMethodKlass::internal_name() const { return "{constMethod}"; } diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/constMethodKlass.hpp --- a/src/share/vm/oops/constMethodKlass.hpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/constMethodKlass.hpp Sat Jan 16 23:51:50 2010 -0800 @@ -77,15 +77,13 @@ int oop_oop_iterate(oop obj, OopClosure* blk); int oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr); -#ifndef PRODUCT public: // Printing + void oop_print_value_on(oop obj, outputStream* st); +#ifndef PRODUCT void oop_print_on (oop obj, outputStream* st); - void oop_print_value_on(oop obj, outputStream* st); +#endif //PRODUCT -#endif - - public: // Verify operations const char* internal_name() const; void oop_verify_on(oop obj, outputStream* st); diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/constantPoolKlass.cpp --- a/src/share/vm/oops/constantPoolKlass.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/constantPoolKlass.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -387,8 +387,18 @@ cp->set_cache(cache()); } +#endif -#endif +void constantPoolKlass::oop_print_value_on(oop obj, outputStream* st) { + assert(obj->is_constantPool(), "must be constantPool"); + constantPoolOop cp = constantPoolOop(obj); + st->print("constant pool [%d]", cp->length()); + if (cp->has_pseudo_string()) st->print("/pseudo_string"); + if (cp->has_invokedynamic()) st->print("/invokedynamic"); + cp->print_address_on(st); + st->print(" for "); + cp->pool_holder()->print_value_on(st); +} const char* constantPoolKlass::internal_name() const { return "{constant pool}"; diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/constantPoolKlass.hpp --- a/src/share/vm/oops/constantPoolKlass.hpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/constantPoolKlass.hpp Sat Jan 16 23:51:50 2010 -0800 @@ -65,9 +65,10 @@ juint alloc_size() const { return _alloc_size; } void set_alloc_size(juint n) { _alloc_size = n; } -#ifndef PRODUCT public: // Printing + void oop_print_value_on(oop obj, outputStream* st); +#ifndef PRODUCT void oop_print_on(oop obj, outputStream* st); #endif diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/cpCacheKlass.cpp --- a/src/share/vm/oops/cpCacheKlass.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/cpCacheKlass.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -261,6 +261,15 @@ #endif +void constantPoolCacheKlass::oop_print_value_on(oop obj, outputStream* st) { + assert(obj->is_constantPoolCache(), "obj must be constant pool cache"); + constantPoolCacheOop cache = (constantPoolCacheOop)obj; + st->print("cache [%d]", cache->length()); + cache->print_address_on(st); + st->print(" for "); + cache->constant_pool()->print_value_on(st); +} + void constantPoolCacheKlass::oop_verify_on(oop obj, outputStream* st) { guarantee(obj->is_constantPoolCache(), "obj must be constant pool cache"); constantPoolCacheOop cache = (constantPoolCacheOop)obj; diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/cpCacheKlass.hpp --- a/src/share/vm/oops/cpCacheKlass.hpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/cpCacheKlass.hpp Sat Jan 16 23:51:50 2010 -0800 @@ -61,9 +61,10 @@ juint alloc_size() const { return _alloc_size; } void set_alloc_size(juint n) { _alloc_size = n; } -#ifndef PRODUCT public: // Printing + void oop_print_value_on(oop obj, outputStream* st); +#ifndef PRODUCT void oop_print_on(oop obj, outputStream* st); #endif diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/instanceKlass.cpp --- a/src/share/vm/oops/instanceKlass.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/instanceKlass.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -2268,6 +2268,8 @@ } } +#endif //PRODUCT + void instanceKlass::oop_print_value_on(oop obj, outputStream* st) { st->print("a "); name()->print_value_on(st); @@ -2299,8 +2301,6 @@ } } -#endif // ndef PRODUCT - const char* instanceKlass::internal_name() const { return external_name(); } diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/instanceKlass.hpp --- a/src/share/vm/oops/instanceKlass.hpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/instanceKlass.hpp Sat Jan 16 23:51:50 2010 -0800 @@ -839,17 +839,16 @@ // JVMTI support jint jvmti_class_status() const; -#ifndef PRODUCT public: // Printing + void oop_print_value_on(oop obj, outputStream* st); +#ifndef PRODUCT void oop_print_on (oop obj, outputStream* st); - void oop_print_value_on(oop obj, outputStream* st); void print_dependent_nmethods(bool verbose = false); bool is_dependent_nmethod(nmethod* nm); #endif - public: // Verification const char* internal_name() const; void oop_verify_on(oop obj, outputStream* st); diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/instanceKlassKlass.cpp --- a/src/share/vm/oops/instanceKlassKlass.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/instanceKlassKlass.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -638,6 +638,7 @@ st->cr(); } +#endif //PRODUCT void instanceKlassKlass::oop_print_value_on(oop obj, outputStream* st) { assert(obj->is_klass(), "must be klass"); @@ -645,8 +646,6 @@ ik->name()->print_value_on(st); } -#endif // PRODUCT - const char* instanceKlassKlass::internal_name() const { return "{instance class}"; } diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/instanceKlassKlass.hpp --- a/src/share/vm/oops/instanceKlassKlass.hpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/instanceKlassKlass.hpp Sat Jan 16 23:51:50 2010 -0800 @@ -69,14 +69,13 @@ // Apply closure to the InstanceKlass oops that are outside the java heap. inline void iterate_c_heap_oops(instanceKlass* ik, OopClosure* closure); -#ifndef PRODUCT public: // Printing + void oop_print_value_on(oop obj, outputStream* st); +#ifndef PRODUCT void oop_print_on(oop obj, outputStream* st); - void oop_print_value_on(oop obj, outputStream* st); #endif - public: // Verification const char* internal_name() const; void oop_verify_on(oop obj, outputStream* st); diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/klass.cpp --- a/src/share/vm/oops/klass.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/klass.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -541,6 +541,7 @@ st->cr(); } +#endif //PRODUCT void Klass::oop_print_value_on(oop obj, outputStream* st) { // print title @@ -549,8 +550,6 @@ obj->print_address_on(st); } -#endif - // Verification void Klass::oop_verify_on(oop obj, outputStream* st) { diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/klass.hpp --- a/src/share/vm/oops/klass.hpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/klass.hpp Sat Jan 16 23:51:50 2010 -0800 @@ -776,14 +776,13 @@ // JVMTI support virtual jint jvmti_class_status() const; -#ifndef PRODUCT public: // Printing + virtual void oop_print_value_on(oop obj, outputStream* st); +#ifndef PRODUCT virtual void oop_print_on (oop obj, outputStream* st); - virtual void oop_print_value_on(oop obj, outputStream* st); -#endif +#endif //PRODUCT - public: // Verification virtual const char* internal_name() const = 0; virtual void oop_verify_on(oop obj, outputStream* st); diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/klassKlass.cpp --- a/src/share/vm/oops/klassKlass.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/klassKlass.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -202,13 +202,12 @@ Klass::oop_print_on(obj, st); } +#endif //PRODUCT void klassKlass::oop_print_value_on(oop obj, outputStream* st) { Klass::oop_print_value_on(obj, st); } -#endif - const char* klassKlass::internal_name() const { return "{other class}"; } diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/klassKlass.hpp --- a/src/share/vm/oops/klassKlass.hpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/klassKlass.hpp Sat Jan 16 23:51:50 2010 -0800 @@ -67,14 +67,13 @@ juint alloc_size() const { return _alloc_size; } void set_alloc_size(juint n) { _alloc_size = n; } -#ifndef PRODUCT public: // Printing + void oop_print_value_on(oop obj, outputStream* st); +#ifndef PRODUCT void oop_print_on (oop obj, outputStream* st); - void oop_print_value_on(oop obj, outputStream* st); -#endif +#endif //PRODUCT - public: // Verification const char* internal_name() const; void oop_verify_on(oop obj, outputStream* st); diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/methodDataKlass.cpp --- a/src/share/vm/oops/methodDataKlass.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/methodDataKlass.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -214,6 +214,8 @@ m->print_data_on(st); } +#endif //PRODUCT + void methodDataKlass::oop_print_value_on(oop obj, outputStream* st) { assert(obj->is_methodData(), "should be method data"); methodDataOop m = methodDataOop(obj); @@ -221,8 +223,6 @@ m->method()->print_value_on(st); } -#endif // !PRODUCT - const char* methodDataKlass::internal_name() const { return "{method data}"; } diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/methodDataKlass.hpp --- a/src/share/vm/oops/methodDataKlass.hpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/methodDataKlass.hpp Sat Jan 16 23:51:50 2010 -0800 @@ -71,14 +71,13 @@ int oop_oop_iterate(oop obj, OopClosure* blk); int oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr); -#ifndef PRODUCT public: // Printing + void oop_print_value_on(oop obj, outputStream* st); +#ifndef PRODUCT void oop_print_on (oop obj, outputStream* st); - void oop_print_value_on(oop obj, outputStream* st); -#endif // !PRODUCT +#endif //PRODUCT - public: // Verify operations const char* internal_name() const; void oop_verify_on(oop obj, outputStream* st); diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/methodKlass.cpp --- a/src/share/vm/oops/methodKlass.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/methodKlass.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -308,6 +308,7 @@ } } +#endif //PRODUCT void methodKlass::oop_print_value_on(oop obj, outputStream* st) { assert(obj->is_method(), "must be method"); @@ -323,8 +324,6 @@ if (WizardMode && m->code() != NULL) st->print(" ((nmethod*)%p)", m->code()); } -#endif // PRODUCT - const char* methodKlass::internal_name() const { return "{method}"; } diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/methodKlass.hpp --- a/src/share/vm/oops/methodKlass.hpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/methodKlass.hpp Sat Jan 16 23:51:50 2010 -0800 @@ -68,14 +68,13 @@ int oop_oop_iterate(oop obj, OopClosure* blk); int oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr); -#ifndef PRODUCT public: // Printing + void oop_print_value_on(oop obj, outputStream* st); +#ifndef PRODUCT void oop_print_on (oop obj, outputStream* st); - void oop_print_value_on(oop obj, outputStream* st); -#endif +#endif //PRODUCT - public: // Verify operations const char* internal_name() const; void oop_verify_on(oop obj, outputStream* st); diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/methodOop.cpp --- a/src/share/vm/oops/methodOop.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/methodOop.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -1,5 +1,5 @@ /* - * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2010 Sun Microsystems, Inc. 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 @@ -821,6 +821,18 @@ return pchase; } +//------------------------------------------------------------------------------ +// methodOopDesc::is_method_handle_adapter +// +// Tests if this method is an internal adapter frame from the +// MethodHandleCompiler. +bool methodOopDesc::is_method_handle_adapter() const { + return ((name() == vmSymbols::invoke_name() && + method_holder() == SystemDictionary::MethodHandle_klass()) + || + method_holder() == SystemDictionary::InvokeDynamic_klass()); +} + methodHandle methodOopDesc::make_invoke_method(KlassHandle holder, symbolHandle signature, Handle method_type, TRAPS) { diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/methodOop.hpp --- a/src/share/vm/oops/methodOop.hpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/methodOop.hpp Sat Jan 16 23:51:50 2010 -0800 @@ -1,5 +1,5 @@ /* - * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2010 Sun Microsystems, Inc. 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 @@ -525,6 +525,9 @@ // JSR 292 support bool is_method_handle_invoke() const { return access_flags().is_method_handle_invoke(); } + // Tests if this method is an internal adapter frame from the + // MethodHandleCompiler. + bool is_method_handle_adapter() const; static methodHandle make_invoke_method(KlassHandle holder, symbolHandle signature, Handle method_type, @@ -538,6 +541,7 @@ // all without checking for a stack overflow static int extra_stack_entries() { return (EnableMethodHandles ? (int)MethodHandlePushLimit : 0) + (EnableInvokeDynamic ? 3 : 0); } static int extra_stack_words(); // = extra_stack_entries() * Interpreter::stackElementSize() + // RedefineClasses() support: bool is_old() const { return access_flags().is_old(); } void set_is_old() { _access_flags.set_is_old(); } diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/objArrayKlass.cpp --- a/src/share/vm/oops/objArrayKlass.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/objArrayKlass.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -499,6 +499,8 @@ } } +#endif //PRODUCT + static int max_objArray_print_length = 4; void objArrayKlass::oop_print_value_on(oop obj, outputStream* st) { @@ -508,7 +510,7 @@ int len = objArrayOop(obj)->length(); st->print("[%d] ", len); obj->print_address_on(st); - if (PrintOopAddress || PrintMiscellaneous && (WizardMode || Verbose)) { + if (NOT_PRODUCT(PrintOopAddress ||) PrintMiscellaneous && (WizardMode || Verbose)) { st->print("{"); for (int i = 0; i < len; i++) { if (i > max_objArray_print_length) { @@ -520,8 +522,6 @@ } } -#endif // PRODUCT - const char* objArrayKlass::internal_name() const { return external_name(); } diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/objArrayKlass.hpp --- a/src/share/vm/oops/objArrayKlass.hpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/objArrayKlass.hpp Sat Jan 16 23:51:50 2010 -0800 @@ -119,14 +119,13 @@ private: static klassOop array_klass_impl (objArrayKlassHandle this_oop, bool or_null, int n, TRAPS); -#ifndef PRODUCT public: // Printing + void oop_print_value_on(oop obj, outputStream* st); +#ifndef PRODUCT void oop_print_on (oop obj, outputStream* st); - void oop_print_value_on(oop obj, outputStream* st); -#endif +#endif //PRODUCT - public: // Verification const char* internal_name() const; void oop_verify_on(oop obj, outputStream* st); diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/objArrayKlassKlass.cpp --- a/src/share/vm/oops/objArrayKlassKlass.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/objArrayKlassKlass.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -278,6 +278,7 @@ st->cr(); } +#endif //PRODUCT void objArrayKlassKlass::oop_print_value_on(oop obj, outputStream* st) { assert(obj->is_klass(), "must be klass"); @@ -287,8 +288,6 @@ st->print("[]"); } -#endif - const char* objArrayKlassKlass::internal_name() const { return "{object array class}"; } diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/objArrayKlassKlass.hpp --- a/src/share/vm/oops/objArrayKlassKlass.hpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/objArrayKlassKlass.hpp Sat Jan 16 23:51:50 2010 -0800 @@ -64,14 +64,13 @@ // helpers static klassOop allocate_objArray_klass_impl(objArrayKlassKlassHandle this_oop, int n, KlassHandle element_klass, TRAPS); -#ifndef PRODUCT public: // Printing + void oop_print_value_on(oop obj, outputStream* st); +#ifndef PRODUCT void oop_print_on(oop obj, outputStream* st); - void oop_print_value_on(oop obj, outputStream* st); -#endif +#endif //PRODUCT - public: // Verification const char* internal_name() const; void oop_verify_on(oop obj, outputStream* st); diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/oop.cpp --- a/src/share/vm/oops/oop.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/oop.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -31,14 +31,13 @@ #ifdef PRODUCT void oopDesc::print_on(outputStream* st) const {} -void oopDesc::print_value_on(outputStream* st) const {} void oopDesc::print_address_on(outputStream* st) const {} -char* oopDesc::print_value_string() { return NULL; } char* oopDesc::print_string() { return NULL; } void oopDesc::print() {} -void oopDesc::print_value() {} void oopDesc::print_address() {} -#else + +#else //PRODUCT + void oopDesc::print_on(outputStream* st) const { if (this == NULL) { st->print_cr("NULL"); @@ -47,22 +46,6 @@ } } -void oopDesc::print_value_on(outputStream* st) const { - oop obj = oop(this); - if (this == NULL) { - st->print("NULL"); - } else if (java_lang_String::is_instance(obj)) { - java_lang_String::print(obj, st); - if (PrintOopAddress) print_address_on(st); -#ifdef ASSERT - } else if (!Universe::heap()->is_in(obj) || !Universe::heap()->is_in(klass())) { - st->print("### BAD OOP %p ###", (address)obj); -#endif - } else { - blueprint()->oop_print_value_on(obj, st); - } -} - void oopDesc::print_address_on(outputStream* st) const { if (PrintOopAddress) { st->print("{"INTPTR_FORMAT"}", this); @@ -71,23 +54,47 @@ void oopDesc::print() { print_on(tty); } -void oopDesc::print_value() { print_value_on(tty); } - void oopDesc::print_address() { print_address_on(tty); } char* oopDesc::print_string() { - stringStream* st = new stringStream(); - print_on(st); - return st->as_string(); + stringStream st; + print_on(&st); + return st.as_string(); +} + +#endif // PRODUCT + +// The print_value functions are present in all builds, to support the disassembler. + +void oopDesc::print_value() { + print_value_on(tty); } char* oopDesc::print_value_string() { - stringStream* st = new stringStream(); - print_value_on(st); - return st->as_string(); + char buf[100]; + stringStream st(buf, sizeof(buf)); + print_value_on(&st); + return st.as_string(); } -#endif // PRODUCT +void oopDesc::print_value_on(outputStream* st) const { + oop obj = oop(this); + if (this == NULL) { + st->print("NULL"); + } else if (java_lang_String::is_instance(obj)) { + java_lang_String::print(obj, st); +#ifndef PRODUCT + if (PrintOopAddress) print_address_on(st); +#endif //PRODUCT +#ifdef ASSERT + } else if (!Universe::heap()->is_in(obj) || !Universe::heap()->is_in(klass())) { + st->print("### BAD OOP %p ###", (address)obj); +#endif //ASSERT + } else { + blueprint()->oop_print_value_on(obj, st); + } +} + void oopDesc::verify_on(outputStream* st) { if (this != NULL) { diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/symbolKlass.cpp --- a/src/share/vm/oops/symbolKlass.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/symbolKlass.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -213,6 +213,8 @@ st->print("'"); } +#endif //PRODUCT + void symbolKlass::oop_print_value_on(oop obj, outputStream* st) { symbolOop sym = symbolOop(obj); st->print("'"); @@ -222,8 +224,6 @@ st->print("'"); } -#endif //PRODUCT - const char* symbolKlass::internal_name() const { return "{symbol}"; } diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/symbolKlass.hpp --- a/src/share/vm/oops/symbolKlass.hpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/symbolKlass.hpp Sat Jan 16 23:51:50 2010 -0800 @@ -65,10 +65,10 @@ int oop_oop_iterate(oop obj, OopClosure* blk); int oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr); -#ifndef PRODUCT // Printing void oop_print_value_on(oop obj, outputStream* st); +#ifndef PRODUCT void oop_print_on(oop obj, outputStream* st); -#endif +#endif //PRODUCT const char* internal_name() const; }; diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/typeArrayKlassKlass.cpp --- a/src/share/vm/oops/typeArrayKlassKlass.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/typeArrayKlassKlass.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -45,6 +45,7 @@ Klass:: oop_print_on(obj, st); } +#endif //PRODUCT void typeArrayKlassKlass::oop_print_value_on(oop obj, outputStream* st) { assert(obj->is_klass(), "must be klass"); @@ -63,8 +64,6 @@ st->print("}"); } -#endif - const char* typeArrayKlassKlass::internal_name() const { return "{type array class}"; } diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/oops/typeArrayKlassKlass.hpp --- a/src/share/vm/oops/typeArrayKlassKlass.hpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/oops/typeArrayKlassKlass.hpp Sat Jan 16 23:51:50 2010 -0800 @@ -47,12 +47,12 @@ static int header_size() { return oopDesc::header_size() + sizeof(typeArrayKlassKlass)/HeapWordSize; } int object_size() const { return align_object_size(header_size()); } -#ifndef PRODUCT public: // Printing + void oop_print_value_on(oop obj, outputStream* st); +#ifndef PRODUCT void oop_print_on(oop obj, outputStream* st); - void oop_print_value_on(oop obj, outputStream* st); -#endif - public: +#endif //PRODUCT + const char* internal_name() const; }; diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/opto/bytecodeInfo.cpp --- a/src/share/vm/opto/bytecodeInfo.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/opto/bytecodeInfo.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -27,11 +27,16 @@ //============================================================================= //------------------------------InlineTree------------------------------------- -InlineTree::InlineTree( Compile* c, const InlineTree *caller_tree, ciMethod* callee, JVMState* caller_jvms, int caller_bci, float site_invoke_ratio ) +InlineTree::InlineTree( Compile* c, + const InlineTree *caller_tree, ciMethod* callee, + JVMState* caller_jvms, int caller_bci, + float site_invoke_ratio, int site_depth_adjust) : C(c), _caller_jvms(caller_jvms), _caller_tree((InlineTree*)caller_tree), _method(callee), _site_invoke_ratio(site_invoke_ratio), - _count_inline_bcs(method()->code_size()) { + _site_depth_adjust(site_depth_adjust), + _count_inline_bcs(method()->code_size()) +{ NOT_PRODUCT(_count_inlines = 0;) if (_caller_jvms != NULL) { // Keep a private copy of the caller_jvms: @@ -40,7 +45,7 @@ assert(!caller_jvms->should_reexecute(), "there should be no reexecute bytecode with inlining"); } assert(_caller_jvms->same_calls_as(caller_jvms), "consistent JVMS"); - assert((caller_tree == NULL ? 0 : caller_tree->inline_depth() + 1) == inline_depth(), "correct (redundant) depth parameter"); + assert((caller_tree == NULL ? 0 : caller_tree->stack_depth() + 1) == stack_depth(), "correct (redundant) depth parameter"); assert(caller_bci == this->caller_bci(), "correct (redundant) bci parameter"); if (UseOldInlining) { // Update hierarchical counts, count_inline_bcs() and count_inlines() @@ -52,10 +57,13 @@ } } -InlineTree::InlineTree(Compile* c, ciMethod* callee_method, JVMState* caller_jvms, float site_invoke_ratio) +InlineTree::InlineTree(Compile* c, ciMethod* callee_method, JVMState* caller_jvms, + float site_invoke_ratio, int site_depth_adjust) : C(c), _caller_jvms(caller_jvms), _caller_tree(NULL), _method(callee_method), _site_invoke_ratio(site_invoke_ratio), - _count_inline_bcs(method()->code_size()) { + _site_depth_adjust(site_depth_adjust), + _count_inline_bcs(method()->code_size()) +{ NOT_PRODUCT(_count_inlines = 0;) assert(!UseOldInlining, "do not use for old stuff"); } @@ -269,10 +277,13 @@ return msg; } - bool is_accessor = InlineAccessors && callee_method->is_accessor(); + if (InlineAccessors && callee_method->is_accessor()) { + // accessor methods are not subject to any of the following limits. + return NULL; + } // suppress a few checks for accessors and trivial methods - if (!is_accessor && callee_method->code_size() > MaxTrivialSize) { + if (callee_method->code_size() > MaxTrivialSize) { // don't inline into giant methods if (C->unique() > (uint)NodeCountInliningCutoff) { @@ -291,7 +302,7 @@ } } - if (!C->do_inlining() && InlineAccessors && !is_accessor) { + if (!C->do_inlining() && InlineAccessors) { return "not an accessor"; } if( inline_depth() > MaxInlineLevel ) { @@ -464,7 +475,30 @@ if (old_ilt != NULL) { return old_ilt; } - InlineTree *ilt = new InlineTree( C, this, callee_method, caller_jvms, caller_bci, recur_frequency ); + int new_depth_adjust = 0; + if (caller_jvms->method() != NULL) { + if ((caller_jvms->method()->name() == ciSymbol::invoke_name() && + caller_jvms->method()->holder()->name() == ciSymbol::java_dyn_MethodHandle()) + || caller_jvms->method()->holder()->name() == ciSymbol::java_dyn_InvokeDynamic()) + /* @@@ FIXME: + if (caller_jvms->method()->is_method_handle_adapter()) + */ + new_depth_adjust -= 1; // don't count actions in MH or indy adapter frames + else if (callee_method->is_method_handle_invoke()) { + new_depth_adjust -= 1; // don't count method handle calls from java.dyn implem + } + if (new_depth_adjust != 0 && PrintInlining) { + stringStream nm1; caller_jvms->method()->print_name(&nm1); + stringStream nm2; callee_method->print_name(&nm2); + tty->print_cr("discounting inlining depth from %s to %s", nm1.base(), nm2.base()); + } + if (new_depth_adjust != 0 && C->log()) { + int id1 = C->log()->identify(caller_jvms->method()); + int id2 = C->log()->identify(callee_method); + C->log()->elem("inline_depth_discount caller='%d' callee='%d'", id1, id2); + } + } + InlineTree *ilt = new InlineTree(C, this, callee_method, caller_jvms, caller_bci, recur_frequency, _site_depth_adjust + new_depth_adjust); _subtrees.append( ilt ); NOT_PRODUCT( _count_inlines += 1; ) @@ -490,7 +524,7 @@ Compile* C = Compile::current(); // Root of inline tree - InlineTree *ilt = new InlineTree(C, NULL, C->method(), NULL, -1, 1.0F); + InlineTree *ilt = new InlineTree(C, NULL, C->method(), NULL, -1, 1.0F, 0); return ilt; } diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/opto/divnode.cpp --- a/src/share/vm/opto/divnode.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/opto/divnode.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -114,7 +114,8 @@ if( andconi_t && andconi_t->is_con() ) { jint andconi = andconi_t->get_con(); if( andconi < 0 && is_power_of_2(-andconi) && (-andconi) >= d ) { - dividend = dividend->in(1); + if( (-andconi) == d ) // Remove AND if it clears bits which will be shifted + dividend = dividend->in(1); needs_rounding = false; } } @@ -356,7 +357,8 @@ if( andconl_t && andconl_t->is_con() ) { jlong andconl = andconl_t->get_con(); if( andconl < 0 && is_power_of_2_long(-andconl) && (-andconl) >= d ) { - dividend = dividend->in(1); + if( (-andconl) == d ) // Remove AND if it clears bits which will be shifted + dividend = dividend->in(1); needs_rounding = false; } } diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/opto/doCall.cpp --- a/src/share/vm/opto/doCall.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/opto/doCall.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -43,7 +43,9 @@ } #endif -CallGenerator* Compile::call_generator(ciMethod* call_method, int vtable_index, bool call_is_virtual, JVMState* jvms, bool allow_inline, float prof_factor) { +CallGenerator* Compile::call_generator(ciMethod* call_method, int vtable_index, bool call_is_virtual, + JVMState* jvms, bool allow_inline, + float prof_factor) { CallGenerator* cg; // Dtrace currently doesn't work unless all calls are vanilla @@ -116,7 +118,7 @@ // TO DO: When UseOldInlining is removed, copy the ILT code elsewhere. float site_invoke_ratio = prof_factor; // Note: ilt is for the root of this parse, not the present call site. - ilt = new InlineTree(this, jvms->method(), jvms->caller(), site_invoke_ratio); + ilt = new InlineTree(this, jvms->method(), jvms->caller(), site_invoke_ratio, 0); } WarmCallInfo scratch_ci; if (!UseOldInlining) diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/opto/ifnode.cpp --- a/src/share/vm/opto/ifnode.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/opto/ifnode.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -531,6 +531,9 @@ if (linear_only) return NULL; + if( dom->is_Root() ) + return NULL; + // Else hit a Region. Check for a loop header if( dom->is_Loop() ) return dom->in(1); // Skip up thru loops diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/opto/lcm.cpp --- a/src/share/vm/opto/lcm.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/opto/lcm.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -120,6 +120,7 @@ case Op_LoadRange: case Op_LoadD_unaligned: case Op_LoadL_unaligned: + assert(mach->in(2) == val, "should be address"); break; case Op_StoreB: case Op_StoreC: @@ -146,6 +147,21 @@ default: // Also check for embedded loads if( !mach->needs_anti_dependence_check() ) continue; // Not an memory op; skip it + { + // Check that value is used in memory address. + Node* base; + Node* index; + const MachOper* oper = mach->memory_inputs(base, index); + if (oper == NULL || oper == (MachOper*)-1) { + continue; // Not an memory op; skip it + } + if (val == base || + val == index && val->bottom_type()->isa_narrowoop()) { + break; // Found it + } else { + continue; // Skip it + } + } break; } // check if the offset is not too high for implicit exception diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/opto/library_call.cpp --- a/src/share/vm/opto/library_call.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/opto/library_call.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -1,5 +1,5 @@ /* - * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1999-2010 Sun Microsystems, Inc. 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 @@ -3697,12 +3697,14 @@ // Helper routine for above bool LibraryCallKit::is_method_invoke_or_aux_frame(JVMState* jvms) { + ciMethod* method = jvms->method(); + // Is this the Method.invoke method itself? - if (jvms->method()->intrinsic_id() == vmIntrinsics::_invoke) + if (method->intrinsic_id() == vmIntrinsics::_invoke) return true; // Is this a helper, defined somewhere underneath MethodAccessorImpl. - ciKlass* k = jvms->method()->holder(); + ciKlass* k = method->holder(); if (k->is_instance_klass()) { ciInstanceKlass* ik = k->as_instance_klass(); for (; ik != NULL; ik = ik->super()) { @@ -3712,6 +3714,10 @@ } } } + else if (method->is_method_handle_adapter()) { + // This is an internal adapter frame from the MethodHandleCompiler -- skip it + return true; + } return false; } diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/opto/parse.hpp --- a/src/share/vm/opto/parse.hpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/opto/parse.hpp Sat Jan 16 23:51:50 2010 -0800 @@ -39,6 +39,7 @@ // Always between 0.0 and 1.0. Represents the percentage of the method's // total execution time used at this call site. const float _site_invoke_ratio; + const int _site_depth_adjust; float compute_callee_frequency( int caller_bci ) const; GrowableArray _subtrees; @@ -50,7 +51,8 @@ ciMethod* callee_method, JVMState* caller_jvms, int caller_bci, - float site_invoke_ratio); + float site_invoke_ratio, + int site_depth_adjust); InlineTree *build_inline_tree_for_callee(ciMethod* callee_method, JVMState* caller_jvms, int caller_bci); @@ -61,14 +63,15 @@ InlineTree *caller_tree() const { return _caller_tree; } InlineTree* callee_at(int bci, ciMethod* m) const; - int inline_depth() const { return _caller_jvms ? _caller_jvms->depth() : 0; } + int inline_depth() const { return stack_depth() + _site_depth_adjust; } + int stack_depth() const { return _caller_jvms ? _caller_jvms->depth() : 0; } public: static InlineTree* build_inline_tree_root(); static InlineTree* find_subtree_from_root(InlineTree* root, JVMState* jvms, ciMethod* callee, bool create_if_not_found = false); // For temporary (stack-allocated, stateless) ilts: - InlineTree(Compile* c, ciMethod* callee_method, JVMState* caller_jvms, float site_invoke_ratio); + InlineTree(Compile* c, ciMethod* callee_method, JVMState* caller_jvms, float site_invoke_ratio, int site_depth_adjust); // InlineTree enum enum InlineStyle { diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/prims/methodHandleWalk.cpp --- a/src/share/vm/prims/methodHandleWalk.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/prims/methodHandleWalk.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -631,6 +631,7 @@ Handle first_mtype(THREAD, chain().method_type_oop()); // _rklass is NULL for primitives. _rtype = java_lang_Class::as_BasicType(java_dyn_MethodType::rtype(first_mtype()), &_rklass); + if (_rtype == T_ARRAY) _rtype = T_OBJECT; int params = _callee->size_of_parameters(); // Incoming arguments plus receiver. _num_params = for_invokedynamic() ? params - 1 : params; // XXX Check if callee is static? @@ -957,10 +958,13 @@ symbolOop name = m->name(); symbolOop signature = m->signature(); - // This generated adapter method should be in the same class as the - // DMH target method (for accessability reasons). if (tailcall) { - _target_klass = klass; + // Actually, in order to make these methods more recognizable, + // let's put them in holder classes MethodHandle and InvokeDynamic. + // That way stack walkers and compiler heuristics can recognize them. + _target_klass = (for_invokedynamic() + ? SystemDictionary::InvokeDynamic_klass() + : SystemDictionary::MethodHandle_klass()); } // instanceKlass* ik = instanceKlass::cast(klass); @@ -1017,6 +1021,7 @@ // If tailcall, we have walked all the way to a direct method handle. // Otherwise, make a recursive call to some helper routine. BasicType rbt = m->result_type(); + if (rbt == T_ARRAY) rbt = T_OBJECT; ArgToken ret; if (tailcall) { if (rbt != _rtype) { diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/prims/methodHandleWalk.hpp --- a/src/share/vm/prims/methodHandleWalk.hpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/prims/methodHandleWalk.hpp Sat Jan 16 23:51:50 2010 -0800 @@ -404,4 +404,10 @@ // Compile the given MH chain into bytecode. methodHandle compile(TRAPS); + + // Tests if the given class is a MH adapter holder. + static bool klass_is_method_handle_adapter_holder(klassOop klass) { + return (klass == SystemDictionary::MethodHandle_klass() || + klass == SystemDictionary::InvokeDynamic_klass()); + } }; diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/runtime/arguments.cpp --- a/src/share/vm/runtime/arguments.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/runtime/arguments.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -2649,6 +2649,10 @@ if (match_option(option, "-XX:-IgnoreUnrecognizedVMOptions", &tail)) { IgnoreUnrecognizedVMOptions = false; } + if (match_option(option, "-XX:+PrintFlagsInitial", &tail)) { + CommandLineFlags::printFlags(); + vm_exit(0); + } } if (IgnoreUnrecognizedVMOptions) { @@ -2806,15 +2810,18 @@ } #endif + if (PrintAssembly && FLAG_IS_DEFAULT(DebugNonSafepoints)) { + warning("PrintAssembly is enabled; turning on DebugNonSafepoints to gain additional output"); + DebugNonSafepoints = true; + } + if (PrintCommandLineFlags) { CommandLineFlags::printSetFlags(); } -#ifdef ASSERT if (PrintFlagsFinal) { CommandLineFlags::printFlags(); } -#endif return JNI_OK; } diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/runtime/globals.cpp --- a/src/share/vm/runtime/globals.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/runtime/globals.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -468,6 +468,8 @@ assert(Arguments::check_vm_args_consistency(), "Some flag settings conflict"); } +#endif // PRODUCT + void CommandLineFlags::printFlags() { // Print the flags sorted by name // note: this method is called before the thread structure is in place @@ -493,5 +495,3 @@ } FREE_C_HEAP_ARRAY(Flag*, array); } - -#endif diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/runtime/globals.hpp --- a/src/share/vm/runtime/globals.hpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/runtime/globals.hpp Sat Jan 16 23:51:50 2010 -0800 @@ -211,7 +211,7 @@ static bool wasSetOnCmdline(const char* name, bool* value); static void printSetFlags(); - static void printFlags() PRODUCT_RETURN; + static void printFlags(); static void verify() PRODUCT_RETURN; }; @@ -327,9 +327,6 @@ product(bool, UseMembar, false, \ "(Unstable) Issues membars on thread state transitions") \ \ - product(bool, PrintCommandLineFlags, false, \ - "Prints flags that appeared on the command line") \ - \ diagnostic(bool, UnlockDiagnosticVMOptions, trueInDebug, \ "Enable normal processing of flags relating to field diagnostics")\ \ @@ -2057,9 +2054,6 @@ "number of times a GC thread (minus the coordinator) " \ "will sleep while yielding before giving up and resuming GC") \ \ - notproduct(bool, PrintFlagsFinal, false, \ - "Print all command line flags after argument processing") \ - \ /* gc tracing */ \ manageable(bool, PrintGC, false, \ "Print message at garbage collect") \ @@ -2359,11 +2353,20 @@ "If false, restricts profiled locations to the root method only") \ \ product(bool, PrintVMOptions, trueInDebug, \ - "print VM flag settings") \ + "Print flags that appeared on the command line") \ \ product(bool, IgnoreUnrecognizedVMOptions, false, \ "Ignore unrecognized VM options") \ \ + product(bool, PrintCommandLineFlags, false, \ + "Print flags specified on command line or set by ergonomics") \ + \ + product(bool, PrintFlagsInitial, false, \ + "Print all VM flags before argument processing and exit VM") \ + \ + product(bool, PrintFlagsFinal, false, \ + "Print all VM flags after argument and ergonomic processing") \ + \ diagnostic(bool, SerializeVMOutput, true, \ "Use a mutex to serialize output to tty and hotspot.log") \ \ @@ -2762,10 +2765,10 @@ notproduct(intx, MaxSubklassPrintSize, 4, \ "maximum number of subklasses to print when printing klass") \ \ - develop(intx, MaxInlineLevel, 9, \ + product(intx, MaxInlineLevel, 9, \ "maximum number of nested calls that are inlined") \ \ - develop(intx, MaxRecursiveInlineLevel, 1, \ + product(intx, MaxRecursiveInlineLevel, 1, \ "maximum number of nested recursive calls that are inlined") \ \ product_pd(intx, InlineSmallCode, \ @@ -2778,10 +2781,10 @@ product_pd(intx, FreqInlineSize, \ "maximum bytecode size of a frequent method to be inlined") \ \ - develop(intx, MaxTrivialSize, 6, \ + product(intx, MaxTrivialSize, 6, \ "maximum bytecode size of a trivial method to be inlined") \ \ - develop(intx, MinInliningThreshold, 250, \ + product(intx, MinInliningThreshold, 250, \ "min. invocation count a method needs to have to be inlined") \ \ develop(intx, AlignEntryCode, 4, \ diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/runtime/reflection.cpp --- a/src/share/vm/runtime/reflection.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/runtime/reflection.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -1,5 +1,5 @@ /* - * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2010 Sun Microsystems, Inc. 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 @@ -482,6 +482,11 @@ under_host_klass(accessee_ik, accessor)) return true; + // Adapter frames can access anything. + if (MethodHandleCompiler::klass_is_method_handle_adapter_holder(accessor)) + // This is an internal adapter frame from the MethodHandleCompiler. + return true; + if (RelaxAccessControlCheck || (accessor_ik->major_version() < JAVA_1_5_VERSION && accessee_ik->major_version() < JAVA_1_5_VERSION)) { diff -r 09646c4656ca -r c4d722788ed6 src/share/vm/runtime/vframe.cpp --- a/src/share/vm/runtime/vframe.cpp Wed Jan 13 15:45:47 2010 -0800 +++ b/src/share/vm/runtime/vframe.cpp Sat Jan 16 23:51:50 2010 -0800 @@ -1,5 +1,5 @@ /* - * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2010 Sun Microsystems, Inc. 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 @@ -432,6 +432,8 @@ Klass::cast(method()->method_holder()) ->is_subclass_of(SystemDictionary::reflect_MethodAccessorImpl_klass())) { // This is an auxilary frame -- skip it + } else if (method()->is_method_handle_adapter()) { + // This is an internal adapter frame from the MethodHandleCompiler -- skip it } else { // This is non-excluded frame, we need to count it against the depth if (depth-- <= 0) { diff -r 09646c4656ca -r c4d722788ed6 test/compiler/6909839/Test6909839.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/6909839/Test6909839.java Sat Jan 16 23:51:50 2010 -0800 @@ -0,0 +1,282 @@ +/* + * Copyright 2010 Sun Microsystems, Inc. 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +/** + * @test + * @bug 6909839 + * @summary missing unsigned compare cases for some cmoves in sparc.ad + * + * @run main/othervm -XX:+AggressiveOpts -Xbatch Test6909839 + */ + +public class Test6909839 { + public static void main(String[] args) { + testi(); + testi(); + testi(); + testui(); + testui(); + testui(); + testdi(); + testdi(); + testdi(); + testfi(); + testfi(); + testfi(); + + testl(); + testl(); + testl(); + testul(); + testul(); + testul(); + testdl(); + testdl(); + testdl(); + testfl(); + testfl(); + testfl(); + + testf(); + testf(); + testf(); + testuf(); + testuf(); + testuf(); + testdf(); + testdf(); + testdf(); + testff(); + testff(); + testff(); + + testd(); + testd(); + testd(); + testud(); + testud(); + testud(); + testdd(); + testdd(); + testdd(); + testfd(); + testfd(); + testfd(); + + testp(); + testp(); + testp(); + testup(); + testup(); + testup(); + testdp(); + testdp(); + testdp(); + testfp(); + testfp(); + testfp(); + } + + static void testui() { + int total = 0; + for (int i = 0 ; i < 10000; i++) { + int v = i % 4; + total += ((v >= 1 && v < 3) ? 1 : 2); + } + System.out.println(total); + } + + static void testdi() { + int total = 0; + for (int i = 0 ; i < 10000; i++) { + int v = i % 4; + total += (v > 1.0) ? 1 : 2; + } + System.out.println(total); + } + + static void testfi() { + int total = 0; + for (int i = 0 ; i < 10000; i++) { + int v = i % 4; + total += (v > 1.0f) ? 1 : 2; + } + System.out.println(total); + } + + static void testi() { + int total = 0; + for (int i = 0 ; i < 10000; i++) { + total += (i % 4 != 0) ? 1 : 2; + } + System.out.println(total); + } + + static void testul() { + long total = 0; + for (int i = 0 ; i < 10000; i++) { + int v = i % 4; + total += ((v >= 1 && v < 3) ? 1L : 2L); + } + System.out.println(total); + } + + static void testdl() { + long total = 0; + for (int i = 0 ; i < 10000; i++) { + int v = i % 4; + total += (v > 1.0) ? 1L : 2L; + } + System.out.println(total); + } + + static void testfl() { + long total = 0; + for (int i = 0 ; i < 10000; i++) { + int v = i % 4; + total += (v > 1.0f) ? 1L : 2L; + } + System.out.println(total); + } + + static void testl() { + long total = 0; + for (int i = 0 ; i < 10000; i++) { + total += (i % 4 != 0) ? 1L : 2L; + } + System.out.println(total); + } + + static void testuf() { + float total = 0; + for (int i = 0 ; i < 10000; i++) { + int v = i % 4; + total += ((v >= 1 && v < 3) ? 1.0f : 2.0f); + } + System.out.println(total); + } + + static void testdf() { + float total = 0; + for (int i = 0 ; i < 10000; i++) { + int v = i % 4; + total += (v > 0.0) ? 1.0f : 2.0f; + } + System.out.println(total); + } + + static void testff() { + float total = 0; + for (int i = 0 ; i < 10000; i++) { + int v = i % 4; + total += (v > 0.0f) ? 1.0f : 2.0f; + } + System.out.println(total); + } + + static void testf() { + float total = 0; + for (int i = 0 ; i < 10000; i++) { + total += (i % 4 != 0) ? 1.0f : 2.0f; + } + System.out.println(total); + } + + static void testud() { + double total = 0; + for (int i = 0 ; i < 10000; i++) { + int v = i % 4; + total += ((v >= 1 && v < 3) ? 1.0d : 2.0d); + } + System.out.println(total); + } + + static void testdd() { + double total = 0; + for (int i = 0 ; i < 10000; i++) { + int v = i % 4; + total += (v > 1.0) ? 1.0d : 2.0d; + } + System.out.println(total); + } + + static void testfd() { + double total = 0; + for (int i = 0 ; i < 10000; i++) { + int v = i % 4; + total += (v > 1.0f) ? 1.0d : 2.0d; + } + System.out.println(total); + } + + static void testd() { + double total = 0; + for (int i = 0 ; i < 10000; i++) { + total += (i % 4 != 0) ? 1.0d : 2.0d; + } + System.out.println(total); + } + + static void testp() { + Object a = new Object(); + Object b = new Object();; + int total = 0; + for (int i = 0 ; i < 10000; i++) { + total += ((i % 4 != 0) ? a : b).hashCode(); + } + System.out.println(total); + } + + static void testup() { + Object a = new Object(); + Object b = new Object();; + int total = 0; + for (int i = 0 ; i < 10000; i++) { + int v = i % 4; + total += ((v >= 1 && v < 3) ? a : b).hashCode(); + } + System.out.println(total); + } + + static void testdp() { + Object a = new Object(); + Object b = new Object();; + int total = 0; + for (int i = 0 ; i < 10000; i++) { + int v = i % 4; + total += ((v > 1.0) ? a : b).hashCode(); + } + System.out.println(total); + } + static void testfp() { + Object a = new Object(); + Object b = new Object();; + int total = 0; + for (int i = 0 ; i < 10000; i++) { + int v = i % 4; + total += ((v > 1.0f) ? a : b).hashCode(); + } + System.out.println(total); + } +} diff -r 09646c4656ca -r c4d722788ed6 test/compiler/6910484/Test.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/6910484/Test.java Sat Jan 16 23:51:50 2010 -0800 @@ -0,0 +1,50 @@ +/* + * Copyright 2009 SAP. 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6910484 + * @summary incorrect integer optimization (loosing and op-r in a given example) + * + * @run main/othervm -Xbatch Test + */ + +public class Test { + + public static void main(String[] args) { + long iteration = 0; + for(int i = 0; i <11000; i++) { + iteration++; + int result = test(255); + if (result != 112) { + System.out.println("expected 112, but got " + result + " after iteration " + iteration); + System.exit(97); + } + } + } + + private static int test(int x) { + return (x & -32) / 2; + } + +} diff -r 09646c4656ca -r c4d722788ed6 test/compiler/6912517/Test.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/6912517/Test.java Sat Jan 16 23:51:50 2010 -0800 @@ -0,0 +1,113 @@ +/* + * Copyright 2009 D.E. Shaw. 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 + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/** + * @test + * @bug 6912517 + * @summary JIT bug compiles out (and stops running) code that needs to be run. Causes NPE. + * + * @run main/othervm -Xbatch -XX:CompileThreshold=100 -XX:+IgnoreUnrecognizedVMOptions -XX:-UseCompressedOops Test + */ + +/** + * Highlights a bug with the JIT compiler. + * @author Matt Bruce m b r u c e __\at/__ g m a i l DOT c o m + */ +public class Test implements Runnable +{ + private final Thread myThread; + private Thread myInitialThread; + private boolean myShouldCheckThreads; + + /** + * Sets up the running thread, and starts it. + */ + public Test(int id) + { + myThread = new Thread(this); + myThread.setName("Runner: " + id); + myThread.start(); + myShouldCheckThreads = false; + } + + /** + * @param shouldCheckThreads the shouldCheckThreads to set + */ + public void setShouldCheckThreads(boolean shouldCheckThreads) + { + myShouldCheckThreads = shouldCheckThreads; + } + + /** + * Starts up the two threads with enough delay between them for JIT to + * kick in. + * @param args + * @throws InterruptedException + */ + public static void main(String[] args) throws InterruptedException + { + // let this run for a bit, so the "run" below is JITTed. + for (int id = 0; id < 20; id++) { + System.out.println("Starting thread: " + id); + Test bug = new Test(id); + bug.setShouldCheckThreads(true); + Thread.sleep(2500); + } + } + + /** + * @see java.lang.Runnable#run() + */ + public void run() + { + long runNumber = 0; + while (true) { + // run hot for a little while, give JIT time to kick in to this loop. + // then run less hot. + if (runNumber > 15000) { + try { + Thread.sleep(5); + } + catch (InterruptedException e) { + e.printStackTrace(); + } + } + runNumber++; + ensureProperCallingThread(); + } + } + + private void ensureProperCallingThread() + { + // this should never be null. but with the JIT bug, it will be. + // JIT BUG IS HERE ==>>>>> + if (myShouldCheckThreads) { + if (myInitialThread == null) { + myInitialThread = Thread.currentThread(); + } + else if (myInitialThread != Thread.currentThread()) { + System.out.println("Not working: " + myInitialThread.getName()); + } + } + } +}