annotate src/share/vm/interpreter/templateInterpreter.cpp @ 9126:bc26f978b0ce

HotSpotResolvedObjectType: implement hasFinalizeSubclass() correctly don't use the (wrong) cached value, but ask the runtime on each request. Fixes regression on xml.* benchmarks @ specjvm2008. The problem was: After the constructor of Object was deoptimized due to an assumption violation, it was recompiled again after some time. However, on recompilation, the value of hasFinalizeSubclass for the class was not updated and it was compiled again with a, now wrong, assumption, which then triggers deoptimization again. This was repeated until it hit the recompilation limit (defined by PerMethodRecompilationCutoff), and therefore only executed by the interpreter from now on, causing the performance regression.
author Bernhard Urban <bernhard.urban@jku.at>
date Mon, 15 Apr 2013 19:54:58 +0200
parents c6a1ffc707ff
children 6b0fd0964b87
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
7066
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
1 /*
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
4 *
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
7 * published by the Free Software Foundation.
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
8 *
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
13 * accompanied this code).
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
14 *
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
15 * You should have received a copy of the GNU General Public License version
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
18 *
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
21 * questions.
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
22 *
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
23 */
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
24
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
25 #include "precompiled.hpp"
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
26 #include "interpreter/interpreter.hpp"
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
27 #include "interpreter/interpreterGenerator.hpp"
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
28 #include "interpreter/interpreterRuntime.hpp"
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
29 #include "interpreter/templateTable.hpp"
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
30
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
31 #ifndef CC_INTERP
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
32
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
33 # define __ _masm->
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
34
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
35 void TemplateInterpreter::initialize() {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
36 if (_code != NULL) return;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
37 // assertions
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
38 assert((int)Bytecodes::number_of_codes <= (int)DispatchTable::length,
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
39 "dispatch table too small");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
40
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
41 AbstractInterpreter::initialize();
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
42
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
43 TemplateTable::initialize();
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
44
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
45 // generate interpreter
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
46 { ResourceMark rm;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
47 TraceTime timer("Interpreter generation", TraceStartupTime);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
48 int code_size = InterpreterCodeSize;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
49 NOT_PRODUCT(code_size *= 4;) // debug uses extra interpreter code space
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
50 _code = new StubQueue(new InterpreterCodeletInterface, code_size, NULL,
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
51 "Interpreter");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
52 InterpreterGenerator g(_code);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
53 if (PrintInterpreter) print();
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
54 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
55
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
56 // initialize dispatch table
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
57 _active_table = _normal_table;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
58 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
59
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
60 //------------------------------------------------------------------------------------------------------------------------
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
61 // Implementation of EntryPoint
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
62
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
63 EntryPoint::EntryPoint() {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
64 assert(number_of_states == 9, "check the code below");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
65 _entry[btos] = NULL;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
66 _entry[ctos] = NULL;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
67 _entry[stos] = NULL;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
68 _entry[atos] = NULL;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
69 _entry[itos] = NULL;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
70 _entry[ltos] = NULL;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
71 _entry[ftos] = NULL;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
72 _entry[dtos] = NULL;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
73 _entry[vtos] = NULL;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
74 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
75
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
76
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
77 EntryPoint::EntryPoint(address bentry, address centry, address sentry, address aentry, address ientry, address lentry, address fentry, address dentry, address ventry) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
78 assert(number_of_states == 9, "check the code below");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
79 _entry[btos] = bentry;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
80 _entry[ctos] = centry;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
81 _entry[stos] = sentry;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
82 _entry[atos] = aentry;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
83 _entry[itos] = ientry;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
84 _entry[ltos] = lentry;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
85 _entry[ftos] = fentry;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
86 _entry[dtos] = dentry;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
87 _entry[vtos] = ventry;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
88 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
89
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
90
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
91 void EntryPoint::set_entry(TosState state, address entry) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
92 assert(0 <= state && state < number_of_states, "state out of bounds");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
93 _entry[state] = entry;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
94 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
95
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
96
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
97 address EntryPoint::entry(TosState state) const {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
98 assert(0 <= state && state < number_of_states, "state out of bounds");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
99 return _entry[state];
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
100 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
101
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
102
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
103 void EntryPoint::print() {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
104 tty->print("[");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
105 for (int i = 0; i < number_of_states; i++) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
106 if (i > 0) tty->print(", ");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
107 tty->print(INTPTR_FORMAT, _entry[i]);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
108 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
109 tty->print("]");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
110 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
111
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
112
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
113 bool EntryPoint::operator == (const EntryPoint& y) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
114 int i = number_of_states;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
115 while (i-- > 0) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
116 if (_entry[i] != y._entry[i]) return false;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
117 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
118 return true;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
119 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
120
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
121
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
122 //------------------------------------------------------------------------------------------------------------------------
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
123 // Implementation of DispatchTable
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
124
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
125 EntryPoint DispatchTable::entry(int i) const {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
126 assert(0 <= i && i < length, "index out of bounds");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
127 return
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
128 EntryPoint(
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
129 _table[btos][i],
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
130 _table[ctos][i],
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
131 _table[stos][i],
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
132 _table[atos][i],
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
133 _table[itos][i],
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
134 _table[ltos][i],
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
135 _table[ftos][i],
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
136 _table[dtos][i],
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
137 _table[vtos][i]
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
138 );
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
139 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
140
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
141
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
142 void DispatchTable::set_entry(int i, EntryPoint& entry) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
143 assert(0 <= i && i < length, "index out of bounds");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
144 assert(number_of_states == 9, "check the code below");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
145 _table[btos][i] = entry.entry(btos);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
146 _table[ctos][i] = entry.entry(ctos);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
147 _table[stos][i] = entry.entry(stos);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
148 _table[atos][i] = entry.entry(atos);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
149 _table[itos][i] = entry.entry(itos);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
150 _table[ltos][i] = entry.entry(ltos);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
151 _table[ftos][i] = entry.entry(ftos);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
152 _table[dtos][i] = entry.entry(dtos);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
153 _table[vtos][i] = entry.entry(vtos);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
154 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
155
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
156
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
157 bool DispatchTable::operator == (DispatchTable& y) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
158 int i = length;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
159 while (i-- > 0) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
160 EntryPoint t = y.entry(i); // for compiler compatibility (BugId 4150096)
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
161 if (!(entry(i) == t)) return false;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
162 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
163 return true;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
164 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
165
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
166 address TemplateInterpreter::_remove_activation_entry = NULL;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
167 address TemplateInterpreter::_remove_activation_preserving_args_entry = NULL;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
168
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
169
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
170 address TemplateInterpreter::_throw_ArrayIndexOutOfBoundsException_entry = NULL;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
171 address TemplateInterpreter::_throw_ArrayStoreException_entry = NULL;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
172 address TemplateInterpreter::_throw_ArithmeticException_entry = NULL;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
173 address TemplateInterpreter::_throw_ClassCastException_entry = NULL;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
174 address TemplateInterpreter::_throw_NullPointerException_entry = NULL;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
175 address TemplateInterpreter::_throw_StackOverflowError_entry = NULL;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
176 address TemplateInterpreter::_throw_exception_entry = NULL;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
177
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
178 #ifndef PRODUCT
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
179 EntryPoint TemplateInterpreter::_trace_code;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
180 #endif // !PRODUCT
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
181 EntryPoint TemplateInterpreter::_return_entry[TemplateInterpreter::number_of_return_entries];
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
182 EntryPoint TemplateInterpreter::_earlyret_entry;
8328
6b6cbd8b8914 Support deoptimizing before the entry to a synchronized method.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents: 8151
diff changeset
183 EntryPoint TemplateInterpreter::_deopt_entry[TemplateInterpreter::number_of_deopt_entries ];
7066
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
184 EntryPoint TemplateInterpreter::_continuation_entry;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
185 EntryPoint TemplateInterpreter::_safept_entry;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
186
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
187 address TemplateInterpreter::_return_3_addrs_by_index[TemplateInterpreter::number_of_return_addrs];
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
188 address TemplateInterpreter::_return_5_addrs_by_index[TemplateInterpreter::number_of_return_addrs];
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
189
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
190 DispatchTable TemplateInterpreter::_active_table;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
191 DispatchTable TemplateInterpreter::_normal_table;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
192 DispatchTable TemplateInterpreter::_safept_table;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
193 address TemplateInterpreter::_wentry_point[DispatchTable::length];
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
194
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
195 TemplateInterpreterGenerator::TemplateInterpreterGenerator(StubQueue* _code): AbstractInterpreterGenerator(_code) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
196 _unimplemented_bytecode = NULL;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
197 _illegal_bytecode_sequence = NULL;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
198 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
199
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
200 static const BasicType types[Interpreter::number_of_result_handlers] = {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
201 T_BOOLEAN,
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
202 T_CHAR ,
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
203 T_BYTE ,
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
204 T_SHORT ,
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
205 T_INT ,
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
206 T_LONG ,
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
207 T_VOID ,
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
208 T_FLOAT ,
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
209 T_DOUBLE ,
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
210 T_OBJECT
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
211 };
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
212
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
213 void TemplateInterpreterGenerator::generate_all() {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
214 AbstractInterpreterGenerator::generate_all();
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
215
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
216 { CodeletMark cm(_masm, "error exits");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
217 _unimplemented_bytecode = generate_error_exit("unimplemented bytecode");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
218 _illegal_bytecode_sequence = generate_error_exit("illegal bytecode sequence - method not verified");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
219 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
220
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
221 #ifndef PRODUCT
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
222 if (TraceBytecodes) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
223 CodeletMark cm(_masm, "bytecode tracing support");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
224 Interpreter::_trace_code =
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
225 EntryPoint(
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
226 generate_trace_code(btos),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
227 generate_trace_code(ctos),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
228 generate_trace_code(stos),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
229 generate_trace_code(atos),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
230 generate_trace_code(itos),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
231 generate_trace_code(ltos),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
232 generate_trace_code(ftos),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
233 generate_trace_code(dtos),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
234 generate_trace_code(vtos)
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
235 );
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
236 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
237 #endif // !PRODUCT
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
238
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
239 { CodeletMark cm(_masm, "return entry points");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
240 for (int i = 0; i < Interpreter::number_of_return_entries; i++) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
241 Interpreter::_return_entry[i] =
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
242 EntryPoint(
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
243 generate_return_entry_for(itos, i),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
244 generate_return_entry_for(itos, i),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
245 generate_return_entry_for(itos, i),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
246 generate_return_entry_for(atos, i),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
247 generate_return_entry_for(itos, i),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
248 generate_return_entry_for(ltos, i),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
249 generate_return_entry_for(ftos, i),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
250 generate_return_entry_for(dtos, i),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
251 generate_return_entry_for(vtos, i)
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
252 );
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
253 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
254 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
255
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
256 { CodeletMark cm(_masm, "earlyret entry points");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
257 Interpreter::_earlyret_entry =
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
258 EntryPoint(
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
259 generate_earlyret_entry_for(btos),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
260 generate_earlyret_entry_for(ctos),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
261 generate_earlyret_entry_for(stos),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
262 generate_earlyret_entry_for(atos),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
263 generate_earlyret_entry_for(itos),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
264 generate_earlyret_entry_for(ltos),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
265 generate_earlyret_entry_for(ftos),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
266 generate_earlyret_entry_for(dtos),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
267 generate_earlyret_entry_for(vtos)
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
268 );
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
269 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
270
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
271 { CodeletMark cm(_masm, "deoptimization entry points");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
272 for (int i = 0; i < Interpreter::number_of_deopt_entries; i++) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
273 Interpreter::_deopt_entry[i] =
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
274 EntryPoint(
8328
6b6cbd8b8914 Support deoptimizing before the entry to a synchronized method.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents: 8151
diff changeset
275 ((InterpreterGenerator*)this)->generate_deopt_entry_for(itos, i),
6b6cbd8b8914 Support deoptimizing before the entry to a synchronized method.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents: 8151
diff changeset
276 ((InterpreterGenerator*)this)->generate_deopt_entry_for(itos, i),
6b6cbd8b8914 Support deoptimizing before the entry to a synchronized method.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents: 8151
diff changeset
277 ((InterpreterGenerator*)this)->generate_deopt_entry_for(itos, i),
6b6cbd8b8914 Support deoptimizing before the entry to a synchronized method.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents: 8151
diff changeset
278 ((InterpreterGenerator*)this)->generate_deopt_entry_for(atos, i),
6b6cbd8b8914 Support deoptimizing before the entry to a synchronized method.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents: 8151
diff changeset
279 ((InterpreterGenerator*)this)->generate_deopt_entry_for(itos, i),
6b6cbd8b8914 Support deoptimizing before the entry to a synchronized method.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents: 8151
diff changeset
280 ((InterpreterGenerator*)this)->generate_deopt_entry_for(ltos, i),
6b6cbd8b8914 Support deoptimizing before the entry to a synchronized method.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents: 8151
diff changeset
281 ((InterpreterGenerator*)this)->generate_deopt_entry_for(ftos, i),
6b6cbd8b8914 Support deoptimizing before the entry to a synchronized method.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents: 8151
diff changeset
282 ((InterpreterGenerator*)this)->generate_deopt_entry_for(dtos, i),
6b6cbd8b8914 Support deoptimizing before the entry to a synchronized method.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents: 8151
diff changeset
283 ((InterpreterGenerator*)this)->generate_deopt_entry_for(vtos, i)
7066
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
284 );
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
285 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
286 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
287
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
288 { CodeletMark cm(_masm, "result handlers for native calls");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
289 // The various result converter stublets.
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
290 int is_generated[Interpreter::number_of_result_handlers];
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
291 memset(is_generated, 0, sizeof(is_generated));
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
292
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
293 for (int i = 0; i < Interpreter::number_of_result_handlers; i++) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
294 BasicType type = types[i];
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
295 if (!is_generated[Interpreter::BasicType_as_index(type)]++) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
296 Interpreter::_native_abi_to_tosca[Interpreter::BasicType_as_index(type)] = generate_result_handler_for(type);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
297 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
298 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
299 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
300
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
301 for (int j = 0; j < number_of_states; j++) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
302 const TosState states[] = {btos, ctos, stos, itos, ltos, ftos, dtos, atos, vtos};
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
303 int index = Interpreter::TosState_as_index(states[j]);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
304 Interpreter::_return_3_addrs_by_index[index] = Interpreter::return_entry(states[j], 3);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
305 Interpreter::_return_5_addrs_by_index[index] = Interpreter::return_entry(states[j], 5);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
306 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
307
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
308 { CodeletMark cm(_masm, "continuation entry points");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
309 Interpreter::_continuation_entry =
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
310 EntryPoint(
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
311 generate_continuation_for(btos),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
312 generate_continuation_for(ctos),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
313 generate_continuation_for(stos),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
314 generate_continuation_for(atos),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
315 generate_continuation_for(itos),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
316 generate_continuation_for(ltos),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
317 generate_continuation_for(ftos),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
318 generate_continuation_for(dtos),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
319 generate_continuation_for(vtos)
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
320 );
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
321 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
322
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
323 { CodeletMark cm(_masm, "safepoint entry points");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
324 Interpreter::_safept_entry =
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
325 EntryPoint(
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
326 generate_safept_entry_for(btos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
327 generate_safept_entry_for(ctos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
328 generate_safept_entry_for(stos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
329 generate_safept_entry_for(atos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
330 generate_safept_entry_for(itos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
331 generate_safept_entry_for(ltos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
332 generate_safept_entry_for(ftos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
333 generate_safept_entry_for(dtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
334 generate_safept_entry_for(vtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint))
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
335 );
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
336 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
337
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
338 { CodeletMark cm(_masm, "exception handling");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
339 // (Note: this is not safepoint safe because thread may return to compiled code)
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
340 generate_throw_exception();
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
341 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
342
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
343 { CodeletMark cm(_masm, "throw exception entrypoints");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
344 Interpreter::_throw_ArrayIndexOutOfBoundsException_entry = generate_ArrayIndexOutOfBounds_handler("java/lang/ArrayIndexOutOfBoundsException");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
345 Interpreter::_throw_ArrayStoreException_entry = generate_klass_exception_handler("java/lang/ArrayStoreException" );
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
346 Interpreter::_throw_ArithmeticException_entry = generate_exception_handler("java/lang/ArithmeticException" , "/ by zero");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
347 Interpreter::_throw_ClassCastException_entry = generate_ClassCastException_handler();
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
348 Interpreter::_throw_NullPointerException_entry = generate_exception_handler("java/lang/NullPointerException" , NULL );
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
349 Interpreter::_throw_StackOverflowError_entry = generate_StackOverflowError_handler();
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
350 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
351
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
352
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
353
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
354 #define method_entry(kind) \
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
355 { CodeletMark cm(_masm, "method entry point (kind = " #kind ")"); \
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
356 Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind); \
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
357 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
358
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
359 // all non-native method kinds
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
360 method_entry(zerolocals)
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
361 method_entry(zerolocals_synchronized)
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
362 method_entry(empty)
9046
c6a1ffc707ff Comments and #ifdef GRAAL for recent changes to C++ code for calling nmethods directly.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents: 9025
diff changeset
363 #ifdef GRAAL
9025
ff5a32117e02 Implement fast invocation of installed code (direct tail call to the target machine code address).
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents: 8328
diff changeset
364 method_entry(execute_compiled_method)
9046
c6a1ffc707ff Comments and #ifdef GRAAL for recent changes to C++ code for calling nmethods directly.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents: 9025
diff changeset
365 #endif
7066
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
366 method_entry(accessor)
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
367 method_entry(abstract)
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
368 method_entry(java_lang_math_sin )
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
369 method_entry(java_lang_math_cos )
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
370 method_entry(java_lang_math_tan )
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
371 method_entry(java_lang_math_abs )
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
372 method_entry(java_lang_math_sqrt )
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
373 method_entry(java_lang_math_log )
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
374 method_entry(java_lang_math_log10)
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
375 method_entry(java_lang_math_exp )
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
376 method_entry(java_lang_math_pow )
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
377 method_entry(java_lang_ref_reference_get)
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
378
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
379 initialize_method_handle_entries();
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
380
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
381 // all native method kinds (must be one contiguous block)
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
382 Interpreter::_native_entry_begin = Interpreter::code()->code_end();
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
383 method_entry(native)
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
384 method_entry(native_synchronized)
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
385 Interpreter::_native_entry_end = Interpreter::code()->code_end();
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
386
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
387 #undef method_entry
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
388
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
389 // Bytecodes
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
390 set_entry_points_for_all_bytes();
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
391 set_safepoints_for_all_bytes();
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
392 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
393
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
394 //------------------------------------------------------------------------------------------------------------------------
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
395
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
396 address TemplateInterpreterGenerator::generate_error_exit(const char* msg) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
397 address entry = __ pc();
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
398 __ stop(msg);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
399 return entry;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
400 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
401
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
402
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
403 //------------------------------------------------------------------------------------------------------------------------
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
404
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
405 void TemplateInterpreterGenerator::set_entry_points_for_all_bytes() {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
406 for (int i = 0; i < DispatchTable::length; i++) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
407 Bytecodes::Code code = (Bytecodes::Code)i;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
408 if (Bytecodes::is_defined(code)) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
409 set_entry_points(code);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
410 } else {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
411 set_unimplemented(i);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
412 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
413 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
414 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
415
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
416
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
417 void TemplateInterpreterGenerator::set_safepoints_for_all_bytes() {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
418 for (int i = 0; i < DispatchTable::length; i++) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
419 Bytecodes::Code code = (Bytecodes::Code)i;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
420 if (Bytecodes::is_defined(code)) Interpreter::_safept_table.set_entry(code, Interpreter::_safept_entry);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
421 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
422 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
423
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
424
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
425 void TemplateInterpreterGenerator::set_unimplemented(int i) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
426 address e = _unimplemented_bytecode;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
427 EntryPoint entry(e, e, e, e, e, e, e, e, e);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
428 Interpreter::_normal_table.set_entry(i, entry);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
429 Interpreter::_wentry_point[i] = _unimplemented_bytecode;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
430 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
431
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
432
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
433 void TemplateInterpreterGenerator::set_entry_points(Bytecodes::Code code) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
434 CodeletMark cm(_masm, Bytecodes::name(code), code);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
435 // initialize entry points
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
436 assert(_unimplemented_bytecode != NULL, "should have been generated before");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
437 assert(_illegal_bytecode_sequence != NULL, "should have been generated before");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
438 address bep = _illegal_bytecode_sequence;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
439 address cep = _illegal_bytecode_sequence;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
440 address sep = _illegal_bytecode_sequence;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
441 address aep = _illegal_bytecode_sequence;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
442 address iep = _illegal_bytecode_sequence;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
443 address lep = _illegal_bytecode_sequence;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
444 address fep = _illegal_bytecode_sequence;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
445 address dep = _illegal_bytecode_sequence;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
446 address vep = _unimplemented_bytecode;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
447 address wep = _unimplemented_bytecode;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
448 // code for short & wide version of bytecode
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
449 if (Bytecodes::is_defined(code)) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
450 Template* t = TemplateTable::template_for(code);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
451 assert(t->is_valid(), "just checking");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
452 set_short_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
453 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
454 if (Bytecodes::wide_is_defined(code)) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
455 Template* t = TemplateTable::template_for_wide(code);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
456 assert(t->is_valid(), "just checking");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
457 set_wide_entry_point(t, wep);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
458 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
459 // set entry points
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
460 EntryPoint entry(bep, cep, sep, aep, iep, lep, fep, dep, vep);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
461 Interpreter::_normal_table.set_entry(code, entry);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
462 Interpreter::_wentry_point[code] = wep;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
463 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
464
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
465
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
466 void TemplateInterpreterGenerator::set_wide_entry_point(Template* t, address& wep) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
467 assert(t->is_valid(), "template must exist");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
468 assert(t->tos_in() == vtos, "only vtos tos_in supported for wide instructions");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
469 wep = __ pc(); generate_and_dispatch(t);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
470 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
471
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
472
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
473 void TemplateInterpreterGenerator::set_short_entry_points(Template* t, address& bep, address& cep, address& sep, address& aep, address& iep, address& lep, address& fep, address& dep, address& vep) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
474 assert(t->is_valid(), "template must exist");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
475 switch (t->tos_in()) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
476 case btos:
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
477 case ctos:
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
478 case stos:
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
479 ShouldNotReachHere(); // btos/ctos/stos should use itos.
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
480 break;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
481 case atos: vep = __ pc(); __ pop(atos); aep = __ pc(); generate_and_dispatch(t); break;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
482 case itos: vep = __ pc(); __ pop(itos); iep = __ pc(); generate_and_dispatch(t); break;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
483 case ltos: vep = __ pc(); __ pop(ltos); lep = __ pc(); generate_and_dispatch(t); break;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
484 case ftos: vep = __ pc(); __ pop(ftos); fep = __ pc(); generate_and_dispatch(t); break;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
485 case dtos: vep = __ pc(); __ pop(dtos); dep = __ pc(); generate_and_dispatch(t); break;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
486 case vtos: set_vtos_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep); break;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
487 default : ShouldNotReachHere(); break;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
488 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
489 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
490
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
491
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
492 //------------------------------------------------------------------------------------------------------------------------
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
493
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
494 void TemplateInterpreterGenerator::generate_and_dispatch(Template* t, TosState tos_out) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
495 if (PrintBytecodeHistogram) histogram_bytecode(t);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
496 #ifndef PRODUCT
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
497 // debugging code
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
498 if (CountBytecodes || TraceBytecodes || StopInterpreterAt > 0) count_bytecode();
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
499 if (PrintBytecodePairHistogram) histogram_bytecode_pair(t);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
500 if (TraceBytecodes) trace_bytecode(t);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
501 if (StopInterpreterAt > 0) stop_interpreter_at();
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
502 __ verify_FPU(1, t->tos_in());
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
503 #endif // !PRODUCT
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
504 int step;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
505 if (!t->does_dispatch()) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
506 step = t->is_wide() ? Bytecodes::wide_length_for(t->bytecode()) : Bytecodes::length_for(t->bytecode());
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
507 if (tos_out == ilgl) tos_out = t->tos_out();
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
508 // compute bytecode size
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
509 assert(step > 0, "just checkin'");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
510 // setup stuff for dispatching next bytecode
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
511 if (ProfileInterpreter && VerifyDataPointer
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
512 && MethodData::bytecode_has_profile(t->bytecode())) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
513 __ verify_method_data_pointer();
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
514 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
515 __ dispatch_prolog(tos_out, step);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
516 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
517 // generate template
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
518 t->generate(_masm);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
519 // advance
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
520 if (t->does_dispatch()) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
521 #ifdef ASSERT
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
522 // make sure execution doesn't go beyond this point if code is broken
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
523 __ should_not_reach_here();
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
524 #endif // ASSERT
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
525 } else {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
526 // dispatch to next bytecode
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
527 __ dispatch_epilog(tos_out, step);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
528 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
529 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
530
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
531 //------------------------------------------------------------------------------------------------------------------------
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
532 // Entry points
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
533
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
534 address TemplateInterpreter::return_entry(TosState state, int length) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
535 guarantee(0 <= length && length < Interpreter::number_of_return_entries, "illegal length");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
536 return _return_entry[length].entry(state);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
537 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
538
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
539
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
540 address TemplateInterpreter::deopt_entry(TosState state, int length) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
541 guarantee(0 <= length && length < Interpreter::number_of_deopt_entries, "illegal length");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
542 return _deopt_entry[length].entry(state);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
543 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
544
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
545 //------------------------------------------------------------------------------------------------------------------------
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
546 // Suport for invokes
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
547
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
548 int TemplateInterpreter::TosState_as_index(TosState state) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
549 assert( state < number_of_states , "Invalid state in TosState_as_index");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
550 assert(0 <= (int)state && (int)state < TemplateInterpreter::number_of_return_addrs, "index out of bounds");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
551 return (int)state;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
552 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
553
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
554
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
555 //------------------------------------------------------------------------------------------------------------------------
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
556 // Safepoint suppport
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
557
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
558 static inline void copy_table(address* from, address* to, int size) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
559 // Copy non-overlapping tables. The copy has to occur word wise for MT safety.
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
560 while (size-- > 0) *to++ = *from++;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
561 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
562
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
563 void TemplateInterpreter::notice_safepoints() {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
564 if (!_notice_safepoints) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
565 // switch to safepoint dispatch table
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
566 _notice_safepoints = true;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
567 copy_table((address*)&_safept_table, (address*)&_active_table, sizeof(_active_table) / sizeof(address));
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
568 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
569 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
570
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
571 // switch from the dispatch table which notices safepoints back to the
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
572 // normal dispatch table. So that we can notice single stepping points,
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
573 // keep the safepoint dispatch table if we are single stepping in JVMTI.
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
574 // Note that the should_post_single_step test is exactly as fast as the
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
575 // JvmtiExport::_enabled test and covers both cases.
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
576 void TemplateInterpreter::ignore_safepoints() {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
577 if (_notice_safepoints) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
578 if (!JvmtiExport::should_post_single_step()) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
579 // switch to normal dispatch table
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
580 _notice_safepoints = false;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
581 copy_table((address*)&_normal_table, (address*)&_active_table, sizeof(_active_table) / sizeof(address));
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
582 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
583 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
584 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
585
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
586 //------------------------------------------------------------------------------------------------------------------------
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
587 // Deoptimization support
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
588
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
589 // If deoptimization happens, this function returns the point of next bytecode to continue execution
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
590 address TemplateInterpreter::deopt_continue_after_entry(Method* method, address bcp, int callee_parameters, bool is_top_frame) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
591 return AbstractInterpreter::deopt_continue_after_entry(method, bcp, callee_parameters, is_top_frame);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
592 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
593
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
594 // If deoptimization happens, this function returns the point where the interpreter reexecutes
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
595 // the bytecode.
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
596 // Note: Bytecodes::_athrow (C1 only) and Bytecodes::_return are the special cases
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
597 // that do not return "Interpreter::deopt_entry(vtos, 0)"
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
598 address TemplateInterpreter::deopt_reexecute_entry(Method* method, address bcp) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
599 assert(method->contains(bcp), "just checkin'");
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
600 Bytecodes::Code code = Bytecodes::java_code_at(method, bcp);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
601 if (code == Bytecodes::_return) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
602 // This is used for deopt during registration of finalizers
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
603 // during Object.<init>. We simply need to resume execution at
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
604 // the standard return vtos bytecode to pop the frame normally.
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
605 // reexecuting the real bytecode would cause double registration
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
606 // of the finalizable object.
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
607 return _normal_table.entry(Bytecodes::_return).entry(vtos);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
608 } else {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
609 return AbstractInterpreter::deopt_reexecute_entry(method, bcp);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
610 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
611 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
612
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
613 // If deoptimization happens, the interpreter should reexecute this bytecode.
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
614 // This function mainly helps the compilers to set up the reexecute bit.
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
615 bool TemplateInterpreter::bytecode_should_reexecute(Bytecodes::Code code) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
616 if (code == Bytecodes::_return) {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
617 //Yes, we consider Bytecodes::_return as a special case of reexecution
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
618 return true;
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
619 } else {
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
620 return AbstractInterpreter::bytecode_should_reexecute(code);
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
621 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
622 }
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
623
Christian Haeubl <haeubl@ssw.jku.at>
parents: 7062 6926
diff changeset
624 #endif // !CC_INTERP