hotspot/src/share/vm/interpreter/cppInterpreter.cpp
changeset 35214 d86005e0b4c2
parent 25950 b5c40ed1d349
child 35479 62c12ca7a45e
equal deleted inserted replaced
35211:3771329165d4 35214:d86005e0b4c2
     1 /*
     1 /*
     2  * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    22  *
    22  *
    23  */
    23  */
    24 
    24 
    25 #include "precompiled.hpp"
    25 #include "precompiled.hpp"
    26 #include "interpreter/bytecodeInterpreter.hpp"
    26 #include "interpreter/bytecodeInterpreter.hpp"
       
    27 #include "interpreter/cppInterpreterGenerator.hpp"
    27 #include "interpreter/interpreter.hpp"
    28 #include "interpreter/interpreter.hpp"
    28 #include "interpreter/interpreterGenerator.hpp"
       
    29 #include "interpreter/interpreterRuntime.hpp"
    29 #include "interpreter/interpreterRuntime.hpp"
    30 
    30 
    31 #ifdef CC_INTERP
    31 #ifdef CC_INTERP
    32 # define __ _masm->
    32 
       
    33 #ifdef ZERO
       
    34 # include "entry_zero.hpp"
       
    35 #else
       
    36 #error "Only Zero CppInterpreter is supported"
       
    37 #endif
    33 
    38 
    34 void CppInterpreter::initialize() {
    39 void CppInterpreter::initialize() {
    35   if (_code != NULL) return;
    40   if (_code != NULL) return;
    36   AbstractInterpreter::initialize();
    41   AbstractInterpreter::initialize();
    37 
    42 
    40     TraceTime timer("Interpreter generation", TraceStartupTime);
    45     TraceTime timer("Interpreter generation", TraceStartupTime);
    41     int code_size = InterpreterCodeSize;
    46     int code_size = InterpreterCodeSize;
    42     NOT_PRODUCT(code_size *= 4;)  // debug uses extra interpreter code space
    47     NOT_PRODUCT(code_size *= 4;)  // debug uses extra interpreter code space
    43     _code = new StubQueue(new InterpreterCodeletInterface, code_size, NULL,
    48     _code = new StubQueue(new InterpreterCodeletInterface, code_size, NULL,
    44                           "Interpreter");
    49                           "Interpreter");
    45     InterpreterGenerator g(_code);
    50     CppInterpreterGenerator g(_code);
    46     if (PrintInterpreter) print();
    51     if (PrintInterpreter) print();
    47   }
    52   }
    48 
    53 
    49 
    54 
    50   // Allow c++ interpreter to do one initialization now that switches are set, etc.
    55   // Allow c++ interpreter to do one initialization now that switches are set, etc.
    54   else
    59   else
    55     BytecodeInterpreter::run(&start_msg);
    60     BytecodeInterpreter::run(&start_msg);
    56 }
    61 }
    57 
    62 
    58 
    63 
    59 address    CppInterpreter::_tosca_to_stack         [AbstractInterpreter::number_of_result_handlers];
    64 void CppInterpreter::invoke_method(Method* method, address entry_point, TRAPS) {
    60 address    CppInterpreter::_stack_to_stack         [AbstractInterpreter::number_of_result_handlers];
    65   ((ZeroEntry *) entry_point)->invoke(method, THREAD);
    61 address    CppInterpreter::_stack_to_native_abi    [AbstractInterpreter::number_of_result_handlers];
    66 }
       
    67 
       
    68 void CppInterpreter::invoke_osr(Method* method,
       
    69                                 address   entry_point,
       
    70                                 address   osr_buf,
       
    71                                 TRAPS) {
       
    72   ((ZeroEntry *) entry_point)->invoke_osr(method, osr_buf, THREAD);
       
    73 }
       
    74 
    62 
    75 
    63 CppInterpreterGenerator::CppInterpreterGenerator(StubQueue* _code): AbstractInterpreterGenerator(_code) {
    76 CppInterpreterGenerator::CppInterpreterGenerator(StubQueue* _code): AbstractInterpreterGenerator(_code) {
       
    77   generate_all();
    64 }
    78 }
    65 
    79 
    66 static const BasicType types[Interpreter::number_of_result_handlers] = {
    80 static const BasicType types[Interpreter::number_of_result_handlers] = {
    67   T_BOOLEAN,
    81   T_BOOLEAN,
    68   T_CHAR   ,
    82   T_CHAR   ,
    77 };
    91 };
    78 
    92 
    79 void CppInterpreterGenerator::generate_all() {
    93 void CppInterpreterGenerator::generate_all() {
    80   AbstractInterpreterGenerator::generate_all();
    94   AbstractInterpreterGenerator::generate_all();
    81 
    95 
    82   { CodeletMark cm(_masm, "result handlers for native calls");
       
    83     // The various result converter stublets.
       
    84     int is_generated[Interpreter::number_of_result_handlers];
       
    85     memset(is_generated, 0, sizeof(is_generated));
       
    86     int _tosca_to_stack_is_generated[Interpreter::number_of_result_handlers];
       
    87     int _stack_to_stack_is_generated[Interpreter::number_of_result_handlers];
       
    88     int _stack_to_native_abi_is_generated[Interpreter::number_of_result_handlers];
       
    89 
    96 
    90     memset(_tosca_to_stack_is_generated, 0, sizeof(_tosca_to_stack_is_generated));
    97 #define method_entry(kind) Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind)
    91     memset(_stack_to_stack_is_generated, 0, sizeof(_stack_to_stack_is_generated));
       
    92     memset(_stack_to_native_abi_is_generated, 0, sizeof(_stack_to_native_abi_is_generated));
       
    93     for (int i = 0; i < Interpreter::number_of_result_handlers; i++) {
       
    94       BasicType type = types[i];
       
    95       if (!is_generated[Interpreter::BasicType_as_index(type)]++) {
       
    96         Interpreter::_native_abi_to_tosca[Interpreter::BasicType_as_index(type)] = generate_result_handler_for(type);
       
    97       }
       
    98       if (!_tosca_to_stack_is_generated[Interpreter::BasicType_as_index(type)]++) {
       
    99         Interpreter::_tosca_to_stack[Interpreter::BasicType_as_index(type)] = generate_tosca_to_stack_converter(type);
       
   100       }
       
   101       if (!_stack_to_stack_is_generated[Interpreter::BasicType_as_index(type)]++) {
       
   102         Interpreter::_stack_to_stack[Interpreter::BasicType_as_index(type)] = generate_stack_to_stack_converter(type);
       
   103       }
       
   104       if (!_stack_to_native_abi_is_generated[Interpreter::BasicType_as_index(type)]++) {
       
   105         Interpreter::_stack_to_native_abi[Interpreter::BasicType_as_index(type)] = generate_stack_to_native_abi_converter(type);
       
   106       }
       
   107     }
       
   108   }
       
   109 
       
   110 
       
   111 #define method_entry(kind) Interpreter::_entry_table[Interpreter::kind] = ((InterpreterGenerator*)this)->generate_method_entry(Interpreter::kind)
       
   112 
    98 
   113   { CodeletMark cm(_masm, "(kind = frame_manager)");
    99   { CodeletMark cm(_masm, "(kind = frame_manager)");
   114     // all non-native method kinds
   100     // all non-native method kinds
   115     method_entry(zerolocals);
   101     method_entry(zerolocals);
   116     method_entry(zerolocals_synchronized);
   102     method_entry(zerolocals_synchronized);
   136     Interpreter::_native_entry_end = Interpreter::code()->code_end();
   122     Interpreter::_native_entry_end = Interpreter::code()->code_end();
   137   }
   123   }
   138 
   124 
   139 
   125 
   140 #undef method_entry
   126 #undef method_entry
   141 
       
   142 }
   127 }
   143 
   128 
       
   129 InterpreterCodelet* CppInterpreter::codelet_containing(address pc) {
       
   130   // FIXME: I'm pretty sure _code is null and this is never called, which is why it's copied.
       
   131   return (InterpreterCodelet*)_code->stub_containing(pc);
       
   132 }
       
   133 
       
   134 // Generate method entries
       
   135 address CppInterpreterGenerator::generate_method_entry(
       
   136                                         AbstractInterpreter::MethodKind kind) {
       
   137   // determine code generation flags
       
   138   bool native = false;
       
   139   bool synchronized = false;
       
   140   address entry_point = NULL;
       
   141 
       
   142   switch (kind) {
       
   143   case Interpreter::zerolocals             :                                          break;
       
   144   case Interpreter::zerolocals_synchronized:                synchronized = true;      break;
       
   145   case Interpreter::native                 : native = true;                           break;
       
   146   case Interpreter::native_synchronized    : native = true; synchronized = true;      break;
       
   147   case Interpreter::empty                  : entry_point = generate_empty_entry();    break;
       
   148   case Interpreter::accessor               : entry_point = generate_accessor_entry(); break;
       
   149   case Interpreter::abstract               : entry_point = generate_abstract_entry(); break;
       
   150 
       
   151   case Interpreter::java_lang_math_sin     : // fall thru
       
   152   case Interpreter::java_lang_math_cos     : // fall thru
       
   153   case Interpreter::java_lang_math_tan     : // fall thru
       
   154   case Interpreter::java_lang_math_abs     : // fall thru
       
   155   case Interpreter::java_lang_math_log     : // fall thru
       
   156   case Interpreter::java_lang_math_log10   : // fall thru
       
   157   case Interpreter::java_lang_math_sqrt    : // fall thru
       
   158   case Interpreter::java_lang_math_pow     : // fall thru
       
   159   case Interpreter::java_lang_math_exp     : entry_point = generate_math_entry(kind);      break;
       
   160   case Interpreter::java_lang_ref_reference_get
       
   161                                            : entry_point = generate_Reference_get_entry(); break;
       
   162   default:
       
   163     fatal("unexpected method kind: %d", kind);
       
   164     break;
       
   165   }
       
   166 
       
   167   if (entry_point) {
       
   168     return entry_point;
       
   169   }
       
   170 
       
   171   // We expect the normal and native entry points to be generated first so we can reuse them.
       
   172   if (native) {
       
   173     entry_point = Interpreter::entry_for_kind(synchronized ? Interpreter::native_synchronized : Interpreter::native);
       
   174     if (entry_point == NULL) {
       
   175       entry_point = generate_native_entry(synchronized);
       
   176     }
       
   177   } else {
       
   178     entry_point = Interpreter::entry_for_kind(synchronized ? Interpreter::zerolocals_synchronized : Interpreter::zerolocals);
       
   179     if (entry_point == NULL) {
       
   180       entry_point = generate_normal_entry(synchronized);
       
   181     }
       
   182   }
       
   183 
       
   184   return entry_point;
       
   185 }
   144 #endif // CC_INTERP
   186 #endif // CC_INTERP