1.1 --- a/src/share/vm/interpreter/templateInterpreter.cpp Wed Oct 23 19:22:28 2013 +0000 1.2 +++ b/src/share/vm/interpreter/templateInterpreter.cpp Thu Oct 24 16:23:07 2013 -0700 1.3 @@ -184,8 +184,9 @@ 1.4 EntryPoint TemplateInterpreter::_continuation_entry; 1.5 EntryPoint TemplateInterpreter::_safept_entry; 1.6 1.7 -address TemplateInterpreter::_return_3_addrs_by_index[TemplateInterpreter::number_of_return_addrs]; 1.8 -address TemplateInterpreter::_return_5_addrs_by_index[TemplateInterpreter::number_of_return_addrs]; 1.9 +address TemplateInterpreter::_invoke_return_entry[TemplateInterpreter::number_of_return_addrs]; 1.10 +address TemplateInterpreter::_invokeinterface_return_entry[TemplateInterpreter::number_of_return_addrs]; 1.11 +address TemplateInterpreter::_invokedynamic_return_entry[TemplateInterpreter::number_of_return_addrs]; 1.12 1.13 DispatchTable TemplateInterpreter::_active_table; 1.14 DispatchTable TemplateInterpreter::_normal_table; 1.15 @@ -237,22 +238,37 @@ 1.16 #endif // !PRODUCT 1.17 1.18 { CodeletMark cm(_masm, "return entry points"); 1.19 + const int index_size = sizeof(u2); 1.20 for (int i = 0; i < Interpreter::number_of_return_entries; i++) { 1.21 Interpreter::_return_entry[i] = 1.22 EntryPoint( 1.23 - generate_return_entry_for(itos, i), 1.24 - generate_return_entry_for(itos, i), 1.25 - generate_return_entry_for(itos, i), 1.26 - generate_return_entry_for(atos, i), 1.27 - generate_return_entry_for(itos, i), 1.28 - generate_return_entry_for(ltos, i), 1.29 - generate_return_entry_for(ftos, i), 1.30 - generate_return_entry_for(dtos, i), 1.31 - generate_return_entry_for(vtos, i) 1.32 + generate_return_entry_for(itos, i, index_size), 1.33 + generate_return_entry_for(itos, i, index_size), 1.34 + generate_return_entry_for(itos, i, index_size), 1.35 + generate_return_entry_for(atos, i, index_size), 1.36 + generate_return_entry_for(itos, i, index_size), 1.37 + generate_return_entry_for(ltos, i, index_size), 1.38 + generate_return_entry_for(ftos, i, index_size), 1.39 + generate_return_entry_for(dtos, i, index_size), 1.40 + generate_return_entry_for(vtos, i, index_size) 1.41 ); 1.42 } 1.43 } 1.44 1.45 + { CodeletMark cm(_masm, "invoke return entry points"); 1.46 + const TosState states[] = {itos, itos, itos, itos, ltos, ftos, dtos, atos, vtos}; 1.47 + const int invoke_length = Bytecodes::length_for(Bytecodes::_invokestatic); 1.48 + const int invokeinterface_length = Bytecodes::length_for(Bytecodes::_invokeinterface); 1.49 + const int invokedynamic_length = Bytecodes::length_for(Bytecodes::_invokedynamic); 1.50 + 1.51 + for (int i = 0; i < Interpreter::number_of_return_addrs; i++) { 1.52 + TosState state = states[i]; 1.53 + Interpreter::_invoke_return_entry[i] = generate_return_entry_for(state, invoke_length, sizeof(u2)); 1.54 + Interpreter::_invokeinterface_return_entry[i] = generate_return_entry_for(state, invokeinterface_length, sizeof(u2)); 1.55 + Interpreter::_invokedynamic_return_entry[i] = generate_return_entry_for(state, invokedynamic_length, sizeof(u4)); 1.56 + } 1.57 + } 1.58 + 1.59 { CodeletMark cm(_masm, "earlyret entry points"); 1.60 Interpreter::_earlyret_entry = 1.61 EntryPoint( 1.62 @@ -298,13 +314,6 @@ 1.63 } 1.64 } 1.65 1.66 - for (int j = 0; j < number_of_states; j++) { 1.67 - const TosState states[] = {btos, ctos, stos, itos, ltos, ftos, dtos, atos, vtos}; 1.68 - int index = Interpreter::TosState_as_index(states[j]); 1.69 - Interpreter::_return_3_addrs_by_index[index] = Interpreter::return_entry(states[j], 3); 1.70 - Interpreter::_return_5_addrs_by_index[index] = Interpreter::return_entry(states[j], 5); 1.71 - } 1.72 - 1.73 { CodeletMark cm(_masm, "continuation entry points"); 1.74 Interpreter::_continuation_entry = 1.75 EntryPoint( 1.76 @@ -534,9 +543,46 @@ 1.77 //------------------------------------------------------------------------------------------------------------------------ 1.78 // Entry points 1.79 1.80 -address TemplateInterpreter::return_entry(TosState state, int length) { 1.81 +/** 1.82 + * Returns the return entry table for the given invoke bytecode. 1.83 + */ 1.84 +address* TemplateInterpreter::invoke_return_entry_table_for(Bytecodes::Code code) { 1.85 + switch (code) { 1.86 + case Bytecodes::_invokestatic: 1.87 + case Bytecodes::_invokespecial: 1.88 + case Bytecodes::_invokevirtual: 1.89 + case Bytecodes::_invokehandle: 1.90 + return Interpreter::invoke_return_entry_table(); 1.91 + case Bytecodes::_invokeinterface: 1.92 + return Interpreter::invokeinterface_return_entry_table(); 1.93 + case Bytecodes::_invokedynamic: 1.94 + return Interpreter::invokedynamic_return_entry_table(); 1.95 + default: 1.96 + fatal(err_msg("invalid bytecode: %s", Bytecodes::name(code))); 1.97 + return NULL; 1.98 + } 1.99 +} 1.100 + 1.101 +/** 1.102 + * Returns the return entry address for the given top-of-stack state and bytecode. 1.103 + */ 1.104 +address TemplateInterpreter::return_entry(TosState state, int length, Bytecodes::Code code) { 1.105 guarantee(0 <= length && length < Interpreter::number_of_return_entries, "illegal length"); 1.106 - return _return_entry[length].entry(state); 1.107 + const int index = TosState_as_index(state); 1.108 + switch (code) { 1.109 + case Bytecodes::_invokestatic: 1.110 + case Bytecodes::_invokespecial: 1.111 + case Bytecodes::_invokevirtual: 1.112 + case Bytecodes::_invokehandle: 1.113 + return _invoke_return_entry[index]; 1.114 + case Bytecodes::_invokeinterface: 1.115 + return _invokeinterface_return_entry[index]; 1.116 + case Bytecodes::_invokedynamic: 1.117 + return _invokedynamic_return_entry[index]; 1.118 + default: 1.119 + assert(!Bytecodes::is_invoke(code), err_msg("invoke instructions should be handled separately: %s", Bytecodes::name(code))); 1.120 + return _return_entry[length].entry(state); 1.121 + } 1.122 } 1.123 1.124