diff options
author | jrose <none@none> | 2009-04-08 10:56:49 -0700 |
---|---|---|
committer | jrose <none@none> | 2009-04-08 10:56:49 -0700 |
commit | 6094e1a45d0a3e8ebc1abeb2decefac21fda1d17 (patch) | |
tree | b7300e43ab49aea0527e81c61bf1232f7a2c6567 /src/cpu/sparc | |
parent | 13e9fa5459a55b69b581abbf0377faf539d46849 (diff) | |
download | jdk8u_hotspot-6094e1a45d0a3e8ebc1abeb2decefac21fda1d17.tar.gz |
6655638: dynamic languages need method handles
Summary: initial implementation, with known omissions (x86/64, sparc, compiler optim., c-oops, C++ interp.)
Reviewed-by: kvn, twisti, never
Diffstat (limited to 'src/cpu/sparc')
-rw-r--r-- | src/cpu/sparc/vm/assembler_sparc.cpp | 52 | ||||
-rw-r--r-- | src/cpu/sparc/vm/assembler_sparc.hpp | 25 | ||||
-rw-r--r-- | src/cpu/sparc/vm/assembler_sparc.inline.hpp | 9 | ||||
-rw-r--r-- | src/cpu/sparc/vm/cppInterpreter_sparc.cpp | 11 | ||||
-rw-r--r-- | src/cpu/sparc/vm/interpreterGenerator_sparc.hpp | 3 | ||||
-rw-r--r-- | src/cpu/sparc/vm/interpreter_sparc.cpp | 16 | ||||
-rw-r--r-- | src/cpu/sparc/vm/methodHandles_sparc.cpp | 70 | ||||
-rw-r--r-- | src/cpu/sparc/vm/register_definitions_sparc.cpp | 4 | ||||
-rw-r--r-- | src/cpu/sparc/vm/sharedRuntime_sparc.cpp | 12 | ||||
-rw-r--r-- | src/cpu/sparc/vm/templateInterpreter_sparc.cpp | 22 |
10 files changed, 209 insertions, 15 deletions
diff --git a/src/cpu/sparc/vm/assembler_sparc.cpp b/src/cpu/sparc/vm/assembler_sparc.cpp index 597a91ae3..d36caf55f 100644 --- a/src/cpu/sparc/vm/assembler_sparc.cpp +++ b/src/cpu/sparc/vm/assembler_sparc.cpp @@ -3029,6 +3029,58 @@ void MacroAssembler::check_klass_subtype_slow_path(Register sub_klass, +void MacroAssembler::check_method_handle_type(Register mtype_reg, Register mh_reg, + Register temp_reg, + Label& wrong_method_type) { + assert_different_registers(mtype_reg, mh_reg, temp_reg); + // compare method type against that of the receiver + RegisterOrConstant mhtype_offset = delayed_value(java_dyn_MethodHandle::type_offset_in_bytes, temp_reg); + ld_ptr(mh_reg, mhtype_offset, temp_reg); + cmp(temp_reg, mtype_reg); + br(Assembler::notEqual, false, Assembler::pn, wrong_method_type); + delayed()->nop(); +} + + +void MacroAssembler::jump_to_method_handle_entry(Register mh_reg, Register temp_reg) { + assert(mh_reg == G3_method_handle, "caller must put MH object in G3"); + assert_different_registers(mh_reg, temp_reg); + + // pick out the interpreted side of the handler + ld_ptr(mh_reg, delayed_value(java_dyn_MethodHandle::vmentry_offset_in_bytes, temp_reg), temp_reg); + + // off we go... + ld_ptr(temp_reg, MethodHandleEntry::from_interpreted_entry_offset_in_bytes(), temp_reg); + jmp(temp_reg, 0); + + // for the various stubs which take control at this point, + // see MethodHandles::generate_method_handle_stub + + // (Can any caller use this delay slot? If so, add an option for supression.) + delayed()->nop(); +} + +RegisterOrConstant MacroAssembler::argument_offset(RegisterOrConstant arg_slot, + int extra_slot_offset) { + // cf. TemplateTable::prepare_invoke(), if (load_receiver). + int stackElementSize = Interpreter::stackElementWords() * wordSize; + int offset = Interpreter::expr_offset_in_bytes(extra_slot_offset+0); + int offset1 = Interpreter::expr_offset_in_bytes(extra_slot_offset+1); + assert(offset1 - offset == stackElementSize, "correct arithmetic"); + if (arg_slot.is_constant()) { + offset += arg_slot.as_constant() * stackElementSize; + return offset; + } else { + Register temp = arg_slot.as_register(); + sll_ptr(temp, exact_log2(stackElementSize), temp); + if (offset != 0) + add(temp, offset, temp); + return temp; + } +} + + + void MacroAssembler::biased_locking_enter(Register obj_reg, Register mark_reg, Register temp_reg, Label& done, Label* slow_case, diff --git a/src/cpu/sparc/vm/assembler_sparc.hpp b/src/cpu/sparc/vm/assembler_sparc.hpp index 5c756c4b6..cfd935987 100644 --- a/src/cpu/sparc/vm/assembler_sparc.hpp +++ b/src/cpu/sparc/vm/assembler_sparc.hpp @@ -84,6 +84,10 @@ REGISTER_DECLARATION(Register, G4_scratch , G4); REGISTER_DECLARATION(Register, Gtemp , G5); +// JSR 292 fixed register usages: +REGISTER_DECLARATION(Register, G5_method_type , G5); +REGISTER_DECLARATION(Register, G3_method_handle , G3); + // The compiler requires that G5_megamorphic_method is G5_inline_cache_klass, // because a single patchable "set" instruction (NativeMovConstReg, // or NativeMovConstPatching for compiler1) instruction @@ -91,9 +95,13 @@ REGISTER_DECLARATION(Register, Gtemp , G5); // call site is an inline cache or is megamorphic. See the function // CompiledIC::set_to_megamorphic. // -// On the other hand, G5_inline_cache_klass must differ from G5_method, -// because both registers are needed for an inline cache that calls -// an interpreted method. +// If a inline cache targets an interpreted method, then the +// G5 register will be used twice during the call. First, +// the call site will be patched to load a compiledICHolder +// into G5. (This is an ordered pair of ic_klass, method.) +// The c2i adapter will first check the ic_klass, then load +// G5_method with the method part of the pair just before +// jumping into the interpreter. // // Note that G5_method is only the method-self for the interpreter, // and is logically unrelated to G5_megamorphic_method. @@ -1931,6 +1939,7 @@ class MacroAssembler: public Assembler { inline void store_ptr_contents( Register s, Address& a, int offset = 0 ); inline void jumpl_to( Address& a, Register d, int offset = 0 ); inline void jump_to( Address& a, int offset = 0 ); + inline void jump_indirect_to( Address& a, Register temp, int ld_offset = 0, int jmp_offset = 0 ); // ring buffer traceable jumps @@ -2366,6 +2375,16 @@ class MacroAssembler: public Assembler { Register temp2_reg, Label& L_success); + // method handles (JSR 292) + void check_method_handle_type(Register mtype_reg, Register mh_reg, + Register temp_reg, + Label& wrong_method_type); + void jump_to_method_handle_entry(Register mh_reg, Register temp_reg); + // offset relative to Gargs of argument at tos[arg_slot]. + // (arg_slot == 0 means the last argument, not the first). + RegisterOrConstant argument_offset(RegisterOrConstant arg_slot, + int extra_slot_offset = 0); + // Stack overflow checking diff --git a/src/cpu/sparc/vm/assembler_sparc.inline.hpp b/src/cpu/sparc/vm/assembler_sparc.inline.hpp index d9053f7f6..692c8650b 100644 --- a/src/cpu/sparc/vm/assembler_sparc.inline.hpp +++ b/src/cpu/sparc/vm/assembler_sparc.inline.hpp @@ -671,6 +671,15 @@ inline void MacroAssembler::jump_to( Address& a, int offset ) { } +inline void MacroAssembler::jump_indirect_to( Address& a, Register temp, + int ld_offset, int jmp_offset ) { + assert_not_delayed(); + //sethi(a); // sethi is caller responsibility for this one + ld_ptr(a, temp, ld_offset); + jmp(temp, jmp_offset); +} + + inline void MacroAssembler::set_oop( jobject obj, Register d ) { set_oop(allocate_oop_address(obj, d)); } diff --git a/src/cpu/sparc/vm/cppInterpreter_sparc.cpp b/src/cpu/sparc/vm/cppInterpreter_sparc.cpp index f2d6486f8..c89d6e169 100644 --- a/src/cpu/sparc/vm/cppInterpreter_sparc.cpp +++ b/src/cpu/sparc/vm/cppInterpreter_sparc.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2007-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2007-2009 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 @@ -1017,6 +1017,7 @@ void CppInterpreterGenerator::generate_compute_interpreter_state(const Register const int slop_factor = 2*wordSize; const int fixed_size = ((sizeof(BytecodeInterpreter) + slop_factor) >> LogBytesPerWord) + // what is the slop factor? + //6815692//methodOopDesc::extra_stack_words() + // extra push slots for MH adapters frame::memory_parameter_word_sp_offset + // register save area + param window (native ? frame::interpreter_frame_extra_outgoing_argument_words : 0); // JNI, class @@ -1163,6 +1164,9 @@ void CppInterpreterGenerator::generate_compute_interpreter_state(const Register __ st_ptr(O2, XXX_STATE(_stack)); // PREPUSH __ lduh(max_stack, O3); // Full size expression stack + guarantee(!EnableMethodHandles, "no support yet for java.dyn.MethodHandle"); //6815692 + //6815692//if (EnableMethodHandles) + //6815692// __ inc(O3, methodOopDesc::extra_stack_entries()); __ sll(O3, LogBytesPerWord, O3); __ sub(O2, O3, O3); // __ sub(O3, wordSize, O3); // so prepush doesn't look out of bounds @@ -2017,7 +2021,9 @@ static int size_activation_helper(int callee_extra_locals, int max_stack, int mo const int fixed_size = sizeof(BytecodeInterpreter)/wordSize + // interpreter state object frame::memory_parameter_word_sp_offset; // register save area + param window + const int extra_stack = 0; //6815692//methodOopDesc::extra_stack_entries(); return (round_to(max_stack + + extra_stack + slop_factor + fixed_size + monitor_size + @@ -2104,7 +2110,8 @@ void BytecodeInterpreter::layout_interpreterState(interpreterState to_fill, // Need +1 here because stack_base points to the word just above the first expr stack entry // and stack_limit is supposed to point to the word just below the last expr stack entry. // See generate_compute_interpreter_state. - to_fill->_stack_limit = stack_base - (method->max_stack() + 1); + int extra_stack = 0; //6815692//methodOopDesc::extra_stack_entries(); + to_fill->_stack_limit = stack_base - (method->max_stack() + 1 + extra_stack); to_fill->_monitor_base = (BasicObjectLock*) monitor_base; // sparc specific diff --git a/src/cpu/sparc/vm/interpreterGenerator_sparc.hpp b/src/cpu/sparc/vm/interpreterGenerator_sparc.hpp index 3352d2abd..3ed9bc471 100644 --- a/src/cpu/sparc/vm/interpreterGenerator_sparc.hpp +++ b/src/cpu/sparc/vm/interpreterGenerator_sparc.hpp @@ -1,5 +1,5 @@ /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2009 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 @@ -29,6 +29,7 @@ address generate_normal_entry(bool synchronized); address generate_native_entry(bool synchronized); address generate_abstract_entry(void); + address generate_method_handle_entry(void); address generate_math_entry(AbstractInterpreter::MethodKind kind); address generate_empty_entry(void); address generate_accessor_entry(void); diff --git a/src/cpu/sparc/vm/interpreter_sparc.cpp b/src/cpu/sparc/vm/interpreter_sparc.cpp index 898d37060..9f0dd7166 100644 --- a/src/cpu/sparc/vm/interpreter_sparc.cpp +++ b/src/cpu/sparc/vm/interpreter_sparc.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2009 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 @@ -235,6 +235,19 @@ address InterpreterGenerator::generate_abstract_entry(void) { } + +// Method handle invoker +// Dispatch a method of the form java.dyn.MethodHandles::invoke(...) +address InterpreterGenerator::generate_method_handle_entry(void) { + if (!EnableMethodHandles) { + return generate_abstract_entry(); + } + return generate_abstract_entry(); //6815692// +} + + + + //---------------------------------------------------------------------------------------------------- // Entry points & stack frame layout // @@ -364,6 +377,7 @@ address AbstractInterpreterGenerator::generate_method_entry(AbstractInterpreter: case Interpreter::empty : entry_point = ((InterpreterGenerator*)this)->generate_empty_entry(); break; case Interpreter::accessor : entry_point = ((InterpreterGenerator*)this)->generate_accessor_entry(); break; case Interpreter::abstract : entry_point = ((InterpreterGenerator*)this)->generate_abstract_entry(); break; + case Interpreter::method_handle : entry_point = ((InterpreterGenerator*)this)->generate_method_handle_entry(); break; case Interpreter::java_lang_math_sin : break; case Interpreter::java_lang_math_cos : break; case Interpreter::java_lang_math_tan : break; diff --git a/src/cpu/sparc/vm/methodHandles_sparc.cpp b/src/cpu/sparc/vm/methodHandles_sparc.cpp new file mode 100644 index 000000000..dd40006e1 --- /dev/null +++ b/src/cpu/sparc/vm/methodHandles_sparc.cpp @@ -0,0 +1,70 @@ +/* + * Copyright 1997-2009 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. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_methodHandles_sparc.cpp.incl" + +#define __ _masm-> + +address MethodHandleEntry::start_compiled_entry(MacroAssembler* _masm, + address interpreted_entry) { + __ align(wordSize); + address target = __ pc() + sizeof(Data); + while (__ pc() < target) { + __ nop(); + __ align(wordSize); + } + + MethodHandleEntry* me = (MethodHandleEntry*) __ pc(); + me->set_end_address(__ pc()); // set a temporary end_address + me->set_from_interpreted_entry(interpreted_entry); + me->set_type_checking_entry(NULL); + + return (address) me; +} + +MethodHandleEntry* MethodHandleEntry::finish_compiled_entry(MacroAssembler* _masm, + address start_addr) { + MethodHandleEntry* me = (MethodHandleEntry*) start_addr; + assert(me->end_address() == start_addr, "valid ME"); + + // Fill in the real end_address: + __ align(wordSize); + me->set_end_address(__ pc()); + + return me; +} + + +// Code generation +address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* _masm) { + ShouldNotReachHere(); //NYI, 6815692 + return NULL; +} + +// Generate an "entry" field for a method handle. +// This determines how the method handle will respond to calls. +void MethodHandles::generate_method_handle_stub(MacroAssembler* _masm, MethodHandles::EntryKind ek) { + ShouldNotReachHere(); //NYI, 6815692 +} diff --git a/src/cpu/sparc/vm/register_definitions_sparc.cpp b/src/cpu/sparc/vm/register_definitions_sparc.cpp index d3e805570..410f62aeb 100644 --- a/src/cpu/sparc/vm/register_definitions_sparc.cpp +++ b/src/cpu/sparc/vm/register_definitions_sparc.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2002-2009 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 @@ -142,6 +142,8 @@ REGISTER_DEFINITION(Register, G1_scratch); REGISTER_DEFINITION(Register, G3_scratch); REGISTER_DEFINITION(Register, G4_scratch); REGISTER_DEFINITION(Register, Gtemp); +REGISTER_DEFINITION(Register, G5_method_type); +REGISTER_DEFINITION(Register, G3_method_handle); REGISTER_DEFINITION(Register, Lentry_args); #ifdef CC_INTERP diff --git a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp index 5804fbbfe..e2bd04436 100644 --- a/src/cpu/sparc/vm/sharedRuntime_sparc.cpp +++ b/src/cpu/sparc/vm/sharedRuntime_sparc.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2003-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2009 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 @@ -937,12 +937,12 @@ void AdapterGenerator::gen_i2c_adapter( // Inputs: // G2_thread - TLS // G5_method - Method oop - // O0 - Flag telling us to restore SP from O5 - // O4_args - Pointer to interpreter's args - // O5 - Caller's saved SP, to be restored if needed + // G4 (Gargs) - Pointer to interpreter's args + // O0..O4 - free for scratch + // O5_savedSP - Caller's saved SP, to be restored if needed // O6 - Current SP! // O7 - Valid return address - // L0-L7, I0-I7 - Caller's temps (no frame pushed yet) + // L0-L7, I0-I7 - Caller's temps (no frame pushed yet) // Outputs: // G2_thread - TLS @@ -954,7 +954,7 @@ void AdapterGenerator::gen_i2c_adapter( // F0-F7 - more outgoing args - // O4 is about to get loaded up with compiled callee's args + // Gargs is the incoming argument base, and also an outgoing argument. __ sub(Gargs, BytesPerWord, Gargs); #ifdef ASSERT diff --git a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp index 090242c17..6cbcf9272 100644 --- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp +++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp @@ -1,5 +1,5 @@ /* - * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2009 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 @@ -108,6 +108,24 @@ address TemplateInterpreterGenerator::generate_ClassCastException_handler() { } +// Arguments are: required type in G5_method_type, and +// failing object (or NULL) in G3_method_handle. +address TemplateInterpreterGenerator::generate_WrongMethodType_handler() { + address entry = __ pc(); + // expression stack must be empty before entering the VM if an exception + // happened + __ empty_expression_stack(); + // load exception object + __ call_VM(Oexception, + CAST_FROM_FN_PTR(address, + InterpreterRuntime::throw_WrongMethodTypeException), + G5_method_type, // required + G3_method_handle); // actual + __ should_not_reach_here(); + return entry; +} + + address TemplateInterpreterGenerator::generate_ArrayIndexOutOfBounds_handler(const char* name) { address entry = __ pc(); // expression stack must be empty before entering the VM if an exception happened @@ -448,6 +466,7 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) { const int extra_space = rounded_vm_local_words + // frame local scratch space + //6815692//methodOopDesc::extra_stack_words() + // extra push slots for MH adapters frame::memory_parameter_word_sp_offset + // register save area (native_call ? frame::interpreter_frame_extra_outgoing_argument_words : 0); @@ -1447,6 +1466,7 @@ static int size_activation_helper(int callee_extra_locals, int max_stack, int mo round_to(callee_extra_locals * Interpreter::stackElementWords(), WordsPerLong); const int max_stack_words = max_stack * Interpreter::stackElementWords(); return (round_to((max_stack_words + //6815692//+ methodOopDesc::extra_stack_words() + rounded_vm_local_words + frame::memory_parameter_word_sp_offset), WordsPerLong) // already rounded |