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 |