annotate src/share/vm/c1/c1_LIRGenerator.cpp @ 20543:e7d0505c8a30

8059758: Footprint regressions with JDK-8038423 Summary: Changes in JDK-8038423 always initialize (zero out) virtual memory used for auxiliary data structures. This causes a footprint regression for G1 in startup benchmarks. This is because they do not touch that memory at all, so the operating system does not actually commit these pages. The fix is to, if the initialization value of the data structures matches the default value of just committed memory (=0), do not do anything. Reviewed-by: jwilhelm, brutisso
author tschatzl
date Fri, 10 Oct 2014 15:51:58 +0200
parents b29261b17343
children 7848fc12602b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
10105
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 8869
diff changeset
2 * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1378
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1378
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1378
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1873
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1873
diff changeset
26 #include "c1/c1_Compilation.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1873
diff changeset
27 #include "c1/c1_FrameMap.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1873
diff changeset
28 #include "c1/c1_Instruction.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1873
diff changeset
29 #include "c1/c1_LIRAssembler.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1873
diff changeset
30 #include "c1/c1_LIRGenerator.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1873
diff changeset
31 #include "c1/c1_ValueStack.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1873
diff changeset
32 #include "ci/ciArrayKlass.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1873
diff changeset
33 #include "ci/ciInstance.hpp"
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6616
diff changeset
34 #include "ci/ciObjArray.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1873
diff changeset
35 #include "runtime/sharedRuntime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1873
diff changeset
36 #include "runtime/stubRoutines.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1873
diff changeset
37 #include "utilities/bitMap.inline.hpp"
8001
db9981fd3124 8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents: 7425
diff changeset
38 #include "utilities/macros.hpp"
db9981fd3124 8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents: 7425
diff changeset
39 #if INCLUDE_ALL_GCS
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1873
diff changeset
40 #include "gc_implementation/g1/heapRegion.hpp"
8001
db9981fd3124 8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents: 7425
diff changeset
41 #endif // INCLUDE_ALL_GCS
0
a61af66fc99e Initial load
duke
parents:
diff changeset
42
a61af66fc99e Initial load
duke
parents:
diff changeset
43 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
44 #define __ gen()->lir(__FILE__, __LINE__)->
a61af66fc99e Initial load
duke
parents:
diff changeset
45 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
46 #define __ gen()->lir()->
a61af66fc99e Initial load
duke
parents:
diff changeset
47 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
48
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
49 // TODO: ARM - Use some recognizable constant which still fits architectural constraints
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
50 #ifdef ARM
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
51 #define PATCHED_ADDR (204)
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
52 #else
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
53 #define PATCHED_ADDR (max_jint)
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
54 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
55
a61af66fc99e Initial load
duke
parents:
diff changeset
56 void PhiResolverState::reset(int max_vregs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
57 // Initialize array sizes
a61af66fc99e Initial load
duke
parents:
diff changeset
58 _virtual_operands.at_put_grow(max_vregs - 1, NULL, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
59 _virtual_operands.trunc_to(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
60 _other_operands.at_put_grow(max_vregs - 1, NULL, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
61 _other_operands.trunc_to(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
62 _vreg_table.at_put_grow(max_vregs - 1, NULL, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
63 _vreg_table.trunc_to(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
64 }
a61af66fc99e Initial load
duke
parents:
diff changeset
65
a61af66fc99e Initial load
duke
parents:
diff changeset
66
a61af66fc99e Initial load
duke
parents:
diff changeset
67
a61af66fc99e Initial load
duke
parents:
diff changeset
68 //--------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
69 // PhiResolver
a61af66fc99e Initial load
duke
parents:
diff changeset
70
a61af66fc99e Initial load
duke
parents:
diff changeset
71 // Resolves cycles:
a61af66fc99e Initial load
duke
parents:
diff changeset
72 //
a61af66fc99e Initial load
duke
parents:
diff changeset
73 // r1 := r2 becomes temp := r1
a61af66fc99e Initial load
duke
parents:
diff changeset
74 // r2 := r1 r1 := r2
a61af66fc99e Initial load
duke
parents:
diff changeset
75 // r2 := temp
a61af66fc99e Initial load
duke
parents:
diff changeset
76 // and orders moves:
a61af66fc99e Initial load
duke
parents:
diff changeset
77 //
a61af66fc99e Initial load
duke
parents:
diff changeset
78 // r2 := r3 becomes r1 := r2
a61af66fc99e Initial load
duke
parents:
diff changeset
79 // r1 := r2 r2 := r3
a61af66fc99e Initial load
duke
parents:
diff changeset
80
a61af66fc99e Initial load
duke
parents:
diff changeset
81 PhiResolver::PhiResolver(LIRGenerator* gen, int max_vregs)
a61af66fc99e Initial load
duke
parents:
diff changeset
82 : _gen(gen)
a61af66fc99e Initial load
duke
parents:
diff changeset
83 , _state(gen->resolver_state())
a61af66fc99e Initial load
duke
parents:
diff changeset
84 , _temp(LIR_OprFact::illegalOpr)
a61af66fc99e Initial load
duke
parents:
diff changeset
85 {
a61af66fc99e Initial load
duke
parents:
diff changeset
86 // reinitialize the shared state arrays
a61af66fc99e Initial load
duke
parents:
diff changeset
87 _state.reset(max_vregs);
a61af66fc99e Initial load
duke
parents:
diff changeset
88 }
a61af66fc99e Initial load
duke
parents:
diff changeset
89
a61af66fc99e Initial load
duke
parents:
diff changeset
90
a61af66fc99e Initial load
duke
parents:
diff changeset
91 void PhiResolver::emit_move(LIR_Opr src, LIR_Opr dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
92 assert(src->is_valid(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
93 assert(dest->is_valid(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
94 __ move(src, dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
95 }
a61af66fc99e Initial load
duke
parents:
diff changeset
96
a61af66fc99e Initial load
duke
parents:
diff changeset
97
a61af66fc99e Initial load
duke
parents:
diff changeset
98 void PhiResolver::move_temp_to(LIR_Opr dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
99 assert(_temp->is_valid(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
100 emit_move(_temp, dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
101 NOT_PRODUCT(_temp = LIR_OprFact::illegalOpr);
a61af66fc99e Initial load
duke
parents:
diff changeset
102 }
a61af66fc99e Initial load
duke
parents:
diff changeset
103
a61af66fc99e Initial load
duke
parents:
diff changeset
104
a61af66fc99e Initial load
duke
parents:
diff changeset
105 void PhiResolver::move_to_temp(LIR_Opr src) {
a61af66fc99e Initial load
duke
parents:
diff changeset
106 assert(_temp->is_illegal(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
107 _temp = _gen->new_register(src->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
108 emit_move(src, _temp);
a61af66fc99e Initial load
duke
parents:
diff changeset
109 }
a61af66fc99e Initial load
duke
parents:
diff changeset
110
a61af66fc99e Initial load
duke
parents:
diff changeset
111
a61af66fc99e Initial load
duke
parents:
diff changeset
112 // Traverse assignment graph in depth first order and generate moves in post order
a61af66fc99e Initial load
duke
parents:
diff changeset
113 // ie. two assignments: b := c, a := b start with node c:
a61af66fc99e Initial load
duke
parents:
diff changeset
114 // Call graph: move(NULL, c) -> move(c, b) -> move(b, a)
a61af66fc99e Initial load
duke
parents:
diff changeset
115 // Generates moves in this order: move b to a and move c to b
a61af66fc99e Initial load
duke
parents:
diff changeset
116 // ie. cycle a := b, b := a start with node a
a61af66fc99e Initial load
duke
parents:
diff changeset
117 // Call graph: move(NULL, a) -> move(a, b) -> move(b, a)
a61af66fc99e Initial load
duke
parents:
diff changeset
118 // Generates moves in this order: move b to temp, move a to b, move temp to a
a61af66fc99e Initial load
duke
parents:
diff changeset
119 void PhiResolver::move(ResolveNode* src, ResolveNode* dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
120 if (!dest->visited()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
121 dest->set_visited();
a61af66fc99e Initial load
duke
parents:
diff changeset
122 for (int i = dest->no_of_destinations()-1; i >= 0; i --) {
a61af66fc99e Initial load
duke
parents:
diff changeset
123 move(dest, dest->destination_at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
125 } else if (!dest->start_node()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
126 // cylce in graph detected
a61af66fc99e Initial load
duke
parents:
diff changeset
127 assert(_loop == NULL, "only one loop valid!");
a61af66fc99e Initial load
duke
parents:
diff changeset
128 _loop = dest;
a61af66fc99e Initial load
duke
parents:
diff changeset
129 move_to_temp(src->operand());
a61af66fc99e Initial load
duke
parents:
diff changeset
130 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
131 } // else dest is a start node
a61af66fc99e Initial load
duke
parents:
diff changeset
132
a61af66fc99e Initial load
duke
parents:
diff changeset
133 if (!dest->assigned()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
134 if (_loop == dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
135 move_temp_to(dest->operand());
a61af66fc99e Initial load
duke
parents:
diff changeset
136 dest->set_assigned();
a61af66fc99e Initial load
duke
parents:
diff changeset
137 } else if (src != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
138 emit_move(src->operand(), dest->operand());
a61af66fc99e Initial load
duke
parents:
diff changeset
139 dest->set_assigned();
a61af66fc99e Initial load
duke
parents:
diff changeset
140 }
a61af66fc99e Initial load
duke
parents:
diff changeset
141 }
a61af66fc99e Initial load
duke
parents:
diff changeset
142 }
a61af66fc99e Initial load
duke
parents:
diff changeset
143
a61af66fc99e Initial load
duke
parents:
diff changeset
144
a61af66fc99e Initial load
duke
parents:
diff changeset
145 PhiResolver::~PhiResolver() {
a61af66fc99e Initial load
duke
parents:
diff changeset
146 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
147 // resolve any cycles in moves from and to virtual registers
a61af66fc99e Initial load
duke
parents:
diff changeset
148 for (i = virtual_operands().length() - 1; i >= 0; i --) {
a61af66fc99e Initial load
duke
parents:
diff changeset
149 ResolveNode* node = virtual_operands()[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
150 if (!node->visited()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
151 _loop = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
152 move(NULL, node);
a61af66fc99e Initial load
duke
parents:
diff changeset
153 node->set_start_node();
a61af66fc99e Initial load
duke
parents:
diff changeset
154 assert(_temp->is_illegal(), "move_temp_to() call missing");
a61af66fc99e Initial load
duke
parents:
diff changeset
155 }
a61af66fc99e Initial load
duke
parents:
diff changeset
156 }
a61af66fc99e Initial load
duke
parents:
diff changeset
157
a61af66fc99e Initial load
duke
parents:
diff changeset
158 // generate move for move from non virtual register to abitrary destination
a61af66fc99e Initial load
duke
parents:
diff changeset
159 for (i = other_operands().length() - 1; i >= 0; i --) {
a61af66fc99e Initial load
duke
parents:
diff changeset
160 ResolveNode* node = other_operands()[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
161 for (int j = node->no_of_destinations() - 1; j >= 0; j --) {
a61af66fc99e Initial load
duke
parents:
diff changeset
162 emit_move(node->operand(), node->destination_at(j)->operand());
a61af66fc99e Initial load
duke
parents:
diff changeset
163 }
a61af66fc99e Initial load
duke
parents:
diff changeset
164 }
a61af66fc99e Initial load
duke
parents:
diff changeset
165 }
a61af66fc99e Initial load
duke
parents:
diff changeset
166
a61af66fc99e Initial load
duke
parents:
diff changeset
167
a61af66fc99e Initial load
duke
parents:
diff changeset
168 ResolveNode* PhiResolver::create_node(LIR_Opr opr, bool source) {
a61af66fc99e Initial load
duke
parents:
diff changeset
169 ResolveNode* node;
a61af66fc99e Initial load
duke
parents:
diff changeset
170 if (opr->is_virtual()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
171 int vreg_num = opr->vreg_number();
a61af66fc99e Initial load
duke
parents:
diff changeset
172 node = vreg_table().at_grow(vreg_num, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
173 assert(node == NULL || node->operand() == opr, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
174 if (node == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
175 node = new ResolveNode(opr);
a61af66fc99e Initial load
duke
parents:
diff changeset
176 vreg_table()[vreg_num] = node;
a61af66fc99e Initial load
duke
parents:
diff changeset
177 }
a61af66fc99e Initial load
duke
parents:
diff changeset
178 // Make sure that all virtual operands show up in the list when
a61af66fc99e Initial load
duke
parents:
diff changeset
179 // they are used as the source of a move.
a61af66fc99e Initial load
duke
parents:
diff changeset
180 if (source && !virtual_operands().contains(node)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
181 virtual_operands().append(node);
a61af66fc99e Initial load
duke
parents:
diff changeset
182 }
a61af66fc99e Initial load
duke
parents:
diff changeset
183 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
184 assert(source, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
185 node = new ResolveNode(opr);
a61af66fc99e Initial load
duke
parents:
diff changeset
186 other_operands().append(node);
a61af66fc99e Initial load
duke
parents:
diff changeset
187 }
a61af66fc99e Initial load
duke
parents:
diff changeset
188 return node;
a61af66fc99e Initial load
duke
parents:
diff changeset
189 }
a61af66fc99e Initial load
duke
parents:
diff changeset
190
a61af66fc99e Initial load
duke
parents:
diff changeset
191
a61af66fc99e Initial load
duke
parents:
diff changeset
192 void PhiResolver::move(LIR_Opr src, LIR_Opr dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
193 assert(dest->is_virtual(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
194 // tty->print("move "); src->print(); tty->print(" to "); dest->print(); tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
195 assert(src->is_valid(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
196 assert(dest->is_valid(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
197 ResolveNode* source = source_node(src);
a61af66fc99e Initial load
duke
parents:
diff changeset
198 source->append(destination_node(dest));
a61af66fc99e Initial load
duke
parents:
diff changeset
199 }
a61af66fc99e Initial load
duke
parents:
diff changeset
200
a61af66fc99e Initial load
duke
parents:
diff changeset
201
a61af66fc99e Initial load
duke
parents:
diff changeset
202 //--------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
203 // LIRItem
a61af66fc99e Initial load
duke
parents:
diff changeset
204
a61af66fc99e Initial load
duke
parents:
diff changeset
205 void LIRItem::set_result(LIR_Opr opr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
206 assert(value()->operand()->is_illegal() || value()->operand()->is_constant(), "operand should never change");
a61af66fc99e Initial load
duke
parents:
diff changeset
207 value()->set_operand(opr);
a61af66fc99e Initial load
duke
parents:
diff changeset
208
a61af66fc99e Initial load
duke
parents:
diff changeset
209 if (opr->is_virtual()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
210 _gen->_instruction_for_operand.at_put_grow(opr->vreg_number(), value(), NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
211 }
a61af66fc99e Initial load
duke
parents:
diff changeset
212
a61af66fc99e Initial load
duke
parents:
diff changeset
213 _result = opr;
a61af66fc99e Initial load
duke
parents:
diff changeset
214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
215
a61af66fc99e Initial load
duke
parents:
diff changeset
216 void LIRItem::load_item() {
a61af66fc99e Initial load
duke
parents:
diff changeset
217 if (result()->is_illegal()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
218 // update the items result
a61af66fc99e Initial load
duke
parents:
diff changeset
219 _result = value()->operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
220 }
a61af66fc99e Initial load
duke
parents:
diff changeset
221 if (!result()->is_register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
222 LIR_Opr reg = _gen->new_register(value()->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
223 __ move(result(), reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
224 if (result()->is_constant()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
225 _result = reg;
a61af66fc99e Initial load
duke
parents:
diff changeset
226 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
227 set_result(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
228 }
a61af66fc99e Initial load
duke
parents:
diff changeset
229 }
a61af66fc99e Initial load
duke
parents:
diff changeset
230 }
a61af66fc99e Initial load
duke
parents:
diff changeset
231
a61af66fc99e Initial load
duke
parents:
diff changeset
232
a61af66fc99e Initial load
duke
parents:
diff changeset
233 void LIRItem::load_for_store(BasicType type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
234 if (_gen->can_store_as_constant(value(), type)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
235 _result = value()->operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
236 if (!_result->is_constant()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
237 _result = LIR_OprFact::value_type(value()->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
238 }
a61af66fc99e Initial load
duke
parents:
diff changeset
239 } else if (type == T_BYTE || type == T_BOOLEAN) {
a61af66fc99e Initial load
duke
parents:
diff changeset
240 load_byte_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
241 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
242 load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
243 }
a61af66fc99e Initial load
duke
parents:
diff changeset
244 }
a61af66fc99e Initial load
duke
parents:
diff changeset
245
a61af66fc99e Initial load
duke
parents:
diff changeset
246 void LIRItem::load_item_force(LIR_Opr reg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
247 LIR_Opr r = result();
a61af66fc99e Initial load
duke
parents:
diff changeset
248 if (r != reg) {
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
249 #if !defined(ARM) && !defined(E500V2)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
250 if (r->type() != reg->type()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
251 // moves between different types need an intervening spill slot
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
252 r = _gen->force_to_spill(r, reg->type());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
253 }
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
254 #endif
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
255 __ move(r, reg);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
256 _result = reg;
a61af66fc99e Initial load
duke
parents:
diff changeset
257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
258 }
a61af66fc99e Initial load
duke
parents:
diff changeset
259
a61af66fc99e Initial load
duke
parents:
diff changeset
260 ciObject* LIRItem::get_jobject_constant() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
261 ObjectType* oc = type()->as_ObjectType();
a61af66fc99e Initial load
duke
parents:
diff changeset
262 if (oc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
263 return oc->constant_value();
a61af66fc99e Initial load
duke
parents:
diff changeset
264 }
a61af66fc99e Initial load
duke
parents:
diff changeset
265 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
266 }
a61af66fc99e Initial load
duke
parents:
diff changeset
267
a61af66fc99e Initial load
duke
parents:
diff changeset
268
a61af66fc99e Initial load
duke
parents:
diff changeset
269 jint LIRItem::get_jint_constant() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
270 assert(is_constant() && value() != NULL, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
271 assert(type()->as_IntConstant() != NULL, "type check");
a61af66fc99e Initial load
duke
parents:
diff changeset
272 return type()->as_IntConstant()->value();
a61af66fc99e Initial load
duke
parents:
diff changeset
273 }
a61af66fc99e Initial load
duke
parents:
diff changeset
274
a61af66fc99e Initial load
duke
parents:
diff changeset
275
a61af66fc99e Initial load
duke
parents:
diff changeset
276 jint LIRItem::get_address_constant() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
277 assert(is_constant() && value() != NULL, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
278 assert(type()->as_AddressConstant() != NULL, "type check");
a61af66fc99e Initial load
duke
parents:
diff changeset
279 return type()->as_AddressConstant()->value();
a61af66fc99e Initial load
duke
parents:
diff changeset
280 }
a61af66fc99e Initial load
duke
parents:
diff changeset
281
a61af66fc99e Initial load
duke
parents:
diff changeset
282
a61af66fc99e Initial load
duke
parents:
diff changeset
283 jfloat LIRItem::get_jfloat_constant() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
284 assert(is_constant() && value() != NULL, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
285 assert(type()->as_FloatConstant() != NULL, "type check");
a61af66fc99e Initial load
duke
parents:
diff changeset
286 return type()->as_FloatConstant()->value();
a61af66fc99e Initial load
duke
parents:
diff changeset
287 }
a61af66fc99e Initial load
duke
parents:
diff changeset
288
a61af66fc99e Initial load
duke
parents:
diff changeset
289
a61af66fc99e Initial load
duke
parents:
diff changeset
290 jdouble LIRItem::get_jdouble_constant() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
291 assert(is_constant() && value() != NULL, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
292 assert(type()->as_DoubleConstant() != NULL, "type check");
a61af66fc99e Initial load
duke
parents:
diff changeset
293 return type()->as_DoubleConstant()->value();
a61af66fc99e Initial load
duke
parents:
diff changeset
294 }
a61af66fc99e Initial load
duke
parents:
diff changeset
295
a61af66fc99e Initial load
duke
parents:
diff changeset
296
a61af66fc99e Initial load
duke
parents:
diff changeset
297 jlong LIRItem::get_jlong_constant() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
298 assert(is_constant() && value() != NULL, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
299 assert(type()->as_LongConstant() != NULL, "type check");
a61af66fc99e Initial load
duke
parents:
diff changeset
300 return type()->as_LongConstant()->value();
a61af66fc99e Initial load
duke
parents:
diff changeset
301 }
a61af66fc99e Initial load
duke
parents:
diff changeset
302
a61af66fc99e Initial load
duke
parents:
diff changeset
303
a61af66fc99e Initial load
duke
parents:
diff changeset
304
a61af66fc99e Initial load
duke
parents:
diff changeset
305 //--------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
306
a61af66fc99e Initial load
duke
parents:
diff changeset
307
a61af66fc99e Initial load
duke
parents:
diff changeset
308 void LIRGenerator::init() {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
309 _bs = Universe::heap()->barrier_set();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
310 }
a61af66fc99e Initial load
duke
parents:
diff changeset
311
a61af66fc99e Initial load
duke
parents:
diff changeset
312
a61af66fc99e Initial load
duke
parents:
diff changeset
313 void LIRGenerator::block_do_prolog(BlockBegin* block) {
a61af66fc99e Initial load
duke
parents:
diff changeset
314 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
315 if (PrintIRWithLIR) {
a61af66fc99e Initial load
duke
parents:
diff changeset
316 block->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
317 }
a61af66fc99e Initial load
duke
parents:
diff changeset
318 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
319
a61af66fc99e Initial load
duke
parents:
diff changeset
320 // set up the list of LIR instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
321 assert(block->lir() == NULL, "LIR list already computed for this block");
a61af66fc99e Initial load
duke
parents:
diff changeset
322 _lir = new LIR_List(compilation(), block);
a61af66fc99e Initial load
duke
parents:
diff changeset
323 block->set_lir(_lir);
a61af66fc99e Initial load
duke
parents:
diff changeset
324
a61af66fc99e Initial load
duke
parents:
diff changeset
325 __ branch_destination(block->label());
a61af66fc99e Initial load
duke
parents:
diff changeset
326
a61af66fc99e Initial load
duke
parents:
diff changeset
327 if (LIRTraceExecution &&
1584
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
328 Compilation::current()->hir()->start()->block_id() != block->block_id() &&
0
a61af66fc99e Initial load
duke
parents:
diff changeset
329 !block->is_set(BlockBegin::exception_entry_flag)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
330 assert(block->lir()->instructions_list()->length() == 1, "should come right after br_dst");
a61af66fc99e Initial load
duke
parents:
diff changeset
331 trace_block_entry(block);
a61af66fc99e Initial load
duke
parents:
diff changeset
332 }
a61af66fc99e Initial load
duke
parents:
diff changeset
333 }
a61af66fc99e Initial load
duke
parents:
diff changeset
334
a61af66fc99e Initial load
duke
parents:
diff changeset
335
a61af66fc99e Initial load
duke
parents:
diff changeset
336 void LIRGenerator::block_do_epilog(BlockBegin* block) {
a61af66fc99e Initial load
duke
parents:
diff changeset
337 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
338 if (PrintIRWithLIR) {
a61af66fc99e Initial load
duke
parents:
diff changeset
339 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
340 }
a61af66fc99e Initial load
duke
parents:
diff changeset
341 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
342
a61af66fc99e Initial load
duke
parents:
diff changeset
343 // LIR_Opr for unpinned constants shouldn't be referenced by other
a61af66fc99e Initial load
duke
parents:
diff changeset
344 // blocks so clear them out after processing the block.
a61af66fc99e Initial load
duke
parents:
diff changeset
345 for (int i = 0; i < _unpinned_constants.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
346 _unpinned_constants.at(i)->clear_operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
347 }
a61af66fc99e Initial load
duke
parents:
diff changeset
348 _unpinned_constants.trunc_to(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
349
a61af66fc99e Initial load
duke
parents:
diff changeset
350 // clear our any registers for other local constants
a61af66fc99e Initial load
duke
parents:
diff changeset
351 _constants.trunc_to(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
352 _reg_for_constants.trunc_to(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
353 }
a61af66fc99e Initial load
duke
parents:
diff changeset
354
a61af66fc99e Initial load
duke
parents:
diff changeset
355
a61af66fc99e Initial load
duke
parents:
diff changeset
356 void LIRGenerator::block_do(BlockBegin* block) {
a61af66fc99e Initial load
duke
parents:
diff changeset
357 CHECK_BAILOUT();
a61af66fc99e Initial load
duke
parents:
diff changeset
358
a61af66fc99e Initial load
duke
parents:
diff changeset
359 block_do_prolog(block);
a61af66fc99e Initial load
duke
parents:
diff changeset
360 set_block(block);
a61af66fc99e Initial load
duke
parents:
diff changeset
361
a61af66fc99e Initial load
duke
parents:
diff changeset
362 for (Instruction* instr = block; instr != NULL; instr = instr->next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
363 if (instr->is_pinned()) do_root(instr);
a61af66fc99e Initial load
duke
parents:
diff changeset
364 }
a61af66fc99e Initial load
duke
parents:
diff changeset
365
a61af66fc99e Initial load
duke
parents:
diff changeset
366 set_block(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
367 block_do_epilog(block);
a61af66fc99e Initial load
duke
parents:
diff changeset
368 }
a61af66fc99e Initial load
duke
parents:
diff changeset
369
a61af66fc99e Initial load
duke
parents:
diff changeset
370
a61af66fc99e Initial load
duke
parents:
diff changeset
371 //-------------------------LIRGenerator-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
372
a61af66fc99e Initial load
duke
parents:
diff changeset
373 // This is where the tree-walk starts; instr must be root;
a61af66fc99e Initial load
duke
parents:
diff changeset
374 void LIRGenerator::do_root(Value instr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
375 CHECK_BAILOUT();
a61af66fc99e Initial load
duke
parents:
diff changeset
376
a61af66fc99e Initial load
duke
parents:
diff changeset
377 InstructionMark im(compilation(), instr);
a61af66fc99e Initial load
duke
parents:
diff changeset
378
a61af66fc99e Initial load
duke
parents:
diff changeset
379 assert(instr->is_pinned(), "use only with roots");
a61af66fc99e Initial load
duke
parents:
diff changeset
380 assert(instr->subst() == instr, "shouldn't have missed substitution");
a61af66fc99e Initial load
duke
parents:
diff changeset
381
a61af66fc99e Initial load
duke
parents:
diff changeset
382 instr->visit(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
383
a61af66fc99e Initial load
duke
parents:
diff changeset
384 assert(!instr->has_uses() || instr->operand()->is_valid() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
385 instr->as_Constant() != NULL || bailed_out(), "invalid item set");
a61af66fc99e Initial load
duke
parents:
diff changeset
386 }
a61af66fc99e Initial load
duke
parents:
diff changeset
387
a61af66fc99e Initial load
duke
parents:
diff changeset
388
a61af66fc99e Initial load
duke
parents:
diff changeset
389 // This is called for each node in tree; the walk stops if a root is reached
a61af66fc99e Initial load
duke
parents:
diff changeset
390 void LIRGenerator::walk(Value instr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
391 InstructionMark im(compilation(), instr);
a61af66fc99e Initial load
duke
parents:
diff changeset
392 //stop walk when encounter a root
a61af66fc99e Initial load
duke
parents:
diff changeset
393 if (instr->is_pinned() && instr->as_Phi() == NULL || instr->operand()->is_valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
394 assert(instr->operand() != LIR_OprFact::illegalOpr || instr->as_Constant() != NULL, "this root has not yet been visited");
a61af66fc99e Initial load
duke
parents:
diff changeset
395 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
396 assert(instr->subst() == instr, "shouldn't have missed substitution");
a61af66fc99e Initial load
duke
parents:
diff changeset
397 instr->visit(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
398 // assert(instr->use_count() > 0 || instr->as_Phi() != NULL, "leaf instruction must have a use");
a61af66fc99e Initial load
duke
parents:
diff changeset
399 }
a61af66fc99e Initial load
duke
parents:
diff changeset
400 }
a61af66fc99e Initial load
duke
parents:
diff changeset
401
a61af66fc99e Initial load
duke
parents:
diff changeset
402
a61af66fc99e Initial load
duke
parents:
diff changeset
403 CodeEmitInfo* LIRGenerator::state_for(Instruction* x, ValueStack* state, bool ignore_xhandler) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
404 assert(state != NULL, "state must be defined");
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
405
8860
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
406 #ifndef PRODUCT
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
407 state->verify();
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
408 #endif
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
409
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
410 ValueStack* s = state;
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
411 for_each_state(s) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
412 if (s->kind() == ValueStack::EmptyExceptionState) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
413 assert(s->stack_size() == 0 && s->locals_size() == 0 && (s->locks_size() == 0 || s->locks_size() == 1), "state must be empty");
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
414 continue;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
415 }
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
416
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
417 int index;
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
418 Value value;
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
419 for_each_stack_value(s, index, value) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
420 assert(value->subst() == value, "missed substitution");
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
421 if (!value->is_pinned() && value->as_Constant() == NULL && value->as_Local() == NULL) {
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
422 walk(value);
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
423 assert(value->operand()->is_valid(), "must be evaluated now");
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
424 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
425 }
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
426
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
427 int bci = s->bci();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
428 IRScope* scope = s->scope();
a61af66fc99e Initial load
duke
parents:
diff changeset
429 ciMethod* method = scope->method();
a61af66fc99e Initial load
duke
parents:
diff changeset
430
a61af66fc99e Initial load
duke
parents:
diff changeset
431 MethodLivenessResult liveness = method->liveness_at_bci(bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
432 if (bci == SynchronizationEntryBCI) {
a61af66fc99e Initial load
duke
parents:
diff changeset
433 if (x->as_ExceptionObject() || x->as_Throw()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
434 // all locals are dead on exit from the synthetic unlocker
a61af66fc99e Initial load
duke
parents:
diff changeset
435 liveness.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
436 } else {
4116
973293defacd 7112085: assert(fr.interpreter_frame_expression_stack_size()==0) failed: only handle empty stacks
iveresov
parents: 3997
diff changeset
437 assert(x->as_MonitorEnter() || x->as_ProfileInvoke(), "only other cases are MonitorEnter and ProfileInvoke");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
438 }
a61af66fc99e Initial load
duke
parents:
diff changeset
439 }
a61af66fc99e Initial load
duke
parents:
diff changeset
440 if (!liveness.is_valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
441 // Degenerate or breakpointed method.
a61af66fc99e Initial load
duke
parents:
diff changeset
442 bailout("Degenerate or breakpointed method");
a61af66fc99e Initial load
duke
parents:
diff changeset
443 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
444 assert((int)liveness.size() == s->locals_size(), "error in use of liveness");
a61af66fc99e Initial load
duke
parents:
diff changeset
445 for_each_local_value(s, index, value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
446 assert(value->subst() == value, "missed substition");
a61af66fc99e Initial load
duke
parents:
diff changeset
447 if (liveness.at(index) && !value->type()->is_illegal()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
448 if (!value->is_pinned() && value->as_Constant() == NULL && value->as_Local() == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
449 walk(value);
a61af66fc99e Initial load
duke
parents:
diff changeset
450 assert(value->operand()->is_valid(), "must be evaluated now");
a61af66fc99e Initial load
duke
parents:
diff changeset
451 }
a61af66fc99e Initial load
duke
parents:
diff changeset
452 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
453 // NULL out this local so that linear scan can assume that all non-NULL values are live.
a61af66fc99e Initial load
duke
parents:
diff changeset
454 s->invalidate_local(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
455 }
a61af66fc99e Initial load
duke
parents:
diff changeset
456 }
a61af66fc99e Initial load
duke
parents:
diff changeset
457 }
a61af66fc99e Initial load
duke
parents:
diff changeset
458 }
a61af66fc99e Initial load
duke
parents:
diff changeset
459
8860
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
460 return new CodeEmitInfo(state, ignore_xhandler ? NULL : x->exception_handlers(), x->check_flag(Instruction::DeoptimizeOnException));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
461 }
a61af66fc99e Initial load
duke
parents:
diff changeset
462
a61af66fc99e Initial load
duke
parents:
diff changeset
463
a61af66fc99e Initial load
duke
parents:
diff changeset
464 CodeEmitInfo* LIRGenerator::state_for(Instruction* x) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
465 return state_for(x, x->exception_state());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
466 }
a61af66fc99e Initial load
duke
parents:
diff changeset
467
a61af66fc99e Initial load
duke
parents:
diff changeset
468
20344
2fd0fd493045 8031994: java/lang/Character/CheckProp test times out
rbackman
parents: 17925
diff changeset
469 void LIRGenerator::klass2reg_with_patching(LIR_Opr r, ciMetadata* obj, CodeEmitInfo* info, bool need_resolve) {
2fd0fd493045 8031994: java/lang/Character/CheckProp test times out
rbackman
parents: 17925
diff changeset
470 /* C2 relies on constant pool entries being resolved (ciTypeFlow), so if TieredCompilation
2fd0fd493045 8031994: java/lang/Character/CheckProp test times out
rbackman
parents: 17925
diff changeset
471 * is active and the class hasn't yet been resolved we need to emit a patch that resolves
2fd0fd493045 8031994: java/lang/Character/CheckProp test times out
rbackman
parents: 17925
diff changeset
472 * the class. */
2fd0fd493045 8031994: java/lang/Character/CheckProp test times out
rbackman
parents: 17925
diff changeset
473 if ((TieredCompilation && need_resolve) || !obj->is_loaded() || PatchALot) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
474 assert(info != NULL, "info must be set if class is not loaded");
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6616
diff changeset
475 __ klass2reg_patch(NULL, r, info);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
476 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
477 // no patching needed
6739
8a02ca5e5576 7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents: 6731
diff changeset
478 __ metadata2reg(obj->constant_encoding(), r);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
479 }
a61af66fc99e Initial load
duke
parents:
diff changeset
480 }
a61af66fc99e Initial load
duke
parents:
diff changeset
481
a61af66fc99e Initial load
duke
parents:
diff changeset
482
a61af66fc99e Initial load
duke
parents:
diff changeset
483 void LIRGenerator::array_range_check(LIR_Opr array, LIR_Opr index,
a61af66fc99e Initial load
duke
parents:
diff changeset
484 CodeEmitInfo* null_check_info, CodeEmitInfo* range_check_info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
485 CodeStub* stub = new RangeCheckStub(range_check_info, index);
a61af66fc99e Initial load
duke
parents:
diff changeset
486 if (index->is_constant()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
487 cmp_mem_int(lir_cond_belowEqual, array, arrayOopDesc::length_offset_in_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
488 index->as_jint(), null_check_info);
a61af66fc99e Initial load
duke
parents:
diff changeset
489 __ branch(lir_cond_belowEqual, T_INT, stub); // forward branch
a61af66fc99e Initial load
duke
parents:
diff changeset
490 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
491 cmp_reg_mem(lir_cond_aboveEqual, index, array,
a61af66fc99e Initial load
duke
parents:
diff changeset
492 arrayOopDesc::length_offset_in_bytes(), T_INT, null_check_info);
a61af66fc99e Initial load
duke
parents:
diff changeset
493 __ branch(lir_cond_aboveEqual, T_INT, stub); // forward branch
a61af66fc99e Initial load
duke
parents:
diff changeset
494 }
a61af66fc99e Initial load
duke
parents:
diff changeset
495 }
a61af66fc99e Initial load
duke
parents:
diff changeset
496
a61af66fc99e Initial load
duke
parents:
diff changeset
497
a61af66fc99e Initial load
duke
parents:
diff changeset
498 void LIRGenerator::nio_range_check(LIR_Opr buffer, LIR_Opr index, LIR_Opr result, CodeEmitInfo* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
499 CodeStub* stub = new RangeCheckStub(info, index, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
500 if (index->is_constant()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
501 cmp_mem_int(lir_cond_belowEqual, buffer, java_nio_Buffer::limit_offset(), index->as_jint(), info);
a61af66fc99e Initial load
duke
parents:
diff changeset
502 __ branch(lir_cond_belowEqual, T_INT, stub); // forward branch
a61af66fc99e Initial load
duke
parents:
diff changeset
503 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
504 cmp_reg_mem(lir_cond_aboveEqual, index, buffer,
a61af66fc99e Initial load
duke
parents:
diff changeset
505 java_nio_Buffer::limit_offset(), T_INT, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
506 __ branch(lir_cond_aboveEqual, T_INT, stub); // forward branch
a61af66fc99e Initial load
duke
parents:
diff changeset
507 }
a61af66fc99e Initial load
duke
parents:
diff changeset
508 __ move(index, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
509 }
a61af66fc99e Initial load
duke
parents:
diff changeset
510
a61af66fc99e Initial load
duke
parents:
diff changeset
511
a61af66fc99e Initial load
duke
parents:
diff changeset
512
a61af66fc99e Initial load
duke
parents:
diff changeset
513 void LIRGenerator::arithmetic_op(Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, bool is_strictfp, LIR_Opr tmp_op, CodeEmitInfo* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
514 LIR_Opr result_op = result;
a61af66fc99e Initial load
duke
parents:
diff changeset
515 LIR_Opr left_op = left;
a61af66fc99e Initial load
duke
parents:
diff changeset
516 LIR_Opr right_op = right;
a61af66fc99e Initial load
duke
parents:
diff changeset
517
a61af66fc99e Initial load
duke
parents:
diff changeset
518 if (TwoOperandLIRForm && left_op != result_op) {
a61af66fc99e Initial load
duke
parents:
diff changeset
519 assert(right_op != result_op, "malformed");
a61af66fc99e Initial load
duke
parents:
diff changeset
520 __ move(left_op, result_op);
a61af66fc99e Initial load
duke
parents:
diff changeset
521 left_op = result_op;
a61af66fc99e Initial load
duke
parents:
diff changeset
522 }
a61af66fc99e Initial load
duke
parents:
diff changeset
523
a61af66fc99e Initial load
duke
parents:
diff changeset
524 switch(code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
525 case Bytecodes::_dadd:
a61af66fc99e Initial load
duke
parents:
diff changeset
526 case Bytecodes::_fadd:
a61af66fc99e Initial load
duke
parents:
diff changeset
527 case Bytecodes::_ladd:
a61af66fc99e Initial load
duke
parents:
diff changeset
528 case Bytecodes::_iadd: __ add(left_op, right_op, result_op); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
529 case Bytecodes::_fmul:
a61af66fc99e Initial load
duke
parents:
diff changeset
530 case Bytecodes::_lmul: __ mul(left_op, right_op, result_op); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
531
a61af66fc99e Initial load
duke
parents:
diff changeset
532 case Bytecodes::_dmul:
a61af66fc99e Initial load
duke
parents:
diff changeset
533 {
a61af66fc99e Initial load
duke
parents:
diff changeset
534 if (is_strictfp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
535 __ mul_strictfp(left_op, right_op, result_op, tmp_op); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
536 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
537 __ mul(left_op, right_op, result_op); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
538 }
a61af66fc99e Initial load
duke
parents:
diff changeset
539 }
a61af66fc99e Initial load
duke
parents:
diff changeset
540 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
541
a61af66fc99e Initial load
duke
parents:
diff changeset
542 case Bytecodes::_imul:
a61af66fc99e Initial load
duke
parents:
diff changeset
543 {
a61af66fc99e Initial load
duke
parents:
diff changeset
544 bool did_strength_reduce = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
545
a61af66fc99e Initial load
duke
parents:
diff changeset
546 if (right->is_constant()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
547 int c = right->as_jint();
a61af66fc99e Initial load
duke
parents:
diff changeset
548 if (is_power_of_2(c)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
549 // do not need tmp here
a61af66fc99e Initial load
duke
parents:
diff changeset
550 __ shift_left(left_op, exact_log2(c), result_op);
a61af66fc99e Initial load
duke
parents:
diff changeset
551 did_strength_reduce = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
552 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
553 did_strength_reduce = strength_reduce_multiply(left_op, c, result_op, tmp_op);
a61af66fc99e Initial load
duke
parents:
diff changeset
554 }
a61af66fc99e Initial load
duke
parents:
diff changeset
555 }
a61af66fc99e Initial load
duke
parents:
diff changeset
556 // we couldn't strength reduce so just emit the multiply
a61af66fc99e Initial load
duke
parents:
diff changeset
557 if (!did_strength_reduce) {
a61af66fc99e Initial load
duke
parents:
diff changeset
558 __ mul(left_op, right_op, result_op);
a61af66fc99e Initial load
duke
parents:
diff changeset
559 }
a61af66fc99e Initial load
duke
parents:
diff changeset
560 }
a61af66fc99e Initial load
duke
parents:
diff changeset
561 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
562
a61af66fc99e Initial load
duke
parents:
diff changeset
563 case Bytecodes::_dsub:
a61af66fc99e Initial load
duke
parents:
diff changeset
564 case Bytecodes::_fsub:
a61af66fc99e Initial load
duke
parents:
diff changeset
565 case Bytecodes::_lsub:
a61af66fc99e Initial load
duke
parents:
diff changeset
566 case Bytecodes::_isub: __ sub(left_op, right_op, result_op); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
567
a61af66fc99e Initial load
duke
parents:
diff changeset
568 case Bytecodes::_fdiv: __ div (left_op, right_op, result_op); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
569 // ldiv and lrem are implemented with a direct runtime call
a61af66fc99e Initial load
duke
parents:
diff changeset
570
a61af66fc99e Initial load
duke
parents:
diff changeset
571 case Bytecodes::_ddiv:
a61af66fc99e Initial load
duke
parents:
diff changeset
572 {
a61af66fc99e Initial load
duke
parents:
diff changeset
573 if (is_strictfp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
574 __ div_strictfp (left_op, right_op, result_op, tmp_op); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
575 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
576 __ div (left_op, right_op, result_op); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
577 }
a61af66fc99e Initial load
duke
parents:
diff changeset
578 }
a61af66fc99e Initial load
duke
parents:
diff changeset
579 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
580
a61af66fc99e Initial load
duke
parents:
diff changeset
581 case Bytecodes::_drem:
a61af66fc99e Initial load
duke
parents:
diff changeset
582 case Bytecodes::_frem: __ rem (left_op, right_op, result_op); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
583
a61af66fc99e Initial load
duke
parents:
diff changeset
584 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
585 }
a61af66fc99e Initial load
duke
parents:
diff changeset
586 }
a61af66fc99e Initial load
duke
parents:
diff changeset
587
a61af66fc99e Initial load
duke
parents:
diff changeset
588
a61af66fc99e Initial load
duke
parents:
diff changeset
589 void LIRGenerator::arithmetic_op_int(Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, LIR_Opr tmp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
590 arithmetic_op(code, result, left, right, false, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
591 }
a61af66fc99e Initial load
duke
parents:
diff changeset
592
a61af66fc99e Initial load
duke
parents:
diff changeset
593
a61af66fc99e Initial load
duke
parents:
diff changeset
594 void LIRGenerator::arithmetic_op_long(Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, CodeEmitInfo* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
595 arithmetic_op(code, result, left, right, false, LIR_OprFact::illegalOpr, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
596 }
a61af66fc99e Initial load
duke
parents:
diff changeset
597
a61af66fc99e Initial load
duke
parents:
diff changeset
598
a61af66fc99e Initial load
duke
parents:
diff changeset
599 void LIRGenerator::arithmetic_op_fpu(Bytecodes::Code code, LIR_Opr result, LIR_Opr left, LIR_Opr right, bool is_strictfp, LIR_Opr tmp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
600 arithmetic_op(code, result, left, right, is_strictfp, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
601 }
a61af66fc99e Initial load
duke
parents:
diff changeset
602
a61af66fc99e Initial load
duke
parents:
diff changeset
603
a61af66fc99e Initial load
duke
parents:
diff changeset
604 void LIRGenerator::shift_op(Bytecodes::Code code, LIR_Opr result_op, LIR_Opr value, LIR_Opr count, LIR_Opr tmp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
605 if (TwoOperandLIRForm && value != result_op) {
a61af66fc99e Initial load
duke
parents:
diff changeset
606 assert(count != result_op, "malformed");
a61af66fc99e Initial load
duke
parents:
diff changeset
607 __ move(value, result_op);
a61af66fc99e Initial load
duke
parents:
diff changeset
608 value = result_op;
a61af66fc99e Initial load
duke
parents:
diff changeset
609 }
a61af66fc99e Initial load
duke
parents:
diff changeset
610
a61af66fc99e Initial load
duke
parents:
diff changeset
611 assert(count->is_constant() || count->is_register(), "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
612 switch(code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
613 case Bytecodes::_ishl:
a61af66fc99e Initial load
duke
parents:
diff changeset
614 case Bytecodes::_lshl: __ shift_left(value, count, result_op, tmp); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
615 case Bytecodes::_ishr:
a61af66fc99e Initial load
duke
parents:
diff changeset
616 case Bytecodes::_lshr: __ shift_right(value, count, result_op, tmp); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
617 case Bytecodes::_iushr:
a61af66fc99e Initial load
duke
parents:
diff changeset
618 case Bytecodes::_lushr: __ unsigned_shift_right(value, count, result_op, tmp); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
619 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
620 }
a61af66fc99e Initial load
duke
parents:
diff changeset
621 }
a61af66fc99e Initial load
duke
parents:
diff changeset
622
a61af66fc99e Initial load
duke
parents:
diff changeset
623
a61af66fc99e Initial load
duke
parents:
diff changeset
624 void LIRGenerator::logic_op (Bytecodes::Code code, LIR_Opr result_op, LIR_Opr left_op, LIR_Opr right_op) {
a61af66fc99e Initial load
duke
parents:
diff changeset
625 if (TwoOperandLIRForm && left_op != result_op) {
a61af66fc99e Initial load
duke
parents:
diff changeset
626 assert(right_op != result_op, "malformed");
a61af66fc99e Initial load
duke
parents:
diff changeset
627 __ move(left_op, result_op);
a61af66fc99e Initial load
duke
parents:
diff changeset
628 left_op = result_op;
a61af66fc99e Initial load
duke
parents:
diff changeset
629 }
a61af66fc99e Initial load
duke
parents:
diff changeset
630
a61af66fc99e Initial load
duke
parents:
diff changeset
631 switch(code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
632 case Bytecodes::_iand:
a61af66fc99e Initial load
duke
parents:
diff changeset
633 case Bytecodes::_land: __ logical_and(left_op, right_op, result_op); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
634
a61af66fc99e Initial load
duke
parents:
diff changeset
635 case Bytecodes::_ior:
a61af66fc99e Initial load
duke
parents:
diff changeset
636 case Bytecodes::_lor: __ logical_or(left_op, right_op, result_op); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
637
a61af66fc99e Initial load
duke
parents:
diff changeset
638 case Bytecodes::_ixor:
a61af66fc99e Initial load
duke
parents:
diff changeset
639 case Bytecodes::_lxor: __ logical_xor(left_op, right_op, result_op); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
640
a61af66fc99e Initial load
duke
parents:
diff changeset
641 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
642 }
a61af66fc99e Initial load
duke
parents:
diff changeset
643 }
a61af66fc99e Initial load
duke
parents:
diff changeset
644
a61af66fc99e Initial load
duke
parents:
diff changeset
645
a61af66fc99e Initial load
duke
parents:
diff changeset
646 void LIRGenerator::monitor_enter(LIR_Opr object, LIR_Opr lock, LIR_Opr hdr, LIR_Opr scratch, int monitor_no, CodeEmitInfo* info_for_exception, CodeEmitInfo* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
647 if (!GenerateSynchronizationCode) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
648 // for slow path, use debug info for state after successful locking
a61af66fc99e Initial load
duke
parents:
diff changeset
649 CodeStub* slow_path = new MonitorEnterStub(object, lock, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
650 __ load_stack_address_monitor(monitor_no, lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
651 // for handling NullPointerException, use debug info representing just the lock stack before this monitorenter
a61af66fc99e Initial load
duke
parents:
diff changeset
652 __ lock_object(hdr, object, lock, scratch, slow_path, info_for_exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
653 }
a61af66fc99e Initial load
duke
parents:
diff changeset
654
a61af66fc99e Initial load
duke
parents:
diff changeset
655
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
656 void LIRGenerator::monitor_exit(LIR_Opr object, LIR_Opr lock, LIR_Opr new_hdr, LIR_Opr scratch, int monitor_no) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
657 if (!GenerateSynchronizationCode) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
658 // setup registers
a61af66fc99e Initial load
duke
parents:
diff changeset
659 LIR_Opr hdr = lock;
a61af66fc99e Initial load
duke
parents:
diff changeset
660 lock = new_hdr;
a61af66fc99e Initial load
duke
parents:
diff changeset
661 CodeStub* slow_path = new MonitorExitStub(lock, UseFastLocking, monitor_no);
a61af66fc99e Initial load
duke
parents:
diff changeset
662 __ load_stack_address_monitor(monitor_no, lock);
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
663 __ unlock_object(hdr, object, lock, scratch, slow_path);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
664 }
a61af66fc99e Initial load
duke
parents:
diff changeset
665
20344
2fd0fd493045 8031994: java/lang/Character/CheckProp test times out
rbackman
parents: 17925
diff changeset
666 #ifndef PRODUCT
2fd0fd493045 8031994: java/lang/Character/CheckProp test times out
rbackman
parents: 17925
diff changeset
667 void LIRGenerator::print_if_not_loaded(const NewInstance* new_instance) {
2fd0fd493045 8031994: java/lang/Character/CheckProp test times out
rbackman
parents: 17925
diff changeset
668 if (PrintNotLoaded && !new_instance->klass()->is_loaded()) {
2fd0fd493045 8031994: java/lang/Character/CheckProp test times out
rbackman
parents: 17925
diff changeset
669 tty->print_cr(" ###class not loaded at new bci %d", new_instance->printable_bci());
2fd0fd493045 8031994: java/lang/Character/CheckProp test times out
rbackman
parents: 17925
diff changeset
670 } else if (PrintNotLoaded && (TieredCompilation && new_instance->is_unresolved())) {
2fd0fd493045 8031994: java/lang/Character/CheckProp test times out
rbackman
parents: 17925
diff changeset
671 tty->print_cr(" ###class not resolved at new bci %d", new_instance->printable_bci());
2fd0fd493045 8031994: java/lang/Character/CheckProp test times out
rbackman
parents: 17925
diff changeset
672 }
2fd0fd493045 8031994: java/lang/Character/CheckProp test times out
rbackman
parents: 17925
diff changeset
673 }
2fd0fd493045 8031994: java/lang/Character/CheckProp test times out
rbackman
parents: 17925
diff changeset
674 #endif
2fd0fd493045 8031994: java/lang/Character/CheckProp test times out
rbackman
parents: 17925
diff changeset
675
2fd0fd493045 8031994: java/lang/Character/CheckProp test times out
rbackman
parents: 17925
diff changeset
676 void LIRGenerator::new_instance(LIR_Opr dst, ciInstanceKlass* klass, bool is_unresolved, LIR_Opr scratch1, LIR_Opr scratch2, LIR_Opr scratch3, LIR_Opr scratch4, LIR_Opr klass_reg, CodeEmitInfo* info) {
2fd0fd493045 8031994: java/lang/Character/CheckProp test times out
rbackman
parents: 17925
diff changeset
677 klass2reg_with_patching(klass_reg, klass, info, is_unresolved);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
678 // If klass is not loaded we do not know if the klass has finalizers:
a61af66fc99e Initial load
duke
parents:
diff changeset
679 if (UseFastNewInstance && klass->is_loaded()
a61af66fc99e Initial load
duke
parents:
diff changeset
680 && !Klass::layout_helper_needs_slow_path(klass->layout_helper())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
681
a61af66fc99e Initial load
duke
parents:
diff changeset
682 Runtime1::StubID stub_id = klass->is_initialized() ? Runtime1::fast_new_instance_id : Runtime1::fast_new_instance_init_check_id;
a61af66fc99e Initial load
duke
parents:
diff changeset
683
a61af66fc99e Initial load
duke
parents:
diff changeset
684 CodeStub* slow_path = new NewInstanceStub(klass_reg, dst, klass, info, stub_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
685
a61af66fc99e Initial load
duke
parents:
diff changeset
686 assert(klass->is_loaded(), "must be loaded");
a61af66fc99e Initial load
duke
parents:
diff changeset
687 // allocate space for instance
a61af66fc99e Initial load
duke
parents:
diff changeset
688 assert(klass->size_helper() >= 0, "illegal instance size");
a61af66fc99e Initial load
duke
parents:
diff changeset
689 const int instance_size = align_object_size(klass->size_helper());
a61af66fc99e Initial load
duke
parents:
diff changeset
690 __ allocate_object(dst, scratch1, scratch2, scratch3, scratch4,
a61af66fc99e Initial load
duke
parents:
diff changeset
691 oopDesc::header_size(), instance_size, klass_reg, !klass->is_initialized(), slow_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
692 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
693 CodeStub* slow_path = new NewInstanceStub(klass_reg, dst, klass, info, Runtime1::new_instance_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
694 __ branch(lir_cond_always, T_ILLEGAL, slow_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
695 __ branch_destination(slow_path->continuation());
a61af66fc99e Initial load
duke
parents:
diff changeset
696 }
a61af66fc99e Initial load
duke
parents:
diff changeset
697 }
a61af66fc99e Initial load
duke
parents:
diff changeset
698
a61af66fc99e Initial load
duke
parents:
diff changeset
699
a61af66fc99e Initial load
duke
parents:
diff changeset
700 static bool is_constant_zero(Instruction* inst) {
a61af66fc99e Initial load
duke
parents:
diff changeset
701 IntConstant* c = inst->type()->as_IntConstant();
a61af66fc99e Initial load
duke
parents:
diff changeset
702 if (c) {
a61af66fc99e Initial load
duke
parents:
diff changeset
703 return (c->value() == 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
704 }
a61af66fc99e Initial load
duke
parents:
diff changeset
705 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
706 }
a61af66fc99e Initial load
duke
parents:
diff changeset
707
a61af66fc99e Initial load
duke
parents:
diff changeset
708
a61af66fc99e Initial load
duke
parents:
diff changeset
709 static bool positive_constant(Instruction* inst) {
a61af66fc99e Initial load
duke
parents:
diff changeset
710 IntConstant* c = inst->type()->as_IntConstant();
a61af66fc99e Initial load
duke
parents:
diff changeset
711 if (c) {
a61af66fc99e Initial load
duke
parents:
diff changeset
712 return (c->value() >= 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
713 }
a61af66fc99e Initial load
duke
parents:
diff changeset
714 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
715 }
a61af66fc99e Initial load
duke
parents:
diff changeset
716
a61af66fc99e Initial load
duke
parents:
diff changeset
717
a61af66fc99e Initial load
duke
parents:
diff changeset
718 static ciArrayKlass* as_array_klass(ciType* type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
719 if (type != NULL && type->is_array_klass() && type->is_loaded()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
720 return (ciArrayKlass*)type;
a61af66fc99e Initial load
duke
parents:
diff changeset
721 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
722 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
723 }
a61af66fc99e Initial load
duke
parents:
diff changeset
724 }
a61af66fc99e Initial load
duke
parents:
diff changeset
725
2446
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
726 static ciType* phi_declared_type(Phi* phi) {
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
727 ciType* t = phi->operand_at(0)->declared_type();
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
728 if (t == NULL) {
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
729 return NULL;
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
730 }
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
731 for(int i = 1; i < phi->operand_count(); i++) {
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
732 if (t != phi->operand_at(i)->declared_type()) {
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
733 return NULL;
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
734 }
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
735 }
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
736 return t;
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
737 }
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
738
0
a61af66fc99e Initial load
duke
parents:
diff changeset
739 void LIRGenerator::arraycopy_helper(Intrinsic* x, int* flagsp, ciArrayKlass** expected_typep) {
a61af66fc99e Initial load
duke
parents:
diff changeset
740 Instruction* src = x->argument_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
741 Instruction* src_pos = x->argument_at(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
742 Instruction* dst = x->argument_at(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
743 Instruction* dst_pos = x->argument_at(3);
a61af66fc99e Initial load
duke
parents:
diff changeset
744 Instruction* length = x->argument_at(4);
a61af66fc99e Initial load
duke
parents:
diff changeset
745
a61af66fc99e Initial load
duke
parents:
diff changeset
746 // first try to identify the likely type of the arrays involved
a61af66fc99e Initial load
duke
parents:
diff changeset
747 ciArrayKlass* expected_type = NULL;
2446
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
748 bool is_exact = false, src_objarray = false, dst_objarray = false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
749 {
a61af66fc99e Initial load
duke
parents:
diff changeset
750 ciArrayKlass* src_exact_type = as_array_klass(src->exact_type());
a61af66fc99e Initial load
duke
parents:
diff changeset
751 ciArrayKlass* src_declared_type = as_array_klass(src->declared_type());
2446
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
752 Phi* phi;
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
753 if (src_declared_type == NULL && (phi = src->as_Phi()) != NULL) {
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
754 src_declared_type = as_array_klass(phi_declared_type(phi));
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
755 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
756 ciArrayKlass* dst_exact_type = as_array_klass(dst->exact_type());
a61af66fc99e Initial load
duke
parents:
diff changeset
757 ciArrayKlass* dst_declared_type = as_array_klass(dst->declared_type());
2446
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
758 if (dst_declared_type == NULL && (phi = dst->as_Phi()) != NULL) {
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
759 dst_declared_type = as_array_klass(phi_declared_type(phi));
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
760 }
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
761
0
a61af66fc99e Initial load
duke
parents:
diff changeset
762 if (src_exact_type != NULL && src_exact_type == dst_exact_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
763 // the types exactly match so the type is fully known
a61af66fc99e Initial load
duke
parents:
diff changeset
764 is_exact = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
765 expected_type = src_exact_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
766 } else if (dst_exact_type != NULL && dst_exact_type->is_obj_array_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
767 ciArrayKlass* dst_type = (ciArrayKlass*) dst_exact_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
768 ciArrayKlass* src_type = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
769 if (src_exact_type != NULL && src_exact_type->is_obj_array_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
770 src_type = (ciArrayKlass*) src_exact_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
771 } else if (src_declared_type != NULL && src_declared_type->is_obj_array_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
772 src_type = (ciArrayKlass*) src_declared_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
773 }
a61af66fc99e Initial load
duke
parents:
diff changeset
774 if (src_type != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
775 if (src_type->element_type()->is_subtype_of(dst_type->element_type())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
776 is_exact = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
777 expected_type = dst_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
778 }
a61af66fc99e Initial load
duke
parents:
diff changeset
779 }
a61af66fc99e Initial load
duke
parents:
diff changeset
780 }
a61af66fc99e Initial load
duke
parents:
diff changeset
781 // at least pass along a good guess
a61af66fc99e Initial load
duke
parents:
diff changeset
782 if (expected_type == NULL) expected_type = dst_exact_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
783 if (expected_type == NULL) expected_type = src_declared_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
784 if (expected_type == NULL) expected_type = dst_declared_type;
2446
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
785
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
786 src_objarray = (src_exact_type && src_exact_type->is_obj_array_klass()) || (src_declared_type && src_declared_type->is_obj_array_klass());
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
787 dst_objarray = (dst_exact_type && dst_exact_type->is_obj_array_klass()) || (dst_declared_type && dst_declared_type->is_obj_array_klass());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
788 }
a61af66fc99e Initial load
duke
parents:
diff changeset
789
a61af66fc99e Initial load
duke
parents:
diff changeset
790 // if a probable array type has been identified, figure out if any
a61af66fc99e Initial load
duke
parents:
diff changeset
791 // of the required checks for a fast case can be elided.
a61af66fc99e Initial load
duke
parents:
diff changeset
792 int flags = LIR_OpArrayCopy::all_flags;
2446
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
793
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
794 if (!src_objarray)
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
795 flags &= ~LIR_OpArrayCopy::src_objarray;
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
796 if (!dst_objarray)
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
797 flags &= ~LIR_OpArrayCopy::dst_objarray;
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
798
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
799 if (!x->arg_needs_null_check(0))
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
800 flags &= ~LIR_OpArrayCopy::src_null_check;
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
801 if (!x->arg_needs_null_check(2))
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
802 flags &= ~LIR_OpArrayCopy::dst_null_check;
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
803
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
804
0
a61af66fc99e Initial load
duke
parents:
diff changeset
805 if (expected_type != NULL) {
2446
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
806 Value length_limit = NULL;
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
807
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
808 IfOp* ifop = length->as_IfOp();
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
809 if (ifop != NULL) {
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
810 // look for expressions like min(v, a.length) which ends up as
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
811 // x > y ? y : x or x >= y ? y : x
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
812 if ((ifop->cond() == If::gtr || ifop->cond() == If::geq) &&
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
813 ifop->x() == ifop->fval() &&
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
814 ifop->y() == ifop->tval()) {
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
815 length_limit = ifop->y();
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
816 }
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
817 }
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
818
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
819 // try to skip null checks and range checks
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
820 NewArray* src_array = src->as_NewArray();
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
821 if (src_array != NULL) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
822 flags &= ~LIR_OpArrayCopy::src_null_check;
2446
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
823 if (length_limit != NULL &&
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
824 src_array->length() == length_limit &&
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
825 is_constant_zero(src_pos)) {
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
826 flags &= ~LIR_OpArrayCopy::src_range_check;
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
827 }
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
828 }
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
829
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
830 NewArray* dst_array = dst->as_NewArray();
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
831 if (dst_array != NULL) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
832 flags &= ~LIR_OpArrayCopy::dst_null_check;
2446
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
833 if (length_limit != NULL &&
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
834 dst_array->length() == length_limit &&
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
835 is_constant_zero(dst_pos)) {
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
836 flags &= ~LIR_OpArrayCopy::dst_range_check;
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
837 }
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
838 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
839
a61af66fc99e Initial load
duke
parents:
diff changeset
840 // check from incoming constant values
a61af66fc99e Initial load
duke
parents:
diff changeset
841 if (positive_constant(src_pos))
a61af66fc99e Initial load
duke
parents:
diff changeset
842 flags &= ~LIR_OpArrayCopy::src_pos_positive_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
843 if (positive_constant(dst_pos))
a61af66fc99e Initial load
duke
parents:
diff changeset
844 flags &= ~LIR_OpArrayCopy::dst_pos_positive_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
845 if (positive_constant(length))
a61af66fc99e Initial load
duke
parents:
diff changeset
846 flags &= ~LIR_OpArrayCopy::length_positive_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
847
a61af66fc99e Initial load
duke
parents:
diff changeset
848 // see if the range check can be elided, which might also imply
a61af66fc99e Initial load
duke
parents:
diff changeset
849 // that src or dst is non-null.
a61af66fc99e Initial load
duke
parents:
diff changeset
850 ArrayLength* al = length->as_ArrayLength();
a61af66fc99e Initial load
duke
parents:
diff changeset
851 if (al != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
852 if (al->array() == src) {
a61af66fc99e Initial load
duke
parents:
diff changeset
853 // it's the length of the source array
a61af66fc99e Initial load
duke
parents:
diff changeset
854 flags &= ~LIR_OpArrayCopy::length_positive_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
855 flags &= ~LIR_OpArrayCopy::src_null_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
856 if (is_constant_zero(src_pos))
a61af66fc99e Initial load
duke
parents:
diff changeset
857 flags &= ~LIR_OpArrayCopy::src_range_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
858 }
a61af66fc99e Initial load
duke
parents:
diff changeset
859 if (al->array() == dst) {
a61af66fc99e Initial load
duke
parents:
diff changeset
860 // it's the length of the destination array
a61af66fc99e Initial load
duke
parents:
diff changeset
861 flags &= ~LIR_OpArrayCopy::length_positive_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
862 flags &= ~LIR_OpArrayCopy::dst_null_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
863 if (is_constant_zero(dst_pos))
a61af66fc99e Initial load
duke
parents:
diff changeset
864 flags &= ~LIR_OpArrayCopy::dst_range_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
865 }
a61af66fc99e Initial load
duke
parents:
diff changeset
866 }
a61af66fc99e Initial load
duke
parents:
diff changeset
867 if (is_exact) {
a61af66fc99e Initial load
duke
parents:
diff changeset
868 flags &= ~LIR_OpArrayCopy::type_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
869 }
a61af66fc99e Initial load
duke
parents:
diff changeset
870 }
a61af66fc99e Initial load
duke
parents:
diff changeset
871
2446
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
872 IntConstant* src_int = src_pos->type()->as_IntConstant();
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
873 IntConstant* dst_int = dst_pos->type()->as_IntConstant();
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
874 if (src_int && dst_int) {
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
875 int s_offs = src_int->value();
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
876 int d_offs = dst_int->value();
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
877 if (src_int->value() >= dst_int->value()) {
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
878 flags &= ~LIR_OpArrayCopy::overlapping;
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
879 }
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
880 if (expected_type != NULL) {
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
881 BasicType t = expected_type->element_type()->basic_type();
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
882 int element_size = type2aelembytes(t);
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
883 if (((arrayOopDesc::base_offset_in_bytes(t) + s_offs * element_size) % HeapWordSize == 0) &&
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
884 ((arrayOopDesc::base_offset_in_bytes(t) + d_offs * element_size) % HeapWordSize == 0)) {
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
885 flags &= ~LIR_OpArrayCopy::unaligned;
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
886 }
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
887 }
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
888 } else if (src_pos == dst_pos || is_constant_zero(dst_pos)) {
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
889 // src and dest positions are the same, or dst is zero so assume
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
890 // nonoverlapping copy.
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
891 flags &= ~LIR_OpArrayCopy::overlapping;
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
892 }
13bc79b5c9c8 7033154: Improve C1 arraycopy performance
roland
parents: 2357
diff changeset
893
0
a61af66fc99e Initial load
duke
parents:
diff changeset
894 if (src == dst) {
a61af66fc99e Initial load
duke
parents:
diff changeset
895 // moving within a single array so no type checks are needed
a61af66fc99e Initial load
duke
parents:
diff changeset
896 if (flags & LIR_OpArrayCopy::type_check) {
a61af66fc99e Initial load
duke
parents:
diff changeset
897 flags &= ~LIR_OpArrayCopy::type_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
898 }
a61af66fc99e Initial load
duke
parents:
diff changeset
899 }
a61af66fc99e Initial load
duke
parents:
diff changeset
900 *flagsp = flags;
a61af66fc99e Initial load
duke
parents:
diff changeset
901 *expected_typep = (ciArrayKlass*)expected_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
902 }
a61af66fc99e Initial load
duke
parents:
diff changeset
903
a61af66fc99e Initial load
duke
parents:
diff changeset
904
a61af66fc99e Initial load
duke
parents:
diff changeset
905 LIR_Opr LIRGenerator::round_item(LIR_Opr opr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
906 assert(opr->is_register(), "why spill if item is not register?");
a61af66fc99e Initial load
duke
parents:
diff changeset
907
a61af66fc99e Initial load
duke
parents:
diff changeset
908 if (RoundFPResults && UseSSE < 1 && opr->is_single_fpu()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
909 LIR_Opr result = new_register(T_FLOAT);
a61af66fc99e Initial load
duke
parents:
diff changeset
910 set_vreg_flag(result, must_start_in_memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
911 assert(opr->is_register(), "only a register can be spilled");
a61af66fc99e Initial load
duke
parents:
diff changeset
912 assert(opr->value_type()->is_float(), "rounding only for floats available");
a61af66fc99e Initial load
duke
parents:
diff changeset
913 __ roundfp(opr, LIR_OprFact::illegalOpr, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
914 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
915 }
a61af66fc99e Initial load
duke
parents:
diff changeset
916 return opr;
a61af66fc99e Initial load
duke
parents:
diff changeset
917 }
a61af66fc99e Initial load
duke
parents:
diff changeset
918
a61af66fc99e Initial load
duke
parents:
diff changeset
919
a61af66fc99e Initial load
duke
parents:
diff changeset
920 LIR_Opr LIRGenerator::force_to_spill(LIR_Opr value, BasicType t) {
6616
7a302948f5a4 7192167: JSR 292: C1 has old broken code which needs to be removed
twisti
parents: 6615
diff changeset
921 assert(type2size[t] == type2size[value->type()],
7a302948f5a4 7192167: JSR 292: C1 has old broken code which needs to be removed
twisti
parents: 6615
diff changeset
922 err_msg_res("size mismatch: t=%s, value->type()=%s", type2name(t), type2name(value->type())));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
923 if (!value->is_register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
924 // force into a register
a61af66fc99e Initial load
duke
parents:
diff changeset
925 LIR_Opr r = new_register(value->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
926 __ move(value, r);
a61af66fc99e Initial load
duke
parents:
diff changeset
927 value = r;
a61af66fc99e Initial load
duke
parents:
diff changeset
928 }
a61af66fc99e Initial load
duke
parents:
diff changeset
929
a61af66fc99e Initial load
duke
parents:
diff changeset
930 // create a spill location
a61af66fc99e Initial load
duke
parents:
diff changeset
931 LIR_Opr tmp = new_register(t);
a61af66fc99e Initial load
duke
parents:
diff changeset
932 set_vreg_flag(tmp, LIRGenerator::must_start_in_memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
933
a61af66fc99e Initial load
duke
parents:
diff changeset
934 // move from register to spill
a61af66fc99e Initial load
duke
parents:
diff changeset
935 __ move(value, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
936 return tmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
937 }
a61af66fc99e Initial load
duke
parents:
diff changeset
938
a61af66fc99e Initial load
duke
parents:
diff changeset
939 void LIRGenerator::profile_branch(If* if_instr, If::Condition cond) {
a61af66fc99e Initial load
duke
parents:
diff changeset
940 if (if_instr->should_profile()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
941 ciMethod* method = if_instr->profiled_method();
a61af66fc99e Initial load
duke
parents:
diff changeset
942 assert(method != NULL, "method should be set if branch is profiled");
2007
5ddfcf4b079e 7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents: 2002
diff changeset
943 ciMethodData* md = method->method_data_or_null();
5ddfcf4b079e 7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents: 2002
diff changeset
944 assert(md != NULL, "Sanity");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
945 ciProfileData* data = md->bci_to_data(if_instr->profiled_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
946 assert(data != NULL, "must have profiling data");
a61af66fc99e Initial load
duke
parents:
diff changeset
947 assert(data->is_BranchData(), "need BranchData for two-way branches");
a61af66fc99e Initial load
duke
parents:
diff changeset
948 int taken_count_offset = md->byte_offset_of_slot(data, BranchData::taken_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
949 int not_taken_count_offset = md->byte_offset_of_slot(data, BranchData::not_taken_offset());
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
950 if (if_instr->is_swapped()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
951 int t = taken_count_offset;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
952 taken_count_offset = not_taken_count_offset;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
953 not_taken_count_offset = t;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
954 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
955
6739
8a02ca5e5576 7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents: 6731
diff changeset
956 LIR_Opr md_reg = new_register(T_METADATA);
8a02ca5e5576 7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents: 6731
diff changeset
957 __ metadata2reg(md->constant_encoding(), md_reg);
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
958
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
959 LIR_Opr data_offset_reg = new_pointer_register();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
960 __ cmove(lir_cond(cond),
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
961 LIR_OprFact::intptrConst(taken_count_offset),
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
962 LIR_OprFact::intptrConst(not_taken_count_offset),
2089
037c727f35fb 7009231: C1: Incorrect CAS code for longs on SPARC 32bit
iveresov
parents: 2007
diff changeset
963 data_offset_reg, as_BasicType(if_instr->x()->type()));
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
964
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
965 // MDO cells are intptr_t, so the data_reg width is arch-dependent.
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
966 LIR_Opr data_reg = new_pointer_register();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
967 LIR_Address* data_addr = new LIR_Address(md_reg, data_offset_reg, data_reg->type());
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
968 __ move(data_addr, data_reg);
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
969 // Use leal instead of add to avoid destroying condition codes on x86
0
a61af66fc99e Initial load
duke
parents:
diff changeset
970 LIR_Address* fake_incr_value = new LIR_Address(data_reg, DataLayout::counter_increment, T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
971 __ leal(LIR_OprFact::address(fake_incr_value), data_reg);
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
972 __ move(data_reg, data_addr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
973 }
a61af66fc99e Initial load
duke
parents:
diff changeset
974 }
a61af66fc99e Initial load
duke
parents:
diff changeset
975
a61af66fc99e Initial load
duke
parents:
diff changeset
976 // Phi technique:
a61af66fc99e Initial load
duke
parents:
diff changeset
977 // This is about passing live values from one basic block to the other.
a61af66fc99e Initial load
duke
parents:
diff changeset
978 // In code generated with Java it is rather rare that more than one
a61af66fc99e Initial load
duke
parents:
diff changeset
979 // value is on the stack from one basic block to the other.
a61af66fc99e Initial load
duke
parents:
diff changeset
980 // We optimize our technique for efficient passing of one value
a61af66fc99e Initial load
duke
parents:
diff changeset
981 // (of type long, int, double..) but it can be extended.
a61af66fc99e Initial load
duke
parents:
diff changeset
982 // When entering or leaving a basic block, all registers and all spill
a61af66fc99e Initial load
duke
parents:
diff changeset
983 // slots are release and empty. We use the released registers
a61af66fc99e Initial load
duke
parents:
diff changeset
984 // and spill slots to pass the live values from one block
a61af66fc99e Initial load
duke
parents:
diff changeset
985 // to the other. The topmost value, i.e., the value on TOS of expression
a61af66fc99e Initial load
duke
parents:
diff changeset
986 // stack is passed in registers. All other values are stored in spilling
a61af66fc99e Initial load
duke
parents:
diff changeset
987 // area. Every Phi has an index which designates its spill slot
a61af66fc99e Initial load
duke
parents:
diff changeset
988 // At exit of a basic block, we fill the register(s) and spill slots.
a61af66fc99e Initial load
duke
parents:
diff changeset
989 // At entry of a basic block, the block_prolog sets up the content of phi nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
990 // and locks necessary registers and spilling slots.
a61af66fc99e Initial load
duke
parents:
diff changeset
991
a61af66fc99e Initial load
duke
parents:
diff changeset
992
a61af66fc99e Initial load
duke
parents:
diff changeset
993 // move current value to referenced phi function
a61af66fc99e Initial load
duke
parents:
diff changeset
994 void LIRGenerator::move_to_phi(PhiResolver* resolver, Value cur_val, Value sux_val) {
a61af66fc99e Initial load
duke
parents:
diff changeset
995 Phi* phi = sux_val->as_Phi();
a61af66fc99e Initial load
duke
parents:
diff changeset
996 // cur_val can be null without phi being null in conjunction with inlining
a61af66fc99e Initial load
duke
parents:
diff changeset
997 if (phi != NULL && cur_val != NULL && cur_val != phi && !phi->is_illegal()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
998 LIR_Opr operand = cur_val->operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
999 if (cur_val->operand()->is_illegal()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 assert(cur_val->as_Constant() != NULL || cur_val->as_Local() != NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 "these can be produced lazily");
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 operand = operand_for_instruction(cur_val);
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 resolver->move(operand, operand_for_instruction(phi));
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1007
a61af66fc99e Initial load
duke
parents:
diff changeset
1008
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 // Moves all stack values into their PHI position
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 void LIRGenerator::move_to_phi(ValueStack* cur_state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 BlockBegin* bb = block();
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 if (bb->number_of_sux() == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 BlockBegin* sux = bb->sux_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 assert(sux->number_of_preds() > 0, "invalid CFG");
a61af66fc99e Initial load
duke
parents:
diff changeset
1015
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 // a block with only one predecessor never has phi functions
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 if (sux->number_of_preds() > 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 int max_phis = cur_state->stack_size() + cur_state->locals_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 PhiResolver resolver(this, _virtual_register_number + max_phis * 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1020
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 ValueStack* sux_state = sux->state();
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 Value sux_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 int index;
a61af66fc99e Initial load
duke
parents:
diff changeset
1024
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
1025 assert(cur_state->scope() == sux_state->scope(), "not matching");
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
1026 assert(cur_state->locals_size() == sux_state->locals_size(), "not matching");
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
1027 assert(cur_state->stack_size() == sux_state->stack_size(), "not matching");
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
1028
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 for_each_stack_value(sux_state, index, sux_value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 move_to_phi(&resolver, cur_state->stack_at(index), sux_value);
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1032
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 for_each_local_value(sux_state, index, sux_value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 move_to_phi(&resolver, cur_state->local_at(index), sux_value);
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1036
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 assert(cur_state->caller_state() == sux_state->caller_state(), "caller states must be equal");
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1041
a61af66fc99e Initial load
duke
parents:
diff changeset
1042
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 LIR_Opr LIRGenerator::new_register(BasicType type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 int vreg = _virtual_register_number;
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 // add a little fudge factor for the bailout, since the bailout is
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 // only checked periodically. This gives a few extra registers to
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 // hand out before we really run out, which helps us keep from
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 // tripping over assertions.
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 if (vreg + 20 >= LIR_OprDesc::vreg_max) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 bailout("out of virtual registers");
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 if (vreg + 2 >= LIR_OprDesc::vreg_max) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 // wrap it around
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 _virtual_register_number = LIR_OprDesc::vreg_base;
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 _virtual_register_number += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 return LIR_OprFact::virtual_register(vreg, type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1059
a61af66fc99e Initial load
duke
parents:
diff changeset
1060
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 // Try to lock using register in hint
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 LIR_Opr LIRGenerator::rlock(Value instr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 return new_register(instr->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1065
a61af66fc99e Initial load
duke
parents:
diff changeset
1066
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 // does an rlock and sets result
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 LIR_Opr LIRGenerator::rlock_result(Value x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 LIR_Opr reg = rlock(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 set_result(x, reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 return reg;
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1073
a61af66fc99e Initial load
duke
parents:
diff changeset
1074
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 // does an rlock and sets result
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 LIR_Opr LIRGenerator::rlock_result(Value x, BasicType type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 LIR_Opr reg;
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 switch (type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 case T_BYTE:
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 case T_BOOLEAN:
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 reg = rlock_byte(type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 reg = rlock(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1087
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 set_result(x, reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 return reg;
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1091
a61af66fc99e Initial load
duke
parents:
diff changeset
1092
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 //---------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 ciObject* LIRGenerator::get_jobject_constant(Value value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 ObjectType* oc = value->type()->as_ObjectType();
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 if (oc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 return oc->constant_value();
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1101
a61af66fc99e Initial load
duke
parents:
diff changeset
1102
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 void LIRGenerator::do_ExceptionObject(ExceptionObject* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 assert(block()->is_set(BlockBegin::exception_entry_flag), "ExceptionObject only allowed in exception handler block");
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 assert(block()->next() == x, "ExceptionObject must be first instruction of block");
a61af66fc99e Initial load
duke
parents:
diff changeset
1106
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 // no moves are created for phi functions at the begin of exception
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 // handlers, so assign operands manually here
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 for_each_phi_fun(block(), phi,
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 operand_for_instruction(phi));
a61af66fc99e Initial load
duke
parents:
diff changeset
1111
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 LIR_Opr thread_reg = getThreadPointer();
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1113 __ move_wide(new LIR_Address(thread_reg, in_bytes(JavaThread::exception_oop_offset()), T_OBJECT),
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1114 exceptionOopOpr());
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1115 __ move_wide(LIR_OprFact::oopConst(NULL),
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1116 new LIR_Address(thread_reg, in_bytes(JavaThread::exception_oop_offset()), T_OBJECT));
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1117 __ move_wide(LIR_OprFact::oopConst(NULL),
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1118 new LIR_Address(thread_reg, in_bytes(JavaThread::exception_pc_offset()), T_OBJECT));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1119
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 LIR_Opr result = new_register(T_OBJECT);
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 __ move(exceptionOopOpr(), result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 set_result(x, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1124
a61af66fc99e Initial load
duke
parents:
diff changeset
1125
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 // visitor functions
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1135
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 void LIRGenerator::do_Phi(Phi* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 // phi functions are never visited directly
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1140
a61af66fc99e Initial load
duke
parents:
diff changeset
1141
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 // Code for a constant is generated lazily unless the constant is frequently used and can't be inlined.
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 void LIRGenerator::do_Constant(Constant* x) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
1144 if (x->state_before() != NULL) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 // Any constant with a ValueStack requires patching so emit the patch here
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 LIR_Opr reg = rlock_result(x);
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
1147 CodeEmitInfo* info = state_for(x, x->state_before());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 __ oop2reg_patch(NULL, reg, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 } else if (x->use_count() > 1 && !can_inline_as_constant(x)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 if (!x->is_pinned()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 // unpinned constants are handled specially so that they can be
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 // put into registers when they are used multiple times within a
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 // block. After the block completes their operand will be
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 // cleared so that other blocks can't refer to that register.
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 set_result(x, load_constant(x));
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 LIR_Opr res = x->operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 if (!res->is_valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 res = LIR_OprFact::value_type(x->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 if (res->is_constant()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 LIR_Opr reg = rlock_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 __ move(res, reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 set_result(x, res);
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 set_result(x, LIR_OprFact::value_type(x->type()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1172
a61af66fc99e Initial load
duke
parents:
diff changeset
1173
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 void LIRGenerator::do_Local(Local* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 // operand_for_instruction has the side effect of setting the result
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 // so there's no need to do it here.
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 operand_for_instruction(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1179
a61af66fc99e Initial load
duke
parents:
diff changeset
1180
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 void LIRGenerator::do_IfInstanceOf(IfInstanceOf* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 Unimplemented();
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1184
a61af66fc99e Initial load
duke
parents:
diff changeset
1185
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 void LIRGenerator::do_Return(Return* x) {
780
c96bf21b756f 6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents: 579
diff changeset
1187 if (compilation()->env()->dtrace_method_probes()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 BasicTypeList signature;
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1189 signature.append(LP64_ONLY(T_LONG) NOT_LP64(T_INT)); // thread
12969
9acbfe04b5c3 8026495: JVM Crashes when started with -XX:+DTraceMethodProbes on Solaris x86_64
iveresov
parents: 12962
diff changeset
1190 signature.append(T_METADATA); // Method*
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 LIR_OprList* args = new LIR_OprList();
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 args->append(getThreadPointer());
6739
8a02ca5e5576 7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents: 6731
diff changeset
1193 LIR_Opr meth = new_register(T_METADATA);
8a02ca5e5576 7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents: 6731
diff changeset
1194 __ metadata2reg(method()->constant_encoding(), meth);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 args->append(meth);
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 call_runtime(&signature, args, CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), voidType, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1198
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 if (x->type()->is_void()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 __ return_op(LIR_OprFact::illegalOpr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 LIR_Opr reg = result_register_for(x->type(), /*callee=*/true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 LIRItem result(x->result(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1204
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 result.load_item_force(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 __ return_op(result.result());
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 set_no_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1210
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1211 // Examble: ref.get()
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1212 // Combination of LoadField and g1 pre-write barrier
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1213 void LIRGenerator::do_Reference_get(Intrinsic* x) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1214
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1215 const int referent_offset = java_lang_ref_Reference::referent_offset;
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1216 guarantee(referent_offset > 0, "referent offset not initialized");
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1217
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1218 assert(x->number_of_arguments() == 1, "wrong type");
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1219
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1220 LIRItem reference(x->argument_at(0), this);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1221 reference.load_item();
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1222
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1223 // need to perform the null check on the reference objecy
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1224 CodeEmitInfo* info = NULL;
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1225 if (x->needs_null_check()) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1226 info = state_for(x);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1227 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1228
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1229 LIR_Address* referent_field_adr =
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1230 new LIR_Address(reference.result(), referent_offset, T_OBJECT);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1231
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1232 LIR_Opr result = rlock_result(x);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1233
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1234 __ load(referent_field_adr, result, info);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1235
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1236 // Register the value in the referent field with the pre-barrier
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1237 pre_barrier(LIR_OprFact::illegalOpr /* addr_opr */,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1238 result /* pre_val */,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1239 false /* do_load */,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1240 false /* patch */,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1241 NULL /* info */);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1242 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1243
6135
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
1244 // Example: clazz.isInstance(object)
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
1245 void LIRGenerator::do_isInstance(Intrinsic* x) {
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
1246 assert(x->number_of_arguments() == 2, "wrong type");
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
1247
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
1248 // TODO could try to substitute this node with an equivalent InstanceOf
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
1249 // if clazz is known to be a constant Class. This will pick up newly found
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
1250 // constants after HIR construction. I'll leave this to a future change.
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
1251
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
1252 // as a first cut, make a simple leaf call to runtime to stay platform independent.
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
1253 // could follow the aastore example in a future change.
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
1254
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
1255 LIRItem clazz(x->argument_at(0), this);
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
1256 LIRItem object(x->argument_at(1), this);
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
1257 clazz.load_item();
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
1258 object.load_item();
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
1259 LIR_Opr result = rlock_result(x);
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
1260
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
1261 // need to perform null check on clazz
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
1262 if (x->needs_null_check()) {
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
1263 CodeEmitInfo* info = state_for(x);
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
1264 __ null_check(clazz.result(), info);
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
1265 }
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
1266
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
1267 LIR_Opr call_result = call_runtime(clazz.value(), object.value(),
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
1268 CAST_FROM_FN_PTR(address, Runtime1::is_instance_of),
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
1269 x->type(),
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
1270 NULL); // NULL CodeEmitInfo results in a leaf call
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
1271 __ move(call_result, result);
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
1272 }
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
1273
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 // Example: object.getClass ()
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 void LIRGenerator::do_getClass(Intrinsic* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 assert(x->number_of_arguments() == 1, "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
1277
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 LIRItem rcvr(x->argument_at(0), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 rcvr.load_item();
12955
252d541466ea 8008242: VerifyOops is broken on SPARC
morris
parents: 12882
diff changeset
1280 LIR_Opr temp = new_register(T_METADATA);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 LIR_Opr result = rlock_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1282
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 // need to perform the null check on the rcvr
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 CodeEmitInfo* info = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 if (x->needs_null_check()) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
1286 info = state_for(x);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 }
12955
252d541466ea 8008242: VerifyOops is broken on SPARC
morris
parents: 12882
diff changeset
1288
252d541466ea 8008242: VerifyOops is broken on SPARC
morris
parents: 12882
diff changeset
1289 // FIXME T_ADDRESS should actually be T_METADATA but it can't because the
252d541466ea 8008242: VerifyOops is broken on SPARC
morris
parents: 12882
diff changeset
1290 // meaning of these two is mixed up (see JDK-8026837).
252d541466ea 8008242: VerifyOops is broken on SPARC
morris
parents: 12882
diff changeset
1291 __ move(new LIR_Address(rcvr.result(), oopDesc::klass_offset_in_bytes(), T_ADDRESS), temp, info);
252d541466ea 8008242: VerifyOops is broken on SPARC
morris
parents: 12882
diff changeset
1292 __ move_wide(new LIR_Address(temp, in_bytes(Klass::java_mirror_offset()), T_OBJECT), result);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1294
a61af66fc99e Initial load
duke
parents:
diff changeset
1295
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 // Example: Thread.currentThread()
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 void LIRGenerator::do_currentThread(Intrinsic* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 assert(x->number_of_arguments() == 0, "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 LIR_Opr reg = rlock_result(x);
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1300 __ move_wide(new LIR_Address(getThreadPointer(), in_bytes(JavaThread::threadObj_offset()), T_OBJECT), reg);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1302
a61af66fc99e Initial load
duke
parents:
diff changeset
1303
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 void LIRGenerator::do_RegisterFinalizer(Intrinsic* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 assert(x->number_of_arguments() == 1, "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 LIRItem receiver(x->argument_at(0), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1307
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 receiver.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 BasicTypeList signature;
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 signature.append(T_OBJECT); // receiver
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 LIR_OprList* args = new LIR_OprList();
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 args->append(receiver.result());
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 CodeEmitInfo* info = state_for(x, x->state());
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 call_runtime(&signature, args,
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 CAST_FROM_FN_PTR(address, Runtime1::entry_for(Runtime1::register_finalizer_id)),
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 voidType, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1317
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 set_no_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1320
a61af66fc99e Initial load
duke
parents:
diff changeset
1321
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 //------------------------local access--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1323
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 LIR_Opr LIRGenerator::operand_for_instruction(Instruction* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 if (x->operand()->is_illegal()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 Constant* c = x->as_Constant();
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 if (c != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 x->set_operand(LIR_OprFact::value_type(c->type()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 assert(x->as_Phi() || x->as_Local() != NULL, "only for Phi and Local");
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 // allocate a virtual register for this local or phi
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 x->set_operand(rlock(x));
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 _instruction_for_operand.at_put_grow(x->operand()->vreg_number(), x, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 return x->operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1338
a61af66fc99e Initial load
duke
parents:
diff changeset
1339
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 Instruction* LIRGenerator::instruction_for_opr(LIR_Opr opr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 if (opr->is_virtual()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 return instruction_for_vreg(opr->vreg_number());
a61af66fc99e Initial load
duke
parents:
diff changeset
1343 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1346
a61af66fc99e Initial load
duke
parents:
diff changeset
1347
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 Instruction* LIRGenerator::instruction_for_vreg(int reg_num) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 if (reg_num < _instruction_for_operand.length()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 return _instruction_for_operand.at(reg_num);
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1354
a61af66fc99e Initial load
duke
parents:
diff changeset
1355
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 void LIRGenerator::set_vreg_flag(int vreg_num, VregFlag f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 if (_vreg_flags.size_in_bits() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 BitMap2D temp(100, num_vreg_flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 temp.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 _vreg_flags = temp;
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 _vreg_flags.at_put_grow(vreg_num, f, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1364
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 bool LIRGenerator::is_vreg_flag_set(int vreg_num, VregFlag f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 if (!_vreg_flags.is_valid_index(vreg_num, f)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 return _vreg_flags.at(vreg_num, f);
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1371
a61af66fc99e Initial load
duke
parents:
diff changeset
1372
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 // Block local constant handling. This code is useful for keeping
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 // unpinned constants and constants which aren't exposed in the IR in
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 // registers. Unpinned Constant instructions have their operands
a61af66fc99e Initial load
duke
parents:
diff changeset
1376 // cleared when the block is finished so that other blocks can't end
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 // up referring to their registers.
a61af66fc99e Initial load
duke
parents:
diff changeset
1378
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 LIR_Opr LIRGenerator::load_constant(Constant* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 assert(!x->is_pinned(), "only for unpinned constants");
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 _unpinned_constants.append(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 return load_constant(LIR_OprFact::value_type(x->type())->as_constant_ptr());
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1384
a61af66fc99e Initial load
duke
parents:
diff changeset
1385
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 LIR_Opr LIRGenerator::load_constant(LIR_Const* c) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 BasicType t = c->type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 for (int i = 0; i < _constants.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 LIR_Const* other = _constants.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1390 if (t == other->type()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 switch (t) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 case T_INT:
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 case T_FLOAT:
a61af66fc99e Initial load
duke
parents:
diff changeset
1394 if (c->as_jint_bits() != other->as_jint_bits()) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 case T_LONG:
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 case T_DOUBLE:
486
a738a625039a 6757316: load_constant() produces a wrong long constant, with high a low words swapped
never
parents: 380
diff changeset
1398 if (c->as_jint_hi_bits() != other->as_jint_hi_bits()) continue;
a738a625039a 6757316: load_constant() produces a wrong long constant, with high a low words swapped
never
parents: 380
diff changeset
1399 if (c->as_jint_lo_bits() != other->as_jint_lo_bits()) continue;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1400 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 case T_OBJECT:
a61af66fc99e Initial load
duke
parents:
diff changeset
1402 if (c->as_jobject() != other->as_jobject()) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1404 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 return _reg_for_constants.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1408
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 LIR_Opr result = new_register(t);
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 __ move((LIR_Opr)c, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1411 _constants.append(c);
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 _reg_for_constants.append(result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
1414 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1415
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 // Various barriers
a61af66fc99e Initial load
duke
parents:
diff changeset
1417
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1418 void LIRGenerator::pre_barrier(LIR_Opr addr_opr, LIR_Opr pre_val,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1419 bool do_load, bool patch, CodeEmitInfo* info) {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1420 // Do the pre-write barrier, if any.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1421 switch (_bs->kind()) {
8001
db9981fd3124 8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents: 7425
diff changeset
1422 #if INCLUDE_ALL_GCS
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1423 case BarrierSet::G1SATBCT:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1424 case BarrierSet::G1SATBCTLogging:
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1425 G1SATBCardTableModRef_pre_barrier(addr_opr, pre_val, do_load, patch, info);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1426 break;
8001
db9981fd3124 8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents: 7425
diff changeset
1427 #endif // INCLUDE_ALL_GCS
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1428 case BarrierSet::CardTableModRef:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1429 case BarrierSet::CardTableExtension:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1430 // No pre barriers
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1431 break;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1432 case BarrierSet::ModRef:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1433 case BarrierSet::Other:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1434 // No pre barriers
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1435 break;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1436 default :
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1437 ShouldNotReachHere();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1438
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1439 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1440 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1441
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1442 void LIRGenerator::post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1443 switch (_bs->kind()) {
8001
db9981fd3124 8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents: 7425
diff changeset
1444 #if INCLUDE_ALL_GCS
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1445 case BarrierSet::G1SATBCT:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1446 case BarrierSet::G1SATBCTLogging:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1447 G1SATBCardTableModRef_post_barrier(addr, new_val);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1448 break;
8001
db9981fd3124 8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents: 7425
diff changeset
1449 #endif // INCLUDE_ALL_GCS
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 case BarrierSet::CardTableModRef:
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 case BarrierSet::CardTableExtension:
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 CardTableModRef_post_barrier(addr, new_val);
a61af66fc99e Initial load
duke
parents:
diff changeset
1453 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 case BarrierSet::ModRef:
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 case BarrierSet::Other:
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 // No post barriers
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1458 default :
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1462
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1463 ////////////////////////////////////////////////////////////////////////
8001
db9981fd3124 8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents: 7425
diff changeset
1464 #if INCLUDE_ALL_GCS
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1465
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1466 void LIRGenerator::G1SATBCardTableModRef_pre_barrier(LIR_Opr addr_opr, LIR_Opr pre_val,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1467 bool do_load, bool patch, CodeEmitInfo* info) {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1468 // First we test whether marking is in progress.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1469 BasicType flag_type;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1470 if (in_bytes(PtrQueue::byte_width_of_active()) == 4) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1471 flag_type = T_INT;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1472 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1473 guarantee(in_bytes(PtrQueue::byte_width_of_active()) == 1,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1474 "Assumption");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1475 flag_type = T_BYTE;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1476 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1477 LIR_Opr thrd = getThreadPointer();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1478 LIR_Address* mark_active_flag_addr =
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1479 new LIR_Address(thrd,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1480 in_bytes(JavaThread::satb_mark_queue_offset() +
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1481 PtrQueue::byte_offset_of_active()),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1482 flag_type);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1483 // Read the marking-in-progress flag.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1484 LIR_Opr flag_val = new_register(T_INT);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1485 __ load(mark_active_flag_addr, flag_val);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1486 __ cmp(lir_cond_notEqual, flag_val, LIR_OprFact::intConst(0));
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1487
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1488 LIR_PatchCode pre_val_patch_code = lir_patch_none;
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1489
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1490 CodeStub* slow;
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1491
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1492 if (do_load) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1493 assert(pre_val == LIR_OprFact::illegalOpr, "sanity");
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1494 assert(addr_opr != LIR_OprFact::illegalOpr, "sanity");
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1495
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1496 if (patch)
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1497 pre_val_patch_code = lir_patch_normal;
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1498
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1499 pre_val = new_register(T_OBJECT);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1500
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1501 if (!addr_opr->is_address()) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1502 assert(addr_opr->is_register(), "must be");
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1503 addr_opr = LIR_OprFact::address(new LIR_Address(addr_opr, T_OBJECT));
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1504 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1505 slow = new G1PreBarrierStub(addr_opr, pre_val, pre_val_patch_code, info);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1506 } else {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1507 assert(addr_opr == LIR_OprFact::illegalOpr, "sanity");
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1508 assert(pre_val->is_register(), "must be");
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1509 assert(pre_val->type() == T_OBJECT, "must be an object");
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1510 assert(info == NULL, "sanity");
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1511
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1512 slow = new G1PreBarrierStub(pre_val);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1513 }
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1514
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1515 __ branch(lir_cond_notEqual, T_INT, slow);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1516 __ branch_destination(slow->continuation());
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1517 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1518
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1519 void LIRGenerator::G1SATBCardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1520 // If the "new_val" is a constant NULL, no barrier is necessary.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1521 if (new_val->is_constant() &&
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1522 new_val->as_constant_ptr()->as_jobject() == NULL) return;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1523
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1524 if (!new_val->is_register()) {
1572
87fc6aca31ab 6955349: C1: Make G1 barriers work with x64
iveresov
parents: 1564
diff changeset
1525 LIR_Opr new_val_reg = new_register(T_OBJECT);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1526 if (new_val->is_constant()) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1527 __ move(new_val, new_val_reg);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1528 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1529 __ leal(new_val, new_val_reg);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1530 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1531 new_val = new_val_reg;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1532 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1533 assert(new_val->is_register(), "must be a register at this point");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1534
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1535 if (addr->is_address()) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1536 LIR_Address* address = addr->as_address_ptr();
2464
d86923d96dca 7034967: C1: assert(false) failed: error (assembler_sparc.cpp:2043)
iveresov
parents: 2446
diff changeset
1537 LIR_Opr ptr = new_pointer_register();
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1538 if (!address->index()->is_valid() && address->disp() == 0) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1539 __ move(address->base(), ptr);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1540 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1541 assert(address->disp() != max_jint, "lea doesn't support patched addresses!");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1542 __ leal(addr, ptr);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1543 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1544 addr = ptr;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1545 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1546 assert(addr->is_register(), "must be a register at this point");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1547
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1548 LIR_Opr xor_res = new_pointer_register();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1549 LIR_Opr xor_shift_res = new_pointer_register();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1550 if (TwoOperandLIRForm ) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1551 __ move(addr, xor_res);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1552 __ logical_xor(xor_res, new_val, xor_res);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1553 __ move(xor_res, xor_shift_res);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1554 __ unsigned_shift_right(xor_shift_res,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1555 LIR_OprFact::intConst(HeapRegion::LogOfHRGrainBytes),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1556 xor_shift_res,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1557 LIR_OprDesc::illegalOpr());
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1558 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1559 __ logical_xor(addr, new_val, xor_res);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1560 __ unsigned_shift_right(xor_res,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1561 LIR_OprFact::intConst(HeapRegion::LogOfHRGrainBytes),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1562 xor_shift_res,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1563 LIR_OprDesc::illegalOpr());
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1564 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1565
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1566 if (!new_val->is_register()) {
1572
87fc6aca31ab 6955349: C1: Make G1 barriers work with x64
iveresov
parents: 1564
diff changeset
1567 LIR_Opr new_val_reg = new_register(T_OBJECT);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1568 __ leal(new_val, new_val_reg);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1569 new_val = new_val_reg;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1570 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1571 assert(new_val->is_register(), "must be a register at this point");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1572
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1573 __ cmp(lir_cond_notEqual, xor_shift_res, LIR_OprFact::intptrConst(NULL_WORD));
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1574
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1575 CodeStub* slow = new G1PostBarrierStub(addr, new_val);
1572
87fc6aca31ab 6955349: C1: Make G1 barriers work with x64
iveresov
parents: 1564
diff changeset
1576 __ branch(lir_cond_notEqual, LP64_ONLY(T_LONG) NOT_LP64(T_INT), slow);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1577 __ branch_destination(slow->continuation());
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1578 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1579
8001
db9981fd3124 8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents: 7425
diff changeset
1580 #endif // INCLUDE_ALL_GCS
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1581 ////////////////////////////////////////////////////////////////////////
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1582
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1583 void LIRGenerator::CardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1584
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1585 assert(sizeof(*((CardTableModRefBS*)_bs)->byte_map_base) == sizeof(jbyte), "adjust this code");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1586 LIR_Const* card_table_base = new LIR_Const(((CardTableModRefBS*)_bs)->byte_map_base);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1587 if (addr->is_address()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1588 LIR_Address* address = addr->as_address_ptr();
2464
d86923d96dca 7034967: C1: assert(false) failed: error (assembler_sparc.cpp:2043)
iveresov
parents: 2446
diff changeset
1589 // ptr cannot be an object because we use this barrier for array card marks
d86923d96dca 7034967: C1: assert(false) failed: error (assembler_sparc.cpp:2043)
iveresov
parents: 2446
diff changeset
1590 // and addr can point in the middle of an array.
d86923d96dca 7034967: C1: assert(false) failed: error (assembler_sparc.cpp:2043)
iveresov
parents: 2446
diff changeset
1591 LIR_Opr ptr = new_pointer_register();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1592 if (!address->index()->is_valid() && address->disp() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1593 __ move(address->base(), ptr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1594 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1595 assert(address->disp() != max_jint, "lea doesn't support patched addresses!");
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 __ leal(addr, ptr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1598 addr = ptr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1599 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1600 assert(addr->is_register(), "must be a register at this point");
a61af66fc99e Initial load
duke
parents:
diff changeset
1601
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1602 #ifdef ARM
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1603 // TODO: ARM - move to platform-dependent code
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1604 LIR_Opr tmp = FrameMap::R14_opr;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1605 if (VM_Version::supports_movw()) {
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1606 __ move((LIR_Opr)card_table_base, tmp);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1607 } else {
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1608 __ move(new LIR_Address(FrameMap::Rthread_opr, in_bytes(JavaThread::card_table_base_offset()), T_ADDRESS), tmp);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1609 }
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1610
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1611 CardTableModRefBS* ct = (CardTableModRefBS*)_bs;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1612 LIR_Address *card_addr = new LIR_Address(tmp, addr, (LIR_Address::Scale) -CardTableModRefBS::card_shift, 0, T_BYTE);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1613 if(((int)ct->byte_map_base & 0xff) == 0) {
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1614 __ move(tmp, card_addr);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1615 } else {
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1616 LIR_Opr tmp_zero = new_register(T_INT);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1617 __ move(LIR_OprFact::intConst(0), tmp_zero);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1618 __ move(tmp_zero, card_addr);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1619 }
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1620 #else // ARM
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1621 LIR_Opr tmp = new_pointer_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
1622 if (TwoOperandLIRForm) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1623 __ move(addr, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1624 __ unsigned_shift_right(tmp, CardTableModRefBS::card_shift, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1626 __ unsigned_shift_right(addr, CardTableModRefBS::card_shift, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1627 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1628 if (can_inline_as_constant(card_table_base)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1629 __ move(LIR_OprFact::intConst(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
1630 new LIR_Address(tmp, card_table_base->as_jint(), T_BYTE));
a61af66fc99e Initial load
duke
parents:
diff changeset
1631 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1632 __ move(LIR_OprFact::intConst(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
1633 new LIR_Address(tmp, load_constant(card_table_base),
a61af66fc99e Initial load
duke
parents:
diff changeset
1634 T_BYTE));
a61af66fc99e Initial load
duke
parents:
diff changeset
1635 }
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1636 #endif // ARM
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1637 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1638
a61af66fc99e Initial load
duke
parents:
diff changeset
1639
a61af66fc99e Initial load
duke
parents:
diff changeset
1640 //------------------------field access--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1641
a61af66fc99e Initial load
duke
parents:
diff changeset
1642 // Comment copied form templateTable_i486.cpp
a61af66fc99e Initial load
duke
parents:
diff changeset
1643 // ----------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1644 // Volatile variables demand their effects be made known to all CPU's in
a61af66fc99e Initial load
duke
parents:
diff changeset
1645 // order. Store buffers on most chips allow reads & writes to reorder; the
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 // JMM's ReadAfterWrite.java test fails in -Xint mode without some kind of
a61af66fc99e Initial load
duke
parents:
diff changeset
1647 // memory barrier (i.e., it's not sufficient that the interpreter does not
a61af66fc99e Initial load
duke
parents:
diff changeset
1648 // reorder volatile references, the hardware also must not reorder them).
a61af66fc99e Initial load
duke
parents:
diff changeset
1649 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1650 // According to the new Java Memory Model (JMM):
a61af66fc99e Initial load
duke
parents:
diff changeset
1651 // (1) All volatiles are serialized wrt to each other.
a61af66fc99e Initial load
duke
parents:
diff changeset
1652 // ALSO reads & writes act as aquire & release, so:
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 // (2) A read cannot let unrelated NON-volatile memory refs that happen after
a61af66fc99e Initial load
duke
parents:
diff changeset
1654 // the read float up to before the read. It's OK for non-volatile memory refs
a61af66fc99e Initial load
duke
parents:
diff changeset
1655 // that happen before the volatile read to float down below it.
a61af66fc99e Initial load
duke
parents:
diff changeset
1656 // (3) Similar a volatile write cannot let unrelated NON-volatile memory refs
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 // that happen BEFORE the write float down to after the write. It's OK for
a61af66fc99e Initial load
duke
parents:
diff changeset
1658 // non-volatile memory refs that happen after the volatile write to float up
a61af66fc99e Initial load
duke
parents:
diff changeset
1659 // before it.
a61af66fc99e Initial load
duke
parents:
diff changeset
1660 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1661 // We only put in barriers around volatile refs (they are expensive), not
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 // _between_ memory refs (that would require us to track the flavor of the
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 // previous memory refs). Requirements (2) and (3) require some barriers
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 // before volatile stores and after volatile loads. These nearly cover
a61af66fc99e Initial load
duke
parents:
diff changeset
1665 // requirement (1) but miss the volatile-store-volatile-load case. This final
a61af66fc99e Initial load
duke
parents:
diff changeset
1666 // case is placed after volatile-stores although it could just as well go
a61af66fc99e Initial load
duke
parents:
diff changeset
1667 // before volatile-loads.
a61af66fc99e Initial load
duke
parents:
diff changeset
1668
a61af66fc99e Initial load
duke
parents:
diff changeset
1669
a61af66fc99e Initial load
duke
parents:
diff changeset
1670 void LIRGenerator::do_StoreField(StoreField* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 bool needs_patching = x->needs_patching();
a61af66fc99e Initial load
duke
parents:
diff changeset
1672 bool is_volatile = x->field()->is_volatile();
a61af66fc99e Initial load
duke
parents:
diff changeset
1673 BasicType field_type = x->field_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1674 bool is_oop = (field_type == T_ARRAY || field_type == T_OBJECT);
a61af66fc99e Initial load
duke
parents:
diff changeset
1675
a61af66fc99e Initial load
duke
parents:
diff changeset
1676 CodeEmitInfo* info = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1677 if (needs_patching) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1678 assert(x->explicit_null_check() == NULL, "can't fold null check into patching field access");
a61af66fc99e Initial load
duke
parents:
diff changeset
1679 info = state_for(x, x->state_before());
a61af66fc99e Initial load
duke
parents:
diff changeset
1680 } else if (x->needs_null_check()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1681 NullCheck* nc = x->explicit_null_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
1682 if (nc == NULL) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
1683 info = state_for(x);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1684 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1685 info = state_for(nc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1686 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1687 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1688
a61af66fc99e Initial load
duke
parents:
diff changeset
1689
a61af66fc99e Initial load
duke
parents:
diff changeset
1690 LIRItem object(x->obj(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 LIRItem value(x->value(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1692
a61af66fc99e Initial load
duke
parents:
diff changeset
1693 object.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1694
a61af66fc99e Initial load
duke
parents:
diff changeset
1695 if (is_volatile || needs_patching) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1696 // load item if field is volatile (fewer special cases for volatiles)
a61af66fc99e Initial load
duke
parents:
diff changeset
1697 // load item if field not initialized
a61af66fc99e Initial load
duke
parents:
diff changeset
1698 // load item if field not constant
a61af66fc99e Initial load
duke
parents:
diff changeset
1699 // because of code patching we cannot inline constants
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 if (field_type == T_BYTE || field_type == T_BOOLEAN) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1701 value.load_byte_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1702 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1703 value.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1704 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1705 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1706 value.load_for_store(field_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1707 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1708
a61af66fc99e Initial load
duke
parents:
diff changeset
1709 set_no_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1710
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
1711 #ifndef PRODUCT
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1712 if (PrintNotLoaded && needs_patching) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1713 tty->print_cr(" ###class not loaded at store_%s bci %d",
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
1714 x->is_static() ? "static" : "field", x->printable_bci());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1715 }
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
1716 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1717
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 if (x->needs_null_check() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1719 (needs_patching ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1720 MacroAssembler::needs_explicit_null_check(x->offset()))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1721 // emit an explicit null check because the offset is too large
a61af66fc99e Initial load
duke
parents:
diff changeset
1722 __ null_check(object.result(), new CodeEmitInfo(info));
a61af66fc99e Initial load
duke
parents:
diff changeset
1723 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1724
a61af66fc99e Initial load
duke
parents:
diff changeset
1725 LIR_Address* address;
a61af66fc99e Initial load
duke
parents:
diff changeset
1726 if (needs_patching) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 // we need to patch the offset in the instruction so don't allow
a61af66fc99e Initial load
duke
parents:
diff changeset
1728 // generate_address to try to be smart about emitting the -1.
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 // Otherwise the patching code won't know how to find the
a61af66fc99e Initial load
duke
parents:
diff changeset
1730 // instruction to patch.
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1731 address = new LIR_Address(object.result(), PATCHED_ADDR, field_type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1732 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1733 address = generate_address(object.result(), x->offset(), field_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1735
a61af66fc99e Initial load
duke
parents:
diff changeset
1736 if (is_volatile && os::is_MP()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1737 __ membar_release();
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1739
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1740 if (is_oop) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1741 // Do the pre-write barrier, if any.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1742 pre_barrier(LIR_OprFact::address(address),
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1743 LIR_OprFact::illegalOpr /* pre_val */,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1744 true /* do_load*/,
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1745 needs_patching,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1746 (info ? new CodeEmitInfo(info) : NULL));
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1747 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1748
2352
425688247f3d 6965570: assert(!needs_patching && x->is_loaded(),"how do we know it's volatile if it's not loaded")
never
parents: 2167
diff changeset
1749 if (is_volatile && !needs_patching) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1750 volatile_field_store(value.result(), address, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1752 LIR_PatchCode patch_code = needs_patching ? lir_patch_normal : lir_patch_none;
a61af66fc99e Initial load
duke
parents:
diff changeset
1753 __ store(value.result(), address, info, patch_code);
a61af66fc99e Initial load
duke
parents:
diff changeset
1754 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1755
a61af66fc99e Initial load
duke
parents:
diff changeset
1756 if (is_oop) {
819
c6386080541b 6849574: VM crash using NonBlockingHashMap (high_scale_lib)
never
parents: 780
diff changeset
1757 // Store to object so mark the card of the header
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 post_barrier(object.result(), value.result());
a61af66fc99e Initial load
duke
parents:
diff changeset
1759 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1760
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 if (is_volatile && os::is_MP()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1762 __ membar();
a61af66fc99e Initial load
duke
parents:
diff changeset
1763 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1764 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1765
a61af66fc99e Initial load
duke
parents:
diff changeset
1766
a61af66fc99e Initial load
duke
parents:
diff changeset
1767 void LIRGenerator::do_LoadField(LoadField* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1768 bool needs_patching = x->needs_patching();
a61af66fc99e Initial load
duke
parents:
diff changeset
1769 bool is_volatile = x->field()->is_volatile();
a61af66fc99e Initial load
duke
parents:
diff changeset
1770 BasicType field_type = x->field_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1771
a61af66fc99e Initial load
duke
parents:
diff changeset
1772 CodeEmitInfo* info = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1773 if (needs_patching) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1774 assert(x->explicit_null_check() == NULL, "can't fold null check into patching field access");
a61af66fc99e Initial load
duke
parents:
diff changeset
1775 info = state_for(x, x->state_before());
a61af66fc99e Initial load
duke
parents:
diff changeset
1776 } else if (x->needs_null_check()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1777 NullCheck* nc = x->explicit_null_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
1778 if (nc == NULL) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
1779 info = state_for(x);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1780 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1781 info = state_for(nc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1782 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1783 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1784
a61af66fc99e Initial load
duke
parents:
diff changeset
1785 LIRItem object(x->obj(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1786
a61af66fc99e Initial load
duke
parents:
diff changeset
1787 object.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1788
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
1789 #ifndef PRODUCT
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1790 if (PrintNotLoaded && needs_patching) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 tty->print_cr(" ###class not loaded at load_%s bci %d",
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
1792 x->is_static() ? "static" : "field", x->printable_bci());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1793 }
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
1794 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1795
8860
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
1796 bool stress_deopt = StressLoopInvariantCodeMotion && info && info->deoptimize_on_exception();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1797 if (x->needs_null_check() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1798 (needs_patching ||
8860
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
1799 MacroAssembler::needs_explicit_null_check(x->offset()) ||
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
1800 stress_deopt)) {
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
1801 LIR_Opr obj = object.result();
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
1802 if (stress_deopt) {
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
1803 obj = new_register(T_OBJECT);
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
1804 __ move(LIR_OprFact::oopConst(NULL), obj);
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
1805 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1806 // emit an explicit null check because the offset is too large
8860
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
1807 __ null_check(obj, new CodeEmitInfo(info));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1808 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1809
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 LIR_Opr reg = rlock_result(x, field_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1811 LIR_Address* address;
a61af66fc99e Initial load
duke
parents:
diff changeset
1812 if (needs_patching) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1813 // we need to patch the offset in the instruction so don't allow
a61af66fc99e Initial load
duke
parents:
diff changeset
1814 // generate_address to try to be smart about emitting the -1.
a61af66fc99e Initial load
duke
parents:
diff changeset
1815 // Otherwise the patching code won't know how to find the
a61af66fc99e Initial load
duke
parents:
diff changeset
1816 // instruction to patch.
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1817 address = new LIR_Address(object.result(), PATCHED_ADDR, field_type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1818 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1819 address = generate_address(object.result(), x->offset(), field_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1820 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1821
2352
425688247f3d 6965570: assert(!needs_patching && x->is_loaded(),"how do we know it's volatile if it's not loaded")
never
parents: 2167
diff changeset
1822 if (is_volatile && !needs_patching) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1823 volatile_field_load(address, reg, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1824 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1825 LIR_PatchCode patch_code = needs_patching ? lir_patch_normal : lir_patch_none;
a61af66fc99e Initial load
duke
parents:
diff changeset
1826 __ load(address, reg, info, patch_code);
a61af66fc99e Initial load
duke
parents:
diff changeset
1827 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1828
a61af66fc99e Initial load
duke
parents:
diff changeset
1829 if (is_volatile && os::is_MP()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1830 __ membar_acquire();
a61af66fc99e Initial load
duke
parents:
diff changeset
1831 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1832 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1833
a61af66fc99e Initial load
duke
parents:
diff changeset
1834
a61af66fc99e Initial load
duke
parents:
diff changeset
1835 //------------------------java.nio.Buffer.checkIndex------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1836
a61af66fc99e Initial load
duke
parents:
diff changeset
1837 // int java.nio.Buffer.checkIndex(int)
a61af66fc99e Initial load
duke
parents:
diff changeset
1838 void LIRGenerator::do_NIOCheckIndex(Intrinsic* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1839 // NOTE: by the time we are in checkIndex() we are guaranteed that
a61af66fc99e Initial load
duke
parents:
diff changeset
1840 // the buffer is non-null (because checkIndex is package-private and
a61af66fc99e Initial load
duke
parents:
diff changeset
1841 // only called from within other methods in the buffer).
a61af66fc99e Initial load
duke
parents:
diff changeset
1842 assert(x->number_of_arguments() == 2, "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
1843 LIRItem buf (x->argument_at(0), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1844 LIRItem index(x->argument_at(1), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1845 buf.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1846 index.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1847
a61af66fc99e Initial load
duke
parents:
diff changeset
1848 LIR_Opr result = rlock_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1849 if (GenerateRangeChecks) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 CodeEmitInfo* info = state_for(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1851 CodeStub* stub = new RangeCheckStub(info, index.result(), true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1852 if (index.result()->is_constant()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1853 cmp_mem_int(lir_cond_belowEqual, buf.result(), java_nio_Buffer::limit_offset(), index.result()->as_jint(), info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1854 __ branch(lir_cond_belowEqual, T_INT, stub);
a61af66fc99e Initial load
duke
parents:
diff changeset
1855 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1856 cmp_reg_mem(lir_cond_aboveEqual, index.result(), buf.result(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1857 java_nio_Buffer::limit_offset(), T_INT, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1858 __ branch(lir_cond_aboveEqual, T_INT, stub);
a61af66fc99e Initial load
duke
parents:
diff changeset
1859 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1860 __ move(index.result(), result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1861 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1862 // Just load the index into the result register
a61af66fc99e Initial load
duke
parents:
diff changeset
1863 __ move(index.result(), result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1864 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1865 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1866
a61af66fc99e Initial load
duke
parents:
diff changeset
1867
a61af66fc99e Initial load
duke
parents:
diff changeset
1868 //------------------------array access--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1869
a61af66fc99e Initial load
duke
parents:
diff changeset
1870
a61af66fc99e Initial load
duke
parents:
diff changeset
1871 void LIRGenerator::do_ArrayLength(ArrayLength* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1872 LIRItem array(x->array(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1873 array.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1874 LIR_Opr reg = rlock_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1875
a61af66fc99e Initial load
duke
parents:
diff changeset
1876 CodeEmitInfo* info = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1877 if (x->needs_null_check()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1878 NullCheck* nc = x->explicit_null_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
1879 if (nc == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1880 info = state_for(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1881 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1882 info = state_for(nc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1883 }
8860
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
1884 if (StressLoopInvariantCodeMotion && info->deoptimize_on_exception()) {
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
1885 LIR_Opr obj = new_register(T_OBJECT);
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
1886 __ move(LIR_OprFact::oopConst(NULL), obj);
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
1887 __ null_check(obj, new CodeEmitInfo(info));
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
1888 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1889 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1890 __ load(new LIR_Address(array.result(), arrayOopDesc::length_offset_in_bytes(), T_INT), reg, info, lir_patch_none);
a61af66fc99e Initial load
duke
parents:
diff changeset
1891 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1892
a61af66fc99e Initial load
duke
parents:
diff changeset
1893
a61af66fc99e Initial load
duke
parents:
diff changeset
1894 void LIRGenerator::do_LoadIndexed(LoadIndexed* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1895 bool use_length = x->length() != NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1896 LIRItem array(x->array(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1897 LIRItem index(x->index(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1898 LIRItem length(this);
8860
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
1899 bool needs_range_check = x->compute_needs_range_check();
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
1900
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
1901 if (use_length && needs_range_check) {
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
1902 length.set_instruction(x->length());
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
1903 length.load_item();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1904 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1905
a61af66fc99e Initial load
duke
parents:
diff changeset
1906 array.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1907 if (index.is_constant() && can_inline_as_constant(x->index())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1908 // let it be a constant
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 index.dont_load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1911 index.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1912 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1913
a61af66fc99e Initial load
duke
parents:
diff changeset
1914 CodeEmitInfo* range_check_info = state_for(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1915 CodeEmitInfo* null_check_info = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 if (x->needs_null_check()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1917 NullCheck* nc = x->explicit_null_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
1918 if (nc != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1919 null_check_info = state_for(nc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1920 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1921 null_check_info = range_check_info;
a61af66fc99e Initial load
duke
parents:
diff changeset
1922 }
8860
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
1923 if (StressLoopInvariantCodeMotion && null_check_info->deoptimize_on_exception()) {
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
1924 LIR_Opr obj = new_register(T_OBJECT);
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
1925 __ move(LIR_OprFact::oopConst(NULL), obj);
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
1926 __ null_check(obj, new CodeEmitInfo(null_check_info));
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
1927 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1928 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1929
a61af66fc99e Initial load
duke
parents:
diff changeset
1930 // emit array address setup early so it schedules better
a61af66fc99e Initial load
duke
parents:
diff changeset
1931 LIR_Address* array_addr = emit_array_address(array.result(), index.result(), x->elt_type(), false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1932
a61af66fc99e Initial load
duke
parents:
diff changeset
1933 if (GenerateRangeChecks && needs_range_check) {
8860
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
1934 if (StressLoopInvariantCodeMotion && range_check_info->deoptimize_on_exception()) {
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
1935 __ branch(lir_cond_always, T_ILLEGAL, new RangeCheckStub(range_check_info, index.result()));
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
1936 } else if (use_length) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1937 // TODO: use a (modified) version of array_range_check that does not require a
a61af66fc99e Initial load
duke
parents:
diff changeset
1938 // constant length to be loaded to a register
a61af66fc99e Initial load
duke
parents:
diff changeset
1939 __ cmp(lir_cond_belowEqual, length.result(), index.result());
a61af66fc99e Initial load
duke
parents:
diff changeset
1940 __ branch(lir_cond_belowEqual, T_INT, new RangeCheckStub(range_check_info, index.result()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1941 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1942 array_range_check(array.result(), index.result(), null_check_info, range_check_info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1943 // The range check performs the null check, so clear it out for the load
a61af66fc99e Initial load
duke
parents:
diff changeset
1944 null_check_info = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1945 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1946 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1947
a61af66fc99e Initial load
duke
parents:
diff changeset
1948 __ move(array_addr, rlock_result(x, x->elt_type()), null_check_info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1949 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1950
a61af66fc99e Initial load
duke
parents:
diff changeset
1951
a61af66fc99e Initial load
duke
parents:
diff changeset
1952 void LIRGenerator::do_NullCheck(NullCheck* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1953 if (x->can_trap()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1954 LIRItem value(x->obj(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1955 value.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1956 CodeEmitInfo* info = state_for(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1957 __ null_check(value.result(), info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1958 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1959 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1960
a61af66fc99e Initial load
duke
parents:
diff changeset
1961
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6145
diff changeset
1962 void LIRGenerator::do_TypeCast(TypeCast* x) {
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6145
diff changeset
1963 LIRItem value(x->obj(), this);
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6145
diff changeset
1964 value.load_item();
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6145
diff changeset
1965 // the result is the same as from the node we are casting
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6145
diff changeset
1966 set_result(x, value.result());
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6145
diff changeset
1967 }
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6145
diff changeset
1968
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6145
diff changeset
1969
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1970 void LIRGenerator::do_Throw(Throw* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1971 LIRItem exception(x->exception(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1972 exception.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1973 set_no_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1974 LIR_Opr exception_opr = exception.result();
a61af66fc99e Initial load
duke
parents:
diff changeset
1975 CodeEmitInfo* info = state_for(x, x->state());
a61af66fc99e Initial load
duke
parents:
diff changeset
1976
a61af66fc99e Initial load
duke
parents:
diff changeset
1977 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1978 if (PrintC1Statistics) {
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
1979 increment_counter(Runtime1::throw_count_address(), T_INT);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1980 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1981 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1982
a61af66fc99e Initial load
duke
parents:
diff changeset
1983 // check if the instruction has an xhandler in any of the nested scopes
a61af66fc99e Initial load
duke
parents:
diff changeset
1984 bool unwind = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1985 if (info->exception_handlers()->length() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1986 // this throw is not inside an xhandler
a61af66fc99e Initial load
duke
parents:
diff changeset
1987 unwind = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1988 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1989 // get some idea of the throw type
a61af66fc99e Initial load
duke
parents:
diff changeset
1990 bool type_is_exact = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1991 ciType* throw_type = x->exception()->exact_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1992 if (throw_type == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1993 type_is_exact = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1994 throw_type = x->exception()->declared_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1995 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1996 if (throw_type != NULL && throw_type->is_instance_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1997 ciInstanceKlass* throw_klass = (ciInstanceKlass*)throw_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
1998 unwind = !x->exception_handlers()->could_catch(throw_klass, type_is_exact);
a61af66fc99e Initial load
duke
parents:
diff changeset
1999 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2000 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2001
a61af66fc99e Initial load
duke
parents:
diff changeset
2002 // do null check before moving exception oop into fixed register
a61af66fc99e Initial load
duke
parents:
diff changeset
2003 // to avoid a fixed interval with an oop during the null check.
a61af66fc99e Initial load
duke
parents:
diff changeset
2004 // Use a copy of the CodeEmitInfo because debug information is
a61af66fc99e Initial load
duke
parents:
diff changeset
2005 // different for null_check and throw.
a61af66fc99e Initial load
duke
parents:
diff changeset
2006 if (GenerateCompilerNullChecks &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 (x->exception()->as_NewInstance() == NULL && x->exception()->as_ExceptionObject() == NULL)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2008 // if the exception object wasn't created using new then it might be null.
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
2009 __ null_check(exception_opr, new CodeEmitInfo(info, x->state()->copy(ValueStack::ExceptionState, x->state()->bci())));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2010 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2011
1378
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1304
diff changeset
2012 if (compilation()->env()->jvmti_can_post_on_exceptions()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2013 // we need to go through the exception lookup path to get JVMTI
a61af66fc99e Initial load
duke
parents:
diff changeset
2014 // notification done
a61af66fc99e Initial load
duke
parents:
diff changeset
2015 unwind = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2016 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2017
a61af66fc99e Initial load
duke
parents:
diff changeset
2018 // move exception oop into fixed register
a61af66fc99e Initial load
duke
parents:
diff changeset
2019 __ move(exception_opr, exceptionOopOpr());
a61af66fc99e Initial load
duke
parents:
diff changeset
2020
a61af66fc99e Initial load
duke
parents:
diff changeset
2021 if (unwind) {
1378
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1304
diff changeset
2022 __ unwind_exception(exceptionOopOpr());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2023 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2024 __ throw_exception(exceptionPcOpr(), exceptionOopOpr(), info);
a61af66fc99e Initial load
duke
parents:
diff changeset
2025 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2026 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2027
a61af66fc99e Initial load
duke
parents:
diff changeset
2028
a61af66fc99e Initial load
duke
parents:
diff changeset
2029 void LIRGenerator::do_RoundFP(RoundFP* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2030 LIRItem input(x->input(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2031 input.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2032 LIR_Opr input_opr = input.result();
a61af66fc99e Initial load
duke
parents:
diff changeset
2033 assert(input_opr->is_register(), "why round if value is not in a register?");
a61af66fc99e Initial load
duke
parents:
diff changeset
2034 assert(input_opr->is_single_fpu() || input_opr->is_double_fpu(), "input should be floating-point value");
a61af66fc99e Initial load
duke
parents:
diff changeset
2035 if (input_opr->is_single_fpu()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2036 set_result(x, round_item(input_opr)); // This code path not currently taken
a61af66fc99e Initial load
duke
parents:
diff changeset
2037 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2038 LIR_Opr result = new_register(T_DOUBLE);
a61af66fc99e Initial load
duke
parents:
diff changeset
2039 set_vreg_flag(result, must_start_in_memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
2040 __ roundfp(input_opr, LIR_OprFact::illegalOpr, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
2041 set_result(x, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
2042 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2043 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2044
20491
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2045 // Here UnsafeGetRaw may have x->base() and x->index() be int or long
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2046 // on both 64 and 32 bits. Expecting x->base() to be always long on 64bit.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2047 void LIRGenerator::do_UnsafeGetRaw(UnsafeGetRaw* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2048 LIRItem base(x->base(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2049 LIRItem idx(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2050
a61af66fc99e Initial load
duke
parents:
diff changeset
2051 base.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2052 if (x->has_index()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2053 idx.set_instruction(x->index());
a61af66fc99e Initial load
duke
parents:
diff changeset
2054 idx.load_nonconstant();
a61af66fc99e Initial load
duke
parents:
diff changeset
2055 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2056
a61af66fc99e Initial load
duke
parents:
diff changeset
2057 LIR_Opr reg = rlock_result(x, x->basic_type());
a61af66fc99e Initial load
duke
parents:
diff changeset
2058
a61af66fc99e Initial load
duke
parents:
diff changeset
2059 int log2_scale = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2060 if (x->has_index()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2061 log2_scale = x->log2_scale();
a61af66fc99e Initial load
duke
parents:
diff changeset
2062 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2063
a61af66fc99e Initial load
duke
parents:
diff changeset
2064 assert(!x->has_index() || idx.value() == x->index(), "should match");
a61af66fc99e Initial load
duke
parents:
diff changeset
2065
a61af66fc99e Initial load
duke
parents:
diff changeset
2066 LIR_Opr base_op = base.result();
20491
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2067 LIR_Opr index_op = idx.result();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2068 #ifndef _LP64
20519
b29261b17343 8059621: JVM crashes with "unexpected index type" assert in LIRGenerator::do_UnsafeGetRaw
iveresov
parents: 20491
diff changeset
2069 if (base_op->type() == T_LONG) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2070 base_op = new_register(T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
2071 __ convert(Bytecodes::_l2i, base.result(), base_op);
20491
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2072 }
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2073 if (x->has_index()) {
20519
b29261b17343 8059621: JVM crashes with "unexpected index type" assert in LIRGenerator::do_UnsafeGetRaw
iveresov
parents: 20491
diff changeset
2074 if (index_op->type() == T_LONG) {
20491
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2075 LIR_Opr long_index_op = index_op;
20519
b29261b17343 8059621: JVM crashes with "unexpected index type" assert in LIRGenerator::do_UnsafeGetRaw
iveresov
parents: 20491
diff changeset
2076 if (index_op->is_constant()) {
20491
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2077 long_index_op = new_register(T_LONG);
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2078 __ move(index_op, long_index_op);
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2079 }
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2080 index_op = new_register(T_INT);
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2081 __ convert(Bytecodes::_l2i, long_index_op, index_op);
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2082 } else {
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2083 assert(x->index()->type()->tag() == intTag, "must be");
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2084 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2085 }
20491
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2086 // At this point base and index should be all ints.
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2087 assert(base_op->type() == T_INT && !base_op->is_constant(), "base should be an non-constant int");
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2088 assert(!x->has_index() || index_op->type() == T_INT, "index should be an int");
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2089 #else
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2090 if (x->has_index()) {
20519
b29261b17343 8059621: JVM crashes with "unexpected index type" assert in LIRGenerator::do_UnsafeGetRaw
iveresov
parents: 20491
diff changeset
2091 if (index_op->type() == T_INT) {
b29261b17343 8059621: JVM crashes with "unexpected index type" assert in LIRGenerator::do_UnsafeGetRaw
iveresov
parents: 20491
diff changeset
2092 if (!index_op->is_constant()) {
20491
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2093 index_op = new_register(T_LONG);
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2094 __ convert(Bytecodes::_i2l, idx.result(), index_op);
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2095 }
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2096 } else {
20519
b29261b17343 8059621: JVM crashes with "unexpected index type" assert in LIRGenerator::do_UnsafeGetRaw
iveresov
parents: 20491
diff changeset
2097 assert(index_op->type() == T_LONG, "must be");
b29261b17343 8059621: JVM crashes with "unexpected index type" assert in LIRGenerator::do_UnsafeGetRaw
iveresov
parents: 20491
diff changeset
2098 if (index_op->is_constant()) {
20491
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2099 index_op = new_register(T_LONG);
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2100 __ move(idx.result(), index_op);
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2101 }
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2102 }
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2103 }
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2104 // At this point base is a long non-constant
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2105 // Index is a long register or a int constant.
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2106 // We allow the constant to stay an int because that would allow us a more compact encoding by
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2107 // embedding an immediate offset in the address expression. If we have a long constant, we have to
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2108 // move it into a register first.
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2109 assert(base_op->type() == T_LONG && !base_op->is_constant(), "base must be a long non-constant");
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2110 assert(!x->has_index() || (index_op->type() == T_INT && index_op->is_constant()) ||
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2111 (index_op->type() == T_LONG && !index_op->is_constant()), "unexpected index type");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2112 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2113
a61af66fc99e Initial load
duke
parents:
diff changeset
2114 BasicType dst_type = x->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2115
a61af66fc99e Initial load
duke
parents:
diff changeset
2116 LIR_Address* addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
2117 if (index_op->is_constant()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2118 assert(log2_scale == 0, "must not have a scale");
20491
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2119 assert(index_op->type() == T_INT, "only int constants supported");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2120 addr = new LIR_Address(base_op, index_op->as_jint(), dst_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2121 } else {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2122 #ifdef X86
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2123 addr = new LIR_Address(base_op, index_op, LIR_Address::Scale(log2_scale), 0, dst_type);
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
2124 #elif defined(ARM)
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
2125 addr = generate_address(base_op, index_op, log2_scale, 0, dst_type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2126 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
2127 if (index_op->is_illegal() || log2_scale == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2128 addr = new LIR_Address(base_op, index_op, dst_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2129 } else {
1060
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2130 LIR_Opr tmp = new_pointer_register();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2131 __ shift_left(index_op, log2_scale, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2132 addr = new LIR_Address(base_op, tmp, dst_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2133 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2134 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2135 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2136
a61af66fc99e Initial load
duke
parents:
diff changeset
2137 if (x->may_be_unaligned() && (dst_type == T_LONG || dst_type == T_DOUBLE)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2138 __ unaligned_move(addr, reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2139 } else {
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2140 if (dst_type == T_OBJECT && x->is_wide()) {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2141 __ move_wide(addr, reg);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2142 } else {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2143 __ move(addr, reg);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2144 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2145 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2146 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2147
a61af66fc99e Initial load
duke
parents:
diff changeset
2148
a61af66fc99e Initial load
duke
parents:
diff changeset
2149 void LIRGenerator::do_UnsafePutRaw(UnsafePutRaw* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2150 int log2_scale = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2151 BasicType type = x->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2152
a61af66fc99e Initial load
duke
parents:
diff changeset
2153 if (x->has_index()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2154 log2_scale = x->log2_scale();
a61af66fc99e Initial load
duke
parents:
diff changeset
2155 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2156
a61af66fc99e Initial load
duke
parents:
diff changeset
2157 LIRItem base(x->base(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2158 LIRItem value(x->value(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2159 LIRItem idx(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2160
a61af66fc99e Initial load
duke
parents:
diff changeset
2161 base.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2162 if (x->has_index()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2163 idx.set_instruction(x->index());
a61af66fc99e Initial load
duke
parents:
diff changeset
2164 idx.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2165 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2166
a61af66fc99e Initial load
duke
parents:
diff changeset
2167 if (type == T_BYTE || type == T_BOOLEAN) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2168 value.load_byte_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2169 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2170 value.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2171 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2172
a61af66fc99e Initial load
duke
parents:
diff changeset
2173 set_no_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2174
a61af66fc99e Initial load
duke
parents:
diff changeset
2175 LIR_Opr base_op = base.result();
20491
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2176 LIR_Opr index_op = idx.result();
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2177
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2178 #ifndef _LP64
20519
b29261b17343 8059621: JVM crashes with "unexpected index type" assert in LIRGenerator::do_UnsafeGetRaw
iveresov
parents: 20491
diff changeset
2179 if (base_op->type() == T_LONG) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2180 base_op = new_register(T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
2181 __ convert(Bytecodes::_l2i, base.result(), base_op);
20491
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2182 }
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2183 if (x->has_index()) {
20519
b29261b17343 8059621: JVM crashes with "unexpected index type" assert in LIRGenerator::do_UnsafeGetRaw
iveresov
parents: 20491
diff changeset
2184 if (index_op->type() == T_LONG) {
20491
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2185 index_op = new_register(T_INT);
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2186 __ convert(Bytecodes::_l2i, idx.result(), index_op);
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2187 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2188 }
20491
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2189 // At this point base and index should be all ints and not constants
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2190 assert(base_op->type() == T_INT && !base_op->is_constant(), "base should be an non-constant int");
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2191 assert(!x->has_index() || (index_op->type() == T_INT && !index_op->is_constant()), "index should be an non-constant int");
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2192 #else
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2193 if (x->has_index()) {
20519
b29261b17343 8059621: JVM crashes with "unexpected index type" assert in LIRGenerator::do_UnsafeGetRaw
iveresov
parents: 20491
diff changeset
2194 if (index_op->type() == T_INT) {
20491
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2195 index_op = new_register(T_LONG);
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2196 __ convert(Bytecodes::_i2l, idx.result(), index_op);
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2197 }
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2198 }
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2199 // At this point base and index are long and non-constant
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2200 assert(base_op->type() == T_LONG && !base_op->is_constant(), "base must be a non-constant long");
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2201 assert(!x->has_index() || (index_op->type() == T_LONG && !index_op->is_constant()), "index must be a non-constant long");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2202 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2203
a61af66fc99e Initial load
duke
parents:
diff changeset
2204 if (log2_scale != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2205 // temporary fix (platform dependent code without shift on Intel would be better)
20491
a60a1309a03a 8058744: Crash in C1 OSRed method w/ Unsafe usage
iveresov
parents: 20344
diff changeset
2206 // TODO: ARM also allows embedded shift in the address
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2207 __ shift_left(index_op, log2_scale, index_op);
a61af66fc99e Initial load
duke
parents:
diff changeset
2208 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2209
a61af66fc99e Initial load
duke
parents:
diff changeset
2210 LIR_Address* addr = new LIR_Address(base_op, index_op, x->basic_type());
a61af66fc99e Initial load
duke
parents:
diff changeset
2211 __ move(value.result(), addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2212 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2213
a61af66fc99e Initial load
duke
parents:
diff changeset
2214
a61af66fc99e Initial load
duke
parents:
diff changeset
2215 void LIRGenerator::do_UnsafeGetObject(UnsafeGetObject* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2216 BasicType type = x->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2217 LIRItem src(x->object(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2218 LIRItem off(x->offset(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2219
a61af66fc99e Initial load
duke
parents:
diff changeset
2220 off.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2221 src.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2222
6615
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2223 LIR_Opr value = rlock_result(x, x->basic_type());
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2224
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2225 get_Object_unsafe(value, src.result(), off.result(), type, x->is_volatile());
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2226
8001
db9981fd3124 8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents: 7425
diff changeset
2227 #if INCLUDE_ALL_GCS
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2228 // We might be reading the value of the referent field of a
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2229 // Reference object in order to attach it back to the live
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2230 // object graph. If G1 is enabled then we need to record
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2231 // the value that is being returned in an SATB log buffer.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2232 //
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2233 // We need to generate code similar to the following...
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2234 //
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2235 // if (offset == java_lang_ref_Reference::referent_offset) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2236 // if (src != NULL) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2237 // if (klass(src)->reference_type() != REF_NONE) {
6615
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2238 // pre_barrier(..., value, ...);
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2239 // }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2240 // }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2241 // }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2242
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2243 if (UseG1GC && type == T_OBJECT) {
6615
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2244 bool gen_pre_barrier = true; // Assume we need to generate pre_barrier.
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2245 bool gen_offset_check = true; // Assume we need to generate the offset guard.
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2246 bool gen_source_check = true; // Assume we need to check the src object for null.
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2247 bool gen_type_check = true; // Assume we need to check the reference_type.
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2248
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2249 if (off.is_constant()) {
3254
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2250 jlong off_con = (off.type()->is_int() ?
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2251 (jlong) off.get_jint_constant() :
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2252 off.get_jlong_constant());
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2253
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2254
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2255 if (off_con != (jlong) java_lang_ref_Reference::referent_offset) {
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2256 // The constant offset is something other than referent_offset.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2257 // We can skip generating/checking the remaining guards and
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2258 // skip generation of the code stub.
6615
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2259 gen_pre_barrier = false;
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2260 } else {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2261 // The constant offset is the same as referent_offset -
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2262 // we do not need to generate a runtime offset check.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2263 gen_offset_check = false;
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2264 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2265 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2266
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2267 // We don't need to generate stub if the source object is an array
6615
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2268 if (gen_pre_barrier && src.type()->is_array()) {
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2269 gen_pre_barrier = false;
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2270 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2271
6615
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2272 if (gen_pre_barrier) {
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2273 // We still need to continue with the checks.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2274 if (src.is_constant()) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2275 ciObject* src_con = src.get_jobject_constant();
10397
075ea888b039 8010724: [parfait] Null pointer dereference in hotspot/src/share/vm/c1/c1_LIRGenerator.cpp
morris
parents: 10116
diff changeset
2276 guarantee(src_con != NULL, "no source constant");
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2277
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2278 if (src_con->is_null_object()) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2279 // The constant src object is null - We can skip
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2280 // generating the code stub.
6615
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2281 gen_pre_barrier = false;
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2282 } else {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2283 // Non-null constant source object. We still have to generate
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2284 // the slow stub - but we don't need to generate the runtime
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2285 // null object check.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2286 gen_source_check = false;
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2287 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2288 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2289 }
6615
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2290 if (gen_pre_barrier && !PatchALot) {
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2291 // Can the klass of object be statically determined to be
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2292 // a sub-class of Reference?
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2293 ciType* type = src.value()->declared_type();
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2294 if ((type != NULL) && type->is_loaded()) {
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2295 if (type->is_subtype_of(compilation()->env()->Reference_klass())) {
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2296 gen_type_check = false;
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2297 } else if (type->is_klass() &&
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2298 !compilation()->env()->Object_klass()->is_subtype_of(type->as_klass())) {
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2299 // Not Reference and not Object klass.
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2300 gen_pre_barrier = false;
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2301 }
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2302 }
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2303 }
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2304
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2305 if (gen_pre_barrier) {
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2306 LabelObj* Lcont = new LabelObj();
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2307
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2308 // We can have generate one runtime check here. Let's start with
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2309 // the offset check.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2310 if (gen_offset_check) {
6615
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2311 // if (offset != referent_offset) -> continue
3254
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2312 // If offset is an int then we can do the comparison with the
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2313 // referent_offset constant; otherwise we need to move
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2314 // referent_offset into a temporary register and generate
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2315 // a reg-reg compare.
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2316
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2317 LIR_Opr referent_off;
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2318
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2319 if (off.type()->is_int()) {
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2320 referent_off = LIR_OprFact::intConst(java_lang_ref_Reference::referent_offset);
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2321 } else {
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2322 assert(off.type()->is_long(), "what else?");
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2323 referent_off = new_register(T_LONG);
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2324 __ move(LIR_OprFact::longConst(java_lang_ref_Reference::referent_offset), referent_off);
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2325 }
6615
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2326 __ cmp(lir_cond_notEqual, off.result(), referent_off);
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2327 __ branch(lir_cond_notEqual, as_BasicType(off.type()), Lcont->label());
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2328 }
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2329 if (gen_source_check) {
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2330 // offset is a const and equals referent offset
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2331 // if (source == null) -> continue
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2332 __ cmp(lir_cond_equal, src.result(), LIR_OprFact::oopConst(NULL));
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2333 __ branch(lir_cond_equal, T_OBJECT, Lcont->label());
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2334 }
6615
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2335 LIR_Opr src_klass = new_register(T_OBJECT);
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2336 if (gen_type_check) {
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2337 // We have determined that offset == referent_offset && src != null.
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2338 // if (src->_klass->_reference_type == REF_NONE) -> continue
12000
8d77d02828d9 8016474: Crash in sun.reflect.UnsafeObjectFieldAccessorImpl.get
twisti
parents: 11080
diff changeset
2339 __ move(new LIR_Address(src.result(), oopDesc::klass_offset_in_bytes(), T_ADDRESS), src_klass);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6616
diff changeset
2340 LIR_Address* reference_type_addr = new LIR_Address(src_klass, in_bytes(InstanceKlass::reference_type_offset()), T_BYTE);
6615
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2341 LIR_Opr reference_type = new_register(T_INT);
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2342 __ move(reference_type_addr, reference_type);
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2343 __ cmp(lir_cond_equal, reference_type, LIR_OprFact::intConst(REF_NONE));
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2344 __ branch(lir_cond_equal, T_INT, Lcont->label());
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2345 }
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2346 {
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2347 // We have determined that src->_klass->_reference_type != REF_NONE
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2348 // so register the value in the referent field with the pre-barrier.
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2349 pre_barrier(LIR_OprFact::illegalOpr /* addr_opr */,
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2350 value /* pre_val */,
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2351 false /* do_load */,
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2352 false /* patch */,
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2353 NULL /* info */);
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2354 }
09aad8452938 7190310: Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
kvn
parents: 6266
diff changeset
2355 __ branch_destination(Lcont->label());
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2356 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2357 }
8001
db9981fd3124 8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents: 7425
diff changeset
2358 #endif // INCLUDE_ALL_GCS
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2359
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2360 if (x->is_volatile() && os::is_MP()) __ membar_acquire();
a61af66fc99e Initial load
duke
parents:
diff changeset
2361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2362
a61af66fc99e Initial load
duke
parents:
diff changeset
2363
a61af66fc99e Initial load
duke
parents:
diff changeset
2364 void LIRGenerator::do_UnsafePutObject(UnsafePutObject* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2365 BasicType type = x->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2366 LIRItem src(x->object(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2367 LIRItem off(x->offset(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2368 LIRItem data(x->value(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2369
a61af66fc99e Initial load
duke
parents:
diff changeset
2370 src.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2371 if (type == T_BOOLEAN || type == T_BYTE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2372 data.load_byte_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2373 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2374 data.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2375 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2376 off.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2377
a61af66fc99e Initial load
duke
parents:
diff changeset
2378 set_no_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2379
a61af66fc99e Initial load
duke
parents:
diff changeset
2380 if (x->is_volatile() && os::is_MP()) __ membar_release();
a61af66fc99e Initial load
duke
parents:
diff changeset
2381 put_Object_unsafe(src.result(), off.result(), data.result(), type, x->is_volatile());
2123
df307487d610 7010665: Misplaced membar in C1 implementation of Unsafe.get/putXXX
dholmes
parents: 2007
diff changeset
2382 if (x->is_volatile() && os::is_MP()) __ membar();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2383 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2384
a61af66fc99e Initial load
duke
parents:
diff changeset
2385
a61af66fc99e Initial load
duke
parents:
diff changeset
2386 void LIRGenerator::do_UnsafePrefetch(UnsafePrefetch* x, bool is_store) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2387 LIRItem src(x->object(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2388 LIRItem off(x->offset(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2389
a61af66fc99e Initial load
duke
parents:
diff changeset
2390 src.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2391 if (off.is_constant() && can_inline_as_constant(x->offset())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2392 // let it be a constant
a61af66fc99e Initial load
duke
parents:
diff changeset
2393 off.dont_load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2394 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2395 off.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2396 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2397
a61af66fc99e Initial load
duke
parents:
diff changeset
2398 set_no_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2399
a61af66fc99e Initial load
duke
parents:
diff changeset
2400 LIR_Address* addr = generate_address(src.result(), off.result(), 0, 0, T_BYTE);
a61af66fc99e Initial load
duke
parents:
diff changeset
2401 __ prefetch(addr, is_store);
a61af66fc99e Initial load
duke
parents:
diff changeset
2402 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2403
a61af66fc99e Initial load
duke
parents:
diff changeset
2404
a61af66fc99e Initial load
duke
parents:
diff changeset
2405 void LIRGenerator::do_UnsafePrefetchRead(UnsafePrefetchRead* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2406 do_UnsafePrefetch(x, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2407 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2408
a61af66fc99e Initial load
duke
parents:
diff changeset
2409
a61af66fc99e Initial load
duke
parents:
diff changeset
2410 void LIRGenerator::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2411 do_UnsafePrefetch(x, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
2412 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2413
a61af66fc99e Initial load
duke
parents:
diff changeset
2414
a61af66fc99e Initial load
duke
parents:
diff changeset
2415 void LIRGenerator::do_SwitchRanges(SwitchRangeArray* x, LIR_Opr value, BlockBegin* default_sux) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2416 int lng = x->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
2417
a61af66fc99e Initial load
duke
parents:
diff changeset
2418 for (int i = 0; i < lng; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2419 SwitchRange* one_range = x->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2420 int low_key = one_range->low_key();
a61af66fc99e Initial load
duke
parents:
diff changeset
2421 int high_key = one_range->high_key();
a61af66fc99e Initial load
duke
parents:
diff changeset
2422 BlockBegin* dest = one_range->sux();
a61af66fc99e Initial load
duke
parents:
diff changeset
2423 if (low_key == high_key) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2424 __ cmp(lir_cond_equal, value, low_key);
a61af66fc99e Initial load
duke
parents:
diff changeset
2425 __ branch(lir_cond_equal, T_INT, dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
2426 } else if (high_key - low_key == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2427 __ cmp(lir_cond_equal, value, low_key);
a61af66fc99e Initial load
duke
parents:
diff changeset
2428 __ branch(lir_cond_equal, T_INT, dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
2429 __ cmp(lir_cond_equal, value, high_key);
a61af66fc99e Initial load
duke
parents:
diff changeset
2430 __ branch(lir_cond_equal, T_INT, dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
2431 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2432 LabelObj* L = new LabelObj();
a61af66fc99e Initial load
duke
parents:
diff changeset
2433 __ cmp(lir_cond_less, value, low_key);
4816
9164b8236699 7131028: Switch statement takes wrong path
iveresov
parents: 4762
diff changeset
2434 __ branch(lir_cond_less, T_INT, L->label());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2435 __ cmp(lir_cond_lessEqual, value, high_key);
a61af66fc99e Initial load
duke
parents:
diff changeset
2436 __ branch(lir_cond_lessEqual, T_INT, dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
2437 __ branch_destination(L->label());
a61af66fc99e Initial load
duke
parents:
diff changeset
2438 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2439 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2440 __ jump(default_sux);
a61af66fc99e Initial load
duke
parents:
diff changeset
2441 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2442
a61af66fc99e Initial load
duke
parents:
diff changeset
2443
a61af66fc99e Initial load
duke
parents:
diff changeset
2444 SwitchRangeArray* LIRGenerator::create_lookup_ranges(TableSwitch* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2445 SwitchRangeList* res = new SwitchRangeList();
a61af66fc99e Initial load
duke
parents:
diff changeset
2446 int len = x->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
2447 if (len > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2448 BlockBegin* sux = x->sux_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2449 int key = x->lo_key();
a61af66fc99e Initial load
duke
parents:
diff changeset
2450 BlockBegin* default_sux = x->default_sux();
a61af66fc99e Initial load
duke
parents:
diff changeset
2451 SwitchRange* range = new SwitchRange(key, sux);
a61af66fc99e Initial load
duke
parents:
diff changeset
2452 for (int i = 0; i < len; i++, key++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2453 BlockBegin* new_sux = x->sux_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2454 if (sux == new_sux) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2455 // still in same range
a61af66fc99e Initial load
duke
parents:
diff changeset
2456 range->set_high_key(key);
a61af66fc99e Initial load
duke
parents:
diff changeset
2457 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2458 // skip tests which explicitly dispatch to the default
a61af66fc99e Initial load
duke
parents:
diff changeset
2459 if (sux != default_sux) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2460 res->append(range);
a61af66fc99e Initial load
duke
parents:
diff changeset
2461 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2462 range = new SwitchRange(key, new_sux);
a61af66fc99e Initial load
duke
parents:
diff changeset
2463 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2464 sux = new_sux;
a61af66fc99e Initial load
duke
parents:
diff changeset
2465 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2466 if (res->length() == 0 || res->last() != range) res->append(range);
a61af66fc99e Initial load
duke
parents:
diff changeset
2467 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2468 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
2469 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2470
a61af66fc99e Initial load
duke
parents:
diff changeset
2471
a61af66fc99e Initial load
duke
parents:
diff changeset
2472 // we expect the keys to be sorted by increasing value
a61af66fc99e Initial load
duke
parents:
diff changeset
2473 SwitchRangeArray* LIRGenerator::create_lookup_ranges(LookupSwitch* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2474 SwitchRangeList* res = new SwitchRangeList();
a61af66fc99e Initial load
duke
parents:
diff changeset
2475 int len = x->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
2476 if (len > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2477 BlockBegin* default_sux = x->default_sux();
a61af66fc99e Initial load
duke
parents:
diff changeset
2478 int key = x->key_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2479 BlockBegin* sux = x->sux_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2480 SwitchRange* range = new SwitchRange(key, sux);
a61af66fc99e Initial load
duke
parents:
diff changeset
2481 for (int i = 1; i < len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2482 int new_key = x->key_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2483 BlockBegin* new_sux = x->sux_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2484 if (key+1 == new_key && sux == new_sux) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2485 // still in same range
a61af66fc99e Initial load
duke
parents:
diff changeset
2486 range->set_high_key(new_key);
a61af66fc99e Initial load
duke
parents:
diff changeset
2487 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2488 // skip tests which explicitly dispatch to the default
a61af66fc99e Initial load
duke
parents:
diff changeset
2489 if (range->sux() != default_sux) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2490 res->append(range);
a61af66fc99e Initial load
duke
parents:
diff changeset
2491 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2492 range = new SwitchRange(new_key, new_sux);
a61af66fc99e Initial load
duke
parents:
diff changeset
2493 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2494 key = new_key;
a61af66fc99e Initial load
duke
parents:
diff changeset
2495 sux = new_sux;
a61af66fc99e Initial load
duke
parents:
diff changeset
2496 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2497 if (res->length() == 0 || res->last() != range) res->append(range);
a61af66fc99e Initial load
duke
parents:
diff changeset
2498 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2499 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
2500 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2501
a61af66fc99e Initial load
duke
parents:
diff changeset
2502
a61af66fc99e Initial load
duke
parents:
diff changeset
2503 void LIRGenerator::do_TableSwitch(TableSwitch* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2504 LIRItem tag(x->tag(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2505 tag.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2506 set_no_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2507
a61af66fc99e Initial load
duke
parents:
diff changeset
2508 if (x->is_safepoint()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2509 __ safepoint(safepoint_poll_register(), state_for(x, x->state_before()));
a61af66fc99e Initial load
duke
parents:
diff changeset
2510 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2511
a61af66fc99e Initial load
duke
parents:
diff changeset
2512 // move values into phi locations
a61af66fc99e Initial load
duke
parents:
diff changeset
2513 move_to_phi(x->state());
a61af66fc99e Initial load
duke
parents:
diff changeset
2514
a61af66fc99e Initial load
duke
parents:
diff changeset
2515 int lo_key = x->lo_key();
a61af66fc99e Initial load
duke
parents:
diff changeset
2516 int hi_key = x->hi_key();
a61af66fc99e Initial load
duke
parents:
diff changeset
2517 int len = x->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
2518 LIR_Opr value = tag.result();
a61af66fc99e Initial load
duke
parents:
diff changeset
2519 if (UseTableRanges) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2520 do_SwitchRanges(create_lookup_ranges(x), value, x->default_sux());
a61af66fc99e Initial load
duke
parents:
diff changeset
2521 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2522 for (int i = 0; i < len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2523 __ cmp(lir_cond_equal, value, i + lo_key);
a61af66fc99e Initial load
duke
parents:
diff changeset
2524 __ branch(lir_cond_equal, T_INT, x->sux_at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
2525 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2526 __ jump(x->default_sux());
a61af66fc99e Initial load
duke
parents:
diff changeset
2527 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2528 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2529
a61af66fc99e Initial load
duke
parents:
diff changeset
2530
a61af66fc99e Initial load
duke
parents:
diff changeset
2531 void LIRGenerator::do_LookupSwitch(LookupSwitch* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2532 LIRItem tag(x->tag(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2533 tag.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2534 set_no_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2535
a61af66fc99e Initial load
duke
parents:
diff changeset
2536 if (x->is_safepoint()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2537 __ safepoint(safepoint_poll_register(), state_for(x, x->state_before()));
a61af66fc99e Initial load
duke
parents:
diff changeset
2538 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2539
a61af66fc99e Initial load
duke
parents:
diff changeset
2540 // move values into phi locations
a61af66fc99e Initial load
duke
parents:
diff changeset
2541 move_to_phi(x->state());
a61af66fc99e Initial load
duke
parents:
diff changeset
2542
a61af66fc99e Initial load
duke
parents:
diff changeset
2543 LIR_Opr value = tag.result();
a61af66fc99e Initial load
duke
parents:
diff changeset
2544 if (UseTableRanges) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2545 do_SwitchRanges(create_lookup_ranges(x), value, x->default_sux());
a61af66fc99e Initial load
duke
parents:
diff changeset
2546 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2547 int len = x->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
2548 for (int i = 0; i < len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2549 __ cmp(lir_cond_equal, value, x->key_at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
2550 __ branch(lir_cond_equal, T_INT, x->sux_at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
2551 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2552 __ jump(x->default_sux());
a61af66fc99e Initial load
duke
parents:
diff changeset
2553 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2554 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2555
a61af66fc99e Initial load
duke
parents:
diff changeset
2556
a61af66fc99e Initial load
duke
parents:
diff changeset
2557 void LIRGenerator::do_Goto(Goto* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2558 set_no_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2559
a61af66fc99e Initial load
duke
parents:
diff changeset
2560 if (block()->next()->as_OsrEntry()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2561 // need to free up storage used for OSR entry point
a61af66fc99e Initial load
duke
parents:
diff changeset
2562 LIR_Opr osrBuffer = block()->next()->operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
2563 BasicTypeList signature;
a61af66fc99e Initial load
duke
parents:
diff changeset
2564 signature.append(T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
2565 CallingConvention* cc = frame_map()->c_calling_convention(&signature);
a61af66fc99e Initial load
duke
parents:
diff changeset
2566 __ move(osrBuffer, cc->args()->at(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
2567 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::OSR_migration_end),
a61af66fc99e Initial load
duke
parents:
diff changeset
2568 getThreadTemp(), LIR_OprFact::illegalOpr, cc->args());
a61af66fc99e Initial load
duke
parents:
diff changeset
2569 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2570
a61af66fc99e Initial load
duke
parents:
diff changeset
2571 if (x->is_safepoint()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2572 ValueStack* state = x->state_before() ? x->state_before() : x->state();
a61af66fc99e Initial load
duke
parents:
diff changeset
2573
a61af66fc99e Initial load
duke
parents:
diff changeset
2574 // increment backedge counter if needed
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2575 CodeEmitInfo* info = state_for(x, state);
3997
940513efe83a 7097679: Tiered: events with bad bci to Gotos reduced from Ifs
iveresov
parents: 3964
diff changeset
2576 increment_backedge_counter(info, x->profiled_bci());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2577 CodeEmitInfo* safepoint_info = state_for(x, state);
a61af66fc99e Initial load
duke
parents:
diff changeset
2578 __ safepoint(safepoint_poll_register(), safepoint_info);
a61af66fc99e Initial load
duke
parents:
diff changeset
2579 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2580
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2581 // Gotos can be folded Ifs, handle this case.
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2582 if (x->should_profile()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2583 ciMethod* method = x->profiled_method();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2584 assert(method != NULL, "method should be set if branch is profiled");
2007
5ddfcf4b079e 7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents: 2002
diff changeset
2585 ciMethodData* md = method->method_data_or_null();
5ddfcf4b079e 7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents: 2002
diff changeset
2586 assert(md != NULL, "Sanity");
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2587 ciProfileData* data = md->bci_to_data(x->profiled_bci());
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2588 assert(data != NULL, "must have profiling data");
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2589 int offset;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2590 if (x->direction() == Goto::taken) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2591 assert(data->is_BranchData(), "need BranchData for two-way branches");
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2592 offset = md->byte_offset_of_slot(data, BranchData::taken_offset());
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2593 } else if (x->direction() == Goto::not_taken) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2594 assert(data->is_BranchData(), "need BranchData for two-way branches");
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2595 offset = md->byte_offset_of_slot(data, BranchData::not_taken_offset());
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2596 } else {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2597 assert(data->is_JumpData(), "need JumpData for branches");
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2598 offset = md->byte_offset_of_slot(data, JumpData::taken_offset());
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2599 }
6739
8a02ca5e5576 7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents: 6731
diff changeset
2600 LIR_Opr md_reg = new_register(T_METADATA);
8a02ca5e5576 7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents: 6731
diff changeset
2601 __ metadata2reg(md->constant_encoding(), md_reg);
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2602
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2603 increment_counter(new LIR_Address(md_reg, offset,
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2604 NOT_LP64(T_INT) LP64_ONLY(T_LONG)), DataLayout::counter_increment);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2605 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2606
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2607 // emit phi-instruction move after safepoint since this simplifies
a61af66fc99e Initial load
duke
parents:
diff changeset
2608 // describing the state as the safepoint.
a61af66fc99e Initial load
duke
parents:
diff changeset
2609 move_to_phi(x->state());
a61af66fc99e Initial load
duke
parents:
diff changeset
2610
a61af66fc99e Initial load
duke
parents:
diff changeset
2611 __ jump(x->default_sux());
a61af66fc99e Initial load
duke
parents:
diff changeset
2612 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2613
13078
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2614 /**
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2615 * Emit profiling code if needed for arguments, parameters, return value types
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2616 *
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2617 * @param md MDO the code will update at runtime
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2618 * @param md_base_offset common offset in the MDO for this profile and subsequent ones
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2619 * @param md_offset offset in the MDO (on top of md_base_offset) for this profile
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2620 * @param profiled_k current profile
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2621 * @param obj IR node for the object to be profiled
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2622 * @param mdp register to hold the pointer inside the MDO (md + md_base_offset).
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2623 * Set once we find an update to make and use for next ones.
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2624 * @param not_null true if we know obj cannot be null
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2625 * @param signature_at_call_k signature at call for obj
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2626 * @param callee_signature_k signature of callee for obj
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2627 * at call and callee signatures differ at method handle call
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2628 * @return the only klass we know will ever be seen at this profile point
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2629 */
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2630 ciKlass* LIRGenerator::profile_type(ciMethodData* md, int md_base_offset, int md_offset, intptr_t profiled_k,
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2631 Value obj, LIR_Opr& mdp, bool not_null, ciKlass* signature_at_call_k,
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2632 ciKlass* callee_signature_k) {
12875
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2633 ciKlass* result = NULL;
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2634 bool do_null = !not_null && !TypeEntries::was_null_seen(profiled_k);
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2635 bool do_update = !TypeEntries::is_type_unknown(profiled_k);
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2636 // known not to be null or null bit already set and already set to
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2637 // unknown: nothing we can do to improve profiling
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2638 if (!do_null && !do_update) {
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2639 return result;
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2640 }
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2641
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2642 ciKlass* exact_klass = NULL;
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2643 Compilation* comp = Compilation::current();
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2644 if (do_update) {
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2645 // try to find exact type, using CHA if possible, so that loading
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2646 // the klass from the object can be avoided
13078
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2647 ciType* type = obj->exact_type();
12875
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2648 if (type == NULL) {
13078
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2649 type = obj->declared_type();
12875
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2650 type = comp->cha_exact_type(type);
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2651 }
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2652 assert(type == NULL || type->is_klass(), "type should be class");
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2653 exact_klass = (type != NULL && type->is_loaded()) ? (ciKlass*)type : NULL;
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2654
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2655 do_update = exact_klass == NULL || ciTypeEntries::valid_ciklass(profiled_k) != exact_klass;
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2656 }
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2657
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2658 if (!do_null && !do_update) {
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2659 return result;
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2660 }
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2661
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2662 ciKlass* exact_signature_k = NULL;
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2663 if (do_update) {
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2664 // Is the type from the signature exact (the only one possible)?
13078
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2665 exact_signature_k = signature_at_call_k->exact_klass();
12875
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2666 if (exact_signature_k == NULL) {
13078
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2667 exact_signature_k = comp->cha_exact_type(signature_at_call_k);
12875
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2668 } else {
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2669 result = exact_signature_k;
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2670 // Known statically. No need to emit any code: prevent
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2671 // LIR_Assembler::emit_profile_type() from emitting useless code
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2672 profiled_k = ciTypeEntries::with_status(result, profiled_k);
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2673 }
17925
45e59fae8f2b 8041481: JVM crashes with collect_args_for_profiling
roland
parents: 17900
diff changeset
2674 // exact_klass and exact_signature_k can be both non NULL but
45e59fae8f2b 8041481: JVM crashes with collect_args_for_profiling
roland
parents: 17900
diff changeset
2675 // different if exact_klass is loaded after the ciObject for
45e59fae8f2b 8041481: JVM crashes with collect_args_for_profiling
roland
parents: 17900
diff changeset
2676 // exact_signature_k is created.
45e59fae8f2b 8041481: JVM crashes with collect_args_for_profiling
roland
parents: 17900
diff changeset
2677 if (exact_klass == NULL && exact_signature_k != NULL && exact_klass != exact_signature_k) {
12875
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2678 // sometimes the type of the signature is better than the best type
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2679 // the compiler has
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2680 exact_klass = exact_signature_k;
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2681 }
13078
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2682 if (callee_signature_k != NULL &&
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2683 callee_signature_k != signature_at_call_k) {
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2684 ciKlass* improved_klass = callee_signature_k->exact_klass();
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2685 if (improved_klass == NULL) {
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2686 improved_klass = comp->cha_exact_type(callee_signature_k);
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2687 }
17925
45e59fae8f2b 8041481: JVM crashes with collect_args_for_profiling
roland
parents: 17900
diff changeset
2688 if (exact_klass == NULL && improved_klass != NULL && exact_klass != improved_klass) {
13078
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2689 exact_klass = exact_signature_k;
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2690 }
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2691 }
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2692 do_update = exact_klass == NULL || ciTypeEntries::valid_ciklass(profiled_k) != exact_klass;
12875
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2693 }
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2694
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2695 if (!do_null && !do_update) {
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2696 return result;
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2697 }
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2698
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2699 if (mdp == LIR_OprFact::illegalOpr) {
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2700 mdp = new_register(T_METADATA);
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2701 __ metadata2reg(md->constant_encoding(), mdp);
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2702 if (md_base_offset != 0) {
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2703 LIR_Address* base_type_address = new LIR_Address(mdp, md_base_offset, T_ADDRESS);
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2704 mdp = new_pointer_register();
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2705 __ leal(LIR_OprFact::address(base_type_address), mdp);
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2706 }
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2707 }
13078
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2708 LIRItem value(obj, this);
12875
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2709 value.load_item();
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2710 __ profile_type(new LIR_Address(mdp, md_offset, T_METADATA),
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2711 value.result(), exact_klass, profiled_k, new_pointer_register(), not_null, exact_signature_k != NULL);
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2712 return result;
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2713 }
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
2714
12962
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
2715 // profile parameters on entry to the root of the compilation
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
2716 void LIRGenerator::profile_parameters(Base* x) {
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
2717 if (compilation()->profile_parameters()) {
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
2718 CallingConvention* args = compilation()->frame_map()->incoming_arguments();
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
2719 ciMethodData* md = scope()->method()->method_data_or_null();
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
2720 assert(md != NULL, "Sanity");
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
2721
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
2722 if (md->parameters_type_data() != NULL) {
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
2723 ciParametersTypeData* parameters_type_data = md->parameters_type_data();
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
2724 ciTypeStackSlotEntries* parameters = parameters_type_data->parameters();
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
2725 LIR_Opr mdp = LIR_OprFact::illegalOpr;
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
2726 for (int java_index = 0, i = 0, j = 0; j < parameters_type_data->number_of_parameters(); i++) {
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
2727 LIR_Opr src = args->at(i);
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
2728 assert(!src->is_illegal(), "check");
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
2729 BasicType t = src->type();
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
2730 if (t == T_OBJECT || t == T_ARRAY) {
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
2731 intptr_t profiled_k = parameters->type(j);
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
2732 Local* local = x->state()->local_at(java_index)->as_Local();
13078
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2733 ciKlass* exact = profile_type(md, md->byte_offset_of_slot(parameters_type_data, ParametersTypeData::type_offset(0)),
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2734 in_bytes(ParametersTypeData::type_offset(j)) - in_bytes(ParametersTypeData::type_offset(0)),
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
2735 profiled_k, local, mdp, false, local->declared_type()->as_klass(), NULL);
12962
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
2736 // If the profile is known statically set it once for all and do not emit any code
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
2737 if (exact != NULL) {
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
2738 md->set_parameter_type(j, exact);
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
2739 }
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
2740 j++;
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
2741 }
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
2742 java_index += type2size[t];
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
2743 }
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
2744 }
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
2745 }
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
2746 }
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
2747
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2748 void LIRGenerator::do_Base(Base* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2749 __ std_entry(LIR_OprFact::illegalOpr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2750 // Emit moves from physical registers / stack slots to virtual registers
a61af66fc99e Initial load
duke
parents:
diff changeset
2751 CallingConvention* args = compilation()->frame_map()->incoming_arguments();
a61af66fc99e Initial load
duke
parents:
diff changeset
2752 IRScope* irScope = compilation()->hir()->top_scope();
a61af66fc99e Initial load
duke
parents:
diff changeset
2753 int java_index = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2754 for (int i = 0; i < args->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2755 LIR_Opr src = args->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2756 assert(!src->is_illegal(), "check");
a61af66fc99e Initial load
duke
parents:
diff changeset
2757 BasicType t = src->type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2758
a61af66fc99e Initial load
duke
parents:
diff changeset
2759 // Types which are smaller than int are passed as int, so
a61af66fc99e Initial load
duke
parents:
diff changeset
2760 // correct the type which passed.
a61af66fc99e Initial load
duke
parents:
diff changeset
2761 switch (t) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2762 case T_BYTE:
a61af66fc99e Initial load
duke
parents:
diff changeset
2763 case T_BOOLEAN:
a61af66fc99e Initial load
duke
parents:
diff changeset
2764 case T_SHORT:
a61af66fc99e Initial load
duke
parents:
diff changeset
2765 case T_CHAR:
a61af66fc99e Initial load
duke
parents:
diff changeset
2766 t = T_INT;
a61af66fc99e Initial load
duke
parents:
diff changeset
2767 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2768 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2769
a61af66fc99e Initial load
duke
parents:
diff changeset
2770 LIR_Opr dest = new_register(t);
a61af66fc99e Initial load
duke
parents:
diff changeset
2771 __ move(src, dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
2772
a61af66fc99e Initial load
duke
parents:
diff changeset
2773 // Assign new location to Local instruction for this local
a61af66fc99e Initial load
duke
parents:
diff changeset
2774 Local* local = x->state()->local_at(java_index)->as_Local();
a61af66fc99e Initial load
duke
parents:
diff changeset
2775 assert(local != NULL, "Locals for incoming arguments must have been created");
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
2776 #ifndef __SOFTFP__
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
2777 // The java calling convention passes double as long and float as int.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2778 assert(as_ValueType(t)->tag() == local->type()->tag(), "check");
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
2779 #endif // __SOFTFP__
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2780 local->set_operand(dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
2781 _instruction_for_operand.at_put_grow(dest->vreg_number(), local, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2782 java_index += type2size[t];
a61af66fc99e Initial load
duke
parents:
diff changeset
2783 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2784
780
c96bf21b756f 6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents: 579
diff changeset
2785 if (compilation()->env()->dtrace_method_probes()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2786 BasicTypeList signature;
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2787 signature.append(LP64_ONLY(T_LONG) NOT_LP64(T_INT)); // thread
12969
9acbfe04b5c3 8026495: JVM Crashes when started with -XX:+DTraceMethodProbes on Solaris x86_64
iveresov
parents: 12962
diff changeset
2788 signature.append(T_METADATA); // Method*
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2789 LIR_OprList* args = new LIR_OprList();
a61af66fc99e Initial load
duke
parents:
diff changeset
2790 args->append(getThreadPointer());
6739
8a02ca5e5576 7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents: 6731
diff changeset
2791 LIR_Opr meth = new_register(T_METADATA);
8a02ca5e5576 7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents: 6731
diff changeset
2792 __ metadata2reg(method()->constant_encoding(), meth);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2793 args->append(meth);
a61af66fc99e Initial load
duke
parents:
diff changeset
2794 call_runtime(&signature, args, CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry), voidType, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2795 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2796
a61af66fc99e Initial load
duke
parents:
diff changeset
2797 if (method()->is_synchronized()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2798 LIR_Opr obj;
a61af66fc99e Initial load
duke
parents:
diff changeset
2799 if (method()->is_static()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2800 obj = new_register(T_OBJECT);
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 819
diff changeset
2801 __ oop2reg(method()->holder()->java_mirror()->constant_encoding(), obj);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2802 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2803 Local* receiver = x->state()->local_at(0)->as_Local();
a61af66fc99e Initial load
duke
parents:
diff changeset
2804 assert(receiver != NULL, "must already exist");
a61af66fc99e Initial load
duke
parents:
diff changeset
2805 obj = receiver->operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
2806 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2807 assert(obj->is_valid(), "must be valid");
a61af66fc99e Initial load
duke
parents:
diff changeset
2808
a61af66fc99e Initial load
duke
parents:
diff changeset
2809 if (method()->is_synchronized() && GenerateSynchronizationCode) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2810 LIR_Opr lock = new_register(T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
2811 __ load_stack_address_monitor(0, lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
2812
8860
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
2813 CodeEmitInfo* info = new CodeEmitInfo(scope()->start()->state()->copy(ValueStack::StateBefore, SynchronizationEntryBCI), NULL, x->check_flag(Instruction::DeoptimizeOnException));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2814 CodeStub* slow_path = new MonitorEnterStub(obj, lock, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
2815
a61af66fc99e Initial load
duke
parents:
diff changeset
2816 // receiver is guaranteed non-NULL so don't need CodeEmitInfo
a61af66fc99e Initial load
duke
parents:
diff changeset
2817 __ lock_object(syncTempOpr(), obj, lock, new_register(T_OBJECT), slow_path, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2818 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2819 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2820
a61af66fc99e Initial load
duke
parents:
diff changeset
2821 // increment invocation counters if needed
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2822 if (!method()->is_accessor()) { // Accessors do not have MDOs, so no counting.
12962
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
2823 profile_parameters(x);
8860
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
2824 CodeEmitInfo* info = new CodeEmitInfo(scope()->start()->state()->copy(ValueStack::StateBefore, SynchronizationEntryBCI), NULL, false);
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2825 increment_invocation_counter(info);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2826 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2827
a61af66fc99e Initial load
duke
parents:
diff changeset
2828 // all blocks with a successor must end with an unconditional jump
a61af66fc99e Initial load
duke
parents:
diff changeset
2829 // to the successor even if they are consecutive
a61af66fc99e Initial load
duke
parents:
diff changeset
2830 __ jump(x->default_sux());
a61af66fc99e Initial load
duke
parents:
diff changeset
2831 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2832
a61af66fc99e Initial load
duke
parents:
diff changeset
2833
a61af66fc99e Initial load
duke
parents:
diff changeset
2834 void LIRGenerator::do_OsrEntry(OsrEntry* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2835 // construct our frame and model the production of incoming pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
2836 // to the OSR buffer.
a61af66fc99e Initial load
duke
parents:
diff changeset
2837 __ osr_entry(LIR_Assembler::osrBufferPointer());
a61af66fc99e Initial load
duke
parents:
diff changeset
2838 LIR_Opr result = rlock_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2839 __ move(LIR_Assembler::osrBufferPointer(), result);
a61af66fc99e Initial load
duke
parents:
diff changeset
2840 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2841
a61af66fc99e Initial load
duke
parents:
diff changeset
2842
a61af66fc99e Initial load
duke
parents:
diff changeset
2843 void LIRGenerator::invoke_load_arguments(Invoke* x, LIRItemList* args, const LIR_OprList* arg_list) {
6616
7a302948f5a4 7192167: JSR 292: C1 has old broken code which needs to be removed
twisti
parents: 6615
diff changeset
2844 assert(args->length() == arg_list->length(),
7a302948f5a4 7192167: JSR 292: C1 has old broken code which needs to be removed
twisti
parents: 6615
diff changeset
2845 err_msg_res("args=%d, arg_list=%d", args->length(), arg_list->length()));
7a302948f5a4 7192167: JSR 292: C1 has old broken code which needs to be removed
twisti
parents: 6615
diff changeset
2846 for (int i = x->has_receiver() ? 1 : 0; i < args->length(); i++) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2847 LIRItem* param = args->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2848 LIR_Opr loc = arg_list->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2849 if (loc->is_register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2850 param->load_item_force(loc);
a61af66fc99e Initial load
duke
parents:
diff changeset
2851 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2852 LIR_Address* addr = loc->as_address_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2853 param->load_for_store(addr->type());
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2854 if (addr->type() == T_OBJECT) {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2855 __ move_wide(param->result(), addr);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2856 } else
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2857 if (addr->type() == T_LONG || addr->type() == T_DOUBLE) {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2858 __ unaligned_move(param->result(), addr);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2859 } else {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2860 __ move(param->result(), addr);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2861 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2862 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2863 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2864
a61af66fc99e Initial load
duke
parents:
diff changeset
2865 if (x->has_receiver()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2866 LIRItem* receiver = args->at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2867 LIR_Opr loc = arg_list->at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2868 if (loc->is_register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2869 receiver->load_item_force(loc);
a61af66fc99e Initial load
duke
parents:
diff changeset
2870 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2871 assert(loc->is_address(), "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
2872 receiver->load_for_store(T_OBJECT);
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2873 __ move_wide(receiver->result(), loc->as_address_ptr());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2874 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2875 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2876 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2877
a61af66fc99e Initial load
duke
parents:
diff changeset
2878
a61af66fc99e Initial load
duke
parents:
diff changeset
2879 // Visits all arguments, returns appropriate items without loading them
a61af66fc99e Initial load
duke
parents:
diff changeset
2880 LIRItemList* LIRGenerator::invoke_visit_arguments(Invoke* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2881 LIRItemList* argument_items = new LIRItemList();
a61af66fc99e Initial load
duke
parents:
diff changeset
2882 if (x->has_receiver()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2883 LIRItem* receiver = new LIRItem(x->receiver(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2884 argument_items->append(receiver);
a61af66fc99e Initial load
duke
parents:
diff changeset
2885 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2886 for (int i = 0; i < x->number_of_arguments(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2887 LIRItem* param = new LIRItem(x->argument_at(i), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2888 argument_items->append(param);
a61af66fc99e Initial load
duke
parents:
diff changeset
2889 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2890 return argument_items;
a61af66fc99e Initial load
duke
parents:
diff changeset
2891 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2892
a61af66fc99e Initial load
duke
parents:
diff changeset
2893
a61af66fc99e Initial load
duke
parents:
diff changeset
2894 // The invoke with receiver has following phases:
a61af66fc99e Initial load
duke
parents:
diff changeset
2895 // a) traverse and load/lock receiver;
a61af66fc99e Initial load
duke
parents:
diff changeset
2896 // b) traverse all arguments -> item-array (invoke_visit_argument)
a61af66fc99e Initial load
duke
parents:
diff changeset
2897 // c) push receiver on stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2898 // d) load each of the items and push on stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2899 // e) unlock receiver
a61af66fc99e Initial load
duke
parents:
diff changeset
2900 // f) move receiver into receiver-register %o0
a61af66fc99e Initial load
duke
parents:
diff changeset
2901 // g) lock result registers and emit call operation
a61af66fc99e Initial load
duke
parents:
diff changeset
2902 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2903 // Before issuing a call, we must spill-save all values on stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2904 // that are in caller-save register. "spill-save" moves thos registers
a61af66fc99e Initial load
duke
parents:
diff changeset
2905 // either in a free callee-save register or spills them if no free
a61af66fc99e Initial load
duke
parents:
diff changeset
2906 // callee save register is available.
a61af66fc99e Initial load
duke
parents:
diff changeset
2907 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2908 // The problem is where to invoke spill-save.
a61af66fc99e Initial load
duke
parents:
diff changeset
2909 // - if invoked between e) and f), we may lock callee save
a61af66fc99e Initial load
duke
parents:
diff changeset
2910 // register in "spill-save" that destroys the receiver register
a61af66fc99e Initial load
duke
parents:
diff changeset
2911 // before f) is executed
a61af66fc99e Initial load
duke
parents:
diff changeset
2912 // - if we rearange the f) to be earlier, by loading %o0, it
a61af66fc99e Initial load
duke
parents:
diff changeset
2913 // may destroy a value on the stack that is currently in %o0
a61af66fc99e Initial load
duke
parents:
diff changeset
2914 // and is waiting to be spilled
a61af66fc99e Initial load
duke
parents:
diff changeset
2915 // - if we keep the receiver locked while doing spill-save,
a61af66fc99e Initial load
duke
parents:
diff changeset
2916 // we cannot spill it as it is spill-locked
a61af66fc99e Initial load
duke
parents:
diff changeset
2917 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2918 void LIRGenerator::do_Invoke(Invoke* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2919 CallingConvention* cc = frame_map()->java_calling_convention(x->signature(), true);
a61af66fc99e Initial load
duke
parents:
diff changeset
2920
a61af66fc99e Initial load
duke
parents:
diff changeset
2921 LIR_OprList* arg_list = cc->args();
a61af66fc99e Initial load
duke
parents:
diff changeset
2922 LIRItemList* args = invoke_visit_arguments(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2923 LIR_Opr receiver = LIR_OprFact::illegalOpr;
a61af66fc99e Initial load
duke
parents:
diff changeset
2924
a61af66fc99e Initial load
duke
parents:
diff changeset
2925 // setup result register
a61af66fc99e Initial load
duke
parents:
diff changeset
2926 LIR_Opr result_register = LIR_OprFact::illegalOpr;
a61af66fc99e Initial load
duke
parents:
diff changeset
2927 if (x->type() != voidType) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2928 result_register = result_register_for(x->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
2929 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2930
a61af66fc99e Initial load
duke
parents:
diff changeset
2931 CodeEmitInfo* info = state_for(x, x->state());
a61af66fc99e Initial load
duke
parents:
diff changeset
2932
a61af66fc99e Initial load
duke
parents:
diff changeset
2933 invoke_load_arguments(x, args, arg_list);
a61af66fc99e Initial load
duke
parents:
diff changeset
2934
a61af66fc99e Initial load
duke
parents:
diff changeset
2935 if (x->has_receiver()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2936 args->at(0)->load_item_force(LIR_Assembler::receiverOpr());
a61af66fc99e Initial load
duke
parents:
diff changeset
2937 receiver = args->at(0)->result();
a61af66fc99e Initial load
duke
parents:
diff changeset
2938 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2939
a61af66fc99e Initial load
duke
parents:
diff changeset
2940 // emit invoke code
a61af66fc99e Initial load
duke
parents:
diff changeset
2941 bool optimized = x->target_is_loaded() && x->target_is_final();
a61af66fc99e Initial load
duke
parents:
diff changeset
2942 assert(receiver->is_illegal() || receiver->is_equal(LIR_Assembler::receiverOpr()), "must match");
a61af66fc99e Initial load
duke
parents:
diff changeset
2943
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2944 // JSR 292
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2945 // Preserve the SP over MethodHandle call sites.
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2946 ciMethod* target = x->target();
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6145
diff changeset
2947 bool is_method_handle_invoke = (// %%% FIXME: Are both of these relevant?
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6145
diff changeset
2948 target->is_method_handle_intrinsic() ||
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6145
diff changeset
2949 target->is_compiled_lambda_form());
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6145
diff changeset
2950 if (is_method_handle_invoke) {
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2951 info->set_is_method_handle_invoke(true);
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2952 __ move(FrameMap::stack_pointer(), FrameMap::method_handle_invoke_SP_save_opr());
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2953 }
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2954
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2955 switch (x->code()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2956 case Bytecodes::_invokestatic:
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2957 __ call_static(target, result_register,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2958 SharedRuntime::get_resolve_static_call_stub(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2959 arg_list, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
2960 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2961 case Bytecodes::_invokespecial:
a61af66fc99e Initial load
duke
parents:
diff changeset
2962 case Bytecodes::_invokevirtual:
a61af66fc99e Initial load
duke
parents:
diff changeset
2963 case Bytecodes::_invokeinterface:
a61af66fc99e Initial load
duke
parents:
diff changeset
2964 // for final target we still produce an inline cache, in order
a61af66fc99e Initial load
duke
parents:
diff changeset
2965 // to be able to call mixed mode
a61af66fc99e Initial load
duke
parents:
diff changeset
2966 if (x->code() == Bytecodes::_invokespecial || optimized) {
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2967 __ call_opt_virtual(target, receiver, result_register,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2968 SharedRuntime::get_resolve_opt_virtual_call_stub(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2969 arg_list, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
2970 } else if (x->vtable_index() < 0) {
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2971 __ call_icvirtual(target, receiver, result_register,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2972 SharedRuntime::get_resolve_virtual_call_stub(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2973 arg_list, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
2974 } else {
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6616
diff changeset
2975 int entry_offset = InstanceKlass::vtable_start_offset() + x->vtable_index() * vtableEntry::size();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2976 int vtable_offset = entry_offset * wordSize + vtableEntry::method_offset_in_bytes();
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2977 __ call_virtual(target, receiver, result_register, vtable_offset, arg_list, info);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2978 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2979 break;
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2980 case Bytecodes::_invokedynamic: {
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2981 __ call_dynamic(target, receiver, result_register,
6616
7a302948f5a4 7192167: JSR 292: C1 has old broken code which needs to be removed
twisti
parents: 6615
diff changeset
2982 SharedRuntime::get_resolve_static_call_stub(),
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2983 arg_list, info);
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2984 break;
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2985 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2986 default:
6145
e2fe93124108 7174928: JSR 292: unresolved invokedynamic call sites deopt and osr infinitely
twisti
parents: 6143
diff changeset
2987 fatal(err_msg("unexpected bytecode: %s", Bytecodes::name(x->code())));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2988 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2989 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2990
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2991 // JSR 292
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2992 // Restore the SP after MethodHandle call sites.
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6145
diff changeset
2993 if (is_method_handle_invoke) {
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2994 __ move(FrameMap::method_handle_invoke_SP_save_opr(), FrameMap::stack_pointer());
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2995 }
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2996
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2997 if (x->type()->is_float() || x->type()->is_double()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2998 // Force rounding of results from non-strictfp when in strictfp
a61af66fc99e Initial load
duke
parents:
diff changeset
2999 // scope (or when we don't know the strictness of the callee, to
a61af66fc99e Initial load
duke
parents:
diff changeset
3000 // be safe.)
a61af66fc99e Initial load
duke
parents:
diff changeset
3001 if (method()->is_strict()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3002 if (!x->target_is_loaded() || !x->target_is_strictfp()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3003 result_register = round_item(result_register);
a61af66fc99e Initial load
duke
parents:
diff changeset
3004 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3005 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3006 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3007
a61af66fc99e Initial load
duke
parents:
diff changeset
3008 if (result_register->is_valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3009 LIR_Opr result = rlock_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
3010 __ move(result_register, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
3011 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3012 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3013
a61af66fc99e Initial load
duke
parents:
diff changeset
3014
a61af66fc99e Initial load
duke
parents:
diff changeset
3015 void LIRGenerator::do_FPIntrinsics(Intrinsic* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3016 assert(x->number_of_arguments() == 1, "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
3017 LIRItem value (x->argument_at(0), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
3018 LIR_Opr reg = rlock_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
3019 value.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
3020 LIR_Opr tmp = force_to_spill(value.result(), as_BasicType(x->type()));
a61af66fc99e Initial load
duke
parents:
diff changeset
3021 __ move(tmp, reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
3022 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3023
a61af66fc99e Initial load
duke
parents:
diff changeset
3024
a61af66fc99e Initial load
duke
parents:
diff changeset
3025
a61af66fc99e Initial load
duke
parents:
diff changeset
3026 // Code for : x->x() {x->cond()} x->y() ? x->tval() : x->fval()
a61af66fc99e Initial load
duke
parents:
diff changeset
3027 void LIRGenerator::do_IfOp(IfOp* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3028 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
3029 {
a61af66fc99e Initial load
duke
parents:
diff changeset
3030 ValueTag xtag = x->x()->type()->tag();
a61af66fc99e Initial load
duke
parents:
diff changeset
3031 ValueTag ttag = x->tval()->type()->tag();
a61af66fc99e Initial load
duke
parents:
diff changeset
3032 assert(xtag == intTag || xtag == objectTag, "cannot handle others");
a61af66fc99e Initial load
duke
parents:
diff changeset
3033 assert(ttag == addressTag || ttag == intTag || ttag == objectTag || ttag == longTag, "cannot handle others");
a61af66fc99e Initial load
duke
parents:
diff changeset
3034 assert(ttag == x->fval()->type()->tag(), "cannot handle others");
a61af66fc99e Initial load
duke
parents:
diff changeset
3035 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3036 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3037
a61af66fc99e Initial load
duke
parents:
diff changeset
3038 LIRItem left(x->x(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
3039 LIRItem right(x->y(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
3040 left.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
3041 if (can_inline_as_constant(right.value())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3042 right.dont_load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
3043 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3044 right.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
3045 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3046
a61af66fc99e Initial load
duke
parents:
diff changeset
3047 LIRItem t_val(x->tval(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
3048 LIRItem f_val(x->fval(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
3049 t_val.dont_load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
3050 f_val.dont_load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
3051 LIR_Opr reg = rlock_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
3052
a61af66fc99e Initial load
duke
parents:
diff changeset
3053 __ cmp(lir_cond(x->cond()), left.result(), right.result());
2089
037c727f35fb 7009231: C1: Incorrect CAS code for longs on SPARC 32bit
iveresov
parents: 2007
diff changeset
3054 __ cmove(lir_cond(x->cond()), t_val.result(), f_val.result(), reg, as_BasicType(x->x()->type()));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3055 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3056
6006
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3057 void LIRGenerator::do_RuntimeCall(address routine, int expected_arguments, Intrinsic* x) {
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3058 assert(x->number_of_arguments() == expected_arguments, "wrong type");
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3059 LIR_Opr reg = result_register_for(x->type());
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3060 __ call_runtime_leaf(routine, getThreadTemp(),
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3061 reg, new LIR_OprList());
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3062 LIR_Opr result = rlock_result(x);
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3063 __ move(reg, result);
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3064 }
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3065
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3066 #ifdef TRACE_HAVE_INTRINSICS
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3067 void LIRGenerator::do_ThreadIDIntrinsic(Intrinsic* x) {
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3068 LIR_Opr thread = getThreadPointer();
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3069 LIR_Opr osthread = new_pointer_register();
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3070 __ move(new LIR_Address(thread, in_bytes(JavaThread::osthread_offset()), osthread->type()), osthread);
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3071 size_t thread_id_size = OSThread::thread_id_size();
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3072 if (thread_id_size == (size_t) BytesPerLong) {
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3073 LIR_Opr id = new_register(T_LONG);
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3074 __ move(new LIR_Address(osthread, in_bytes(OSThread::thread_id_offset()), T_LONG), id);
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3075 __ convert(Bytecodes::_l2i, id, rlock_result(x));
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3076 } else if (thread_id_size == (size_t) BytesPerInt) {
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3077 __ move(new LIR_Address(osthread, in_bytes(OSThread::thread_id_offset()), T_INT), rlock_result(x));
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3078 } else {
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3079 ShouldNotReachHere();
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3080 }
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3081 }
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3082
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3083 void LIRGenerator::do_ClassIDIntrinsic(Intrinsic* x) {
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3084 CodeEmitInfo* info = state_for(x);
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3085 CodeEmitInfo* info2 = new CodeEmitInfo(info); // Clone for the second null check
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6616
diff changeset
3086 BasicType klass_pointer_type = NOT_LP64(T_INT) LP64_ONLY(T_LONG);
6006
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3087 assert(info != NULL, "must have info");
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3088 LIRItem arg(x->argument_at(1), this);
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3089 arg.load_item();
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6616
diff changeset
3090 LIR_Opr klass = new_pointer_register();
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6616
diff changeset
3091 __ move(new LIR_Address(arg.result(), java_lang_Class::klass_offset_in_bytes(), klass_pointer_type), klass, info);
6006
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3092 LIR_Opr id = new_register(T_LONG);
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3093 ByteSize offset = TRACE_ID_OFFSET;
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3094 LIR_Address* trace_id_addr = new LIR_Address(klass, in_bytes(offset), T_LONG);
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3095 __ move(trace_id_addr, id);
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3096 __ logical_or(id, LIR_OprFact::longConst(0x01l), id);
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3097 __ store(id, trace_id_addr);
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3098 __ logical_and(id, LIR_OprFact::longConst(~0x3l), id);
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3099 __ move(id, rlock_result(x));
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3100 }
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3101 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3102
a61af66fc99e Initial load
duke
parents:
diff changeset
3103 void LIRGenerator::do_Intrinsic(Intrinsic* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3104 switch (x->id()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3105 case vmIntrinsics::_intBitsToFloat :
a61af66fc99e Initial load
duke
parents:
diff changeset
3106 case vmIntrinsics::_doubleToRawLongBits :
a61af66fc99e Initial load
duke
parents:
diff changeset
3107 case vmIntrinsics::_longBitsToDouble :
a61af66fc99e Initial load
duke
parents:
diff changeset
3108 case vmIntrinsics::_floatToRawIntBits : {
a61af66fc99e Initial load
duke
parents:
diff changeset
3109 do_FPIntrinsics(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
3110 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3111 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3112
6006
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3113 #ifdef TRACE_HAVE_INTRINSICS
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3114 case vmIntrinsics::_threadID: do_ThreadIDIntrinsic(x); break;
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3115 case vmIntrinsics::_classID: do_ClassIDIntrinsic(x); break;
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3116 case vmIntrinsics::_counterTime:
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3117 do_RuntimeCall(CAST_FROM_FN_PTR(address, TRACE_TIME_METHOD), 0, x);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3118 break;
6006
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3119 #endif
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3120
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3121 case vmIntrinsics::_currentTimeMillis:
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3122 do_RuntimeCall(CAST_FROM_FN_PTR(address, os::javaTimeMillis), 0, x);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3123 break;
6006
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3124
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3125 case vmIntrinsics::_nanoTime:
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3126 do_RuntimeCall(CAST_FROM_FN_PTR(address, os::javaTimeNanos), 0, x);
0105f367a14c 7160570: Intrinsification support for tracing framework
rbackman
parents: 4966
diff changeset
3127 break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3128
a61af66fc99e Initial load
duke
parents:
diff changeset
3129 case vmIntrinsics::_Object_init: do_RegisterFinalizer(x); break;
6135
8f37087fc13f 7171890: C1: add Class.isInstance intrinsic
roland
parents: 6084
diff changeset
3130 case vmIntrinsics::_isInstance: do_isInstance(x); break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3131 case vmIntrinsics::_getClass: do_getClass(x); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3132 case vmIntrinsics::_currentThread: do_currentThread(x); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3133
a61af66fc99e Initial load
duke
parents:
diff changeset
3134 case vmIntrinsics::_dlog: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
3135 case vmIntrinsics::_dlog10: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
3136 case vmIntrinsics::_dabs: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
3137 case vmIntrinsics::_dsqrt: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
3138 case vmIntrinsics::_dtan: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
3139 case vmIntrinsics::_dsin : // fall through
6084
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 6006
diff changeset
3140 case vmIntrinsics::_dcos : // fall through
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 6006
diff changeset
3141 case vmIntrinsics::_dexp : // fall through
6759698e3140 7133857: exp() and pow() should use the x87 ISA on x86
roland
parents: 6006
diff changeset
3142 case vmIntrinsics::_dpow : do_MathIntrinsic(x); break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3143 case vmIntrinsics::_arraycopy: do_ArrayCopy(x); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3144
a61af66fc99e Initial load
duke
parents:
diff changeset
3145 // java.nio.Buffer.checkIndex
a61af66fc99e Initial load
duke
parents:
diff changeset
3146 case vmIntrinsics::_checkIndex: do_NIOCheckIndex(x); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3147
a61af66fc99e Initial load
duke
parents:
diff changeset
3148 case vmIntrinsics::_compareAndSwapObject:
a61af66fc99e Initial load
duke
parents:
diff changeset
3149 do_CompareAndSwap(x, objectType);
a61af66fc99e Initial load
duke
parents:
diff changeset
3150 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3151 case vmIntrinsics::_compareAndSwapInt:
a61af66fc99e Initial load
duke
parents:
diff changeset
3152 do_CompareAndSwap(x, intType);
a61af66fc99e Initial load
duke
parents:
diff changeset
3153 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3154 case vmIntrinsics::_compareAndSwapLong:
a61af66fc99e Initial load
duke
parents:
diff changeset
3155 do_CompareAndSwap(x, longType);
a61af66fc99e Initial load
duke
parents:
diff changeset
3156 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3157
7425
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 6848
diff changeset
3158 case vmIntrinsics::_loadFence :
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 6848
diff changeset
3159 if (os::is_MP()) __ membar_acquire();
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 6848
diff changeset
3160 break;
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 6848
diff changeset
3161 case vmIntrinsics::_storeFence:
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 6848
diff changeset
3162 if (os::is_MP()) __ membar_release();
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 6848
diff changeset
3163 break;
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 6848
diff changeset
3164 case vmIntrinsics::_fullFence :
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 6848
diff changeset
3165 if (os::is_MP()) __ membar();
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 6848
diff changeset
3166 break;
1e41b0bc58a0 8004318: JEP-171: Support Unsafe fences intrinsics
kvn
parents: 6848
diff changeset
3167
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
3168 case vmIntrinsics::_Reference_get:
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
3169 do_Reference_get(x);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
3170 break;
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
3171
11080
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10397
diff changeset
3172 case vmIntrinsics::_updateCRC32:
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10397
diff changeset
3173 case vmIntrinsics::_updateBytesCRC32:
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10397
diff changeset
3174 case vmIntrinsics::_updateByteBufferCRC32:
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10397
diff changeset
3175 do_update_CRC32(x);
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10397
diff changeset
3176 break;
b800986664f4 7088419: Use x86 Hardware CRC32 Instruction with java.util.zip.CRC32
drchase
parents: 10397
diff changeset
3177
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3178 default: ShouldNotReachHere(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3179 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3180 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3181
12875
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
3182 void LIRGenerator::profile_arguments(ProfileCall* x) {
12962
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3183 if (compilation()->profile_arguments()) {
12875
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
3184 int bci = x->bci_of_invoke();
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
3185 ciMethodData* md = x->method()->method_data_or_null();
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
3186 ciProfileData* data = md->bci_to_data(bci);
12962
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3187 if ((data->is_CallTypeData() && data->as_CallTypeData()->has_arguments()) ||
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3188 (data->is_VirtualCallTypeData() && data->as_VirtualCallTypeData()->has_arguments())) {
12875
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
3189 ByteSize extra = data->is_CallTypeData() ? CallTypeData::args_data_offset() : VirtualCallTypeData::args_data_offset();
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
3190 int base_offset = md->byte_offset_of_slot(data, extra);
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
3191 LIR_Opr mdp = LIR_OprFact::illegalOpr;
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
3192 ciTypeStackSlotEntries* args = data->is_CallTypeData() ? ((ciCallTypeData*)data)->args() : ((ciVirtualCallTypeData*)data)->args();
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
3193
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
3194 Bytecodes::Code bc = x->method()->java_code_at_bci(bci);
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
3195 int start = 0;
12882
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
3196 int stop = data->is_CallTypeData() ? ((ciCallTypeData*)data)->number_of_arguments() : ((ciVirtualCallTypeData*)data)->number_of_arguments();
13078
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3197 if (x->inlined() && x->callee()->is_static() && Bytecodes::has_receiver(bc)) {
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3198 // first argument is not profiled at call (method handle invoke)
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3199 assert(x->method()->raw_code_at_bci(bci) == Bytecodes::_invokehandle, "invokehandle expected");
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3200 start = 1;
12875
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
3201 }
13078
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3202 ciSignature* callee_signature = x->callee()->signature();
12875
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
3203 // method handle call to virtual method
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
3204 bool has_receiver = x->inlined() && !x->callee()->is_static() && !Bytecodes::has_receiver(bc);
13078
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3205 ciSignatureStream callee_signature_stream(callee_signature, has_receiver ? x->callee()->holder() : NULL);
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3206
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3207 bool ignored_will_link;
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3208 ciSignature* signature_at_call = NULL;
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3209 x->method()->get_method_at_bci(bci, ignored_will_link, &signature_at_call);
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3210 ciSignatureStream signature_at_call_stream(signature_at_call);
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3211
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3212 // if called through method handle invoke, some arguments may have been popped
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3213 for (int i = 0; i < stop && i+start < x->nb_profiled_args(); i++) {
12882
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
3214 int off = in_bytes(TypeEntriesAtCall::argument_type_offset(i)) - in_bytes(TypeEntriesAtCall::args_data_offset());
13078
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3215 ciKlass* exact = profile_type(md, base_offset, off,
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3216 args->type(i), x->profiled_arg_at(i+start), mdp,
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3217 !x->arg_needs_null_check(i+start),
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3218 signature_at_call_stream.next_klass(), callee_signature_stream.next_klass());
12875
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
3219 if (exact != NULL) {
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
3220 md->set_argument_type(bci, i, exact);
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
3221 }
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
3222 }
12962
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3223 } else {
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3224 #ifdef ASSERT
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3225 Bytecodes::Code code = x->method()->raw_code_at_bci(x->bci_of_invoke());
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3226 int n = x->nb_profiled_args();
17900
ce9fd31ffd14 8039975: SIGSEGV in MethodData::next_data(ProfileData*)
roland
parents: 17628
diff changeset
3227 assert(MethodData::profile_parameters() && (MethodData::profile_arguments_jsr292_only() ||
ce9fd31ffd14 8039975: SIGSEGV in MethodData::next_data(ProfileData*)
roland
parents: 17628
diff changeset
3228 (x->inlined() && ((code == Bytecodes::_invokedynamic && n <= 1) || (code == Bytecodes::_invokehandle && n <= 2)))),
12962
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3229 "only at JSR292 bytecodes");
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3230 #endif
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3231 }
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3232 }
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3233 }
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3234
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3235 // profile parameters on entry to an inlined method
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3236 void LIRGenerator::profile_parameters_at_call(ProfileCall* x) {
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3237 if (compilation()->profile_parameters() && x->inlined()) {
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3238 ciMethodData* md = x->callee()->method_data_or_null();
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3239 if (md != NULL) {
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3240 ciParametersTypeData* parameters_type_data = md->parameters_type_data();
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3241 if (parameters_type_data != NULL) {
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3242 ciTypeStackSlotEntries* parameters = parameters_type_data->parameters();
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3243 LIR_Opr mdp = LIR_OprFact::illegalOpr;
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3244 bool has_receiver = !x->callee()->is_static();
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3245 ciSignature* sig = x->callee()->signature();
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3246 ciSignatureStream sig_stream(sig, has_receiver ? x->callee()->holder() : NULL);
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3247 int i = 0; // to iterate on the Instructions
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3248 Value arg = x->recv();
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3249 bool not_null = false;
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3250 int bci = x->bci_of_invoke();
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3251 Bytecodes::Code bc = x->method()->java_code_at_bci(bci);
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3252 // The first parameter is the receiver so that's what we start
13078
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3253 // with if it exists. One exception is method handle call to
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3254 // virtual method: the receiver is in the args list
12962
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3255 if (arg == NULL || !Bytecodes::has_receiver(bc)) {
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3256 i = 1;
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3257 arg = x->profiled_arg_at(0);
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3258 not_null = !x->arg_needs_null_check(0);
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3259 }
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3260 int k = 0; // to iterate on the profile data
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3261 for (;;) {
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3262 intptr_t profiled_k = parameters->type(k);
13078
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3263 ciKlass* exact = profile_type(md, md->byte_offset_of_slot(parameters_type_data, ParametersTypeData::type_offset(0)),
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3264 in_bytes(ParametersTypeData::type_offset(k)) - in_bytes(ParametersTypeData::type_offset(0)),
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3265 profiled_k, arg, mdp, not_null, sig_stream.next_klass(), NULL);
12962
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3266 // If the profile is known statically set it once for all and do not emit any code
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3267 if (exact != NULL) {
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3268 md->set_parameter_type(k, exact);
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3269 }
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3270 k++;
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3271 if (k >= parameters_type_data->number_of_parameters()) {
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3272 #ifdef ASSERT
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3273 int extra = 0;
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3274 if (MethodData::profile_arguments() && TypeProfileParmsLimit != -1 &&
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3275 x->nb_profiled_args() >= TypeProfileParmsLimit &&
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3276 x->recv() != NULL && Bytecodes::has_receiver(bc)) {
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3277 extra += 1;
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3278 }
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3279 assert(i == x->nb_profiled_args() - extra || (TypeProfileParmsLimit != -1 && TypeProfileArgsLimit > TypeProfileParmsLimit), "unused parameters?");
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3280 #endif
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3281 break;
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3282 }
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3283 arg = x->profiled_arg_at(i);
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3284 not_null = !x->arg_needs_null_check(i);
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3285 i++;
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3286 }
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3287 }
12875
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
3288 }
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
3289 }
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
3290 }
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
3291
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3292 void LIRGenerator::do_ProfileCall(ProfileCall* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3293 // Need recv in a temporary register so it interferes with the other temporaries
a61af66fc99e Initial load
duke
parents:
diff changeset
3294 LIR_Opr recv = LIR_OprFact::illegalOpr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3295 LIR_Opr mdo = new_register(T_OBJECT);
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3296 // tmp is used to hold the counters on SPARC
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3297 LIR_Opr tmp = new_pointer_register();
12875
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
3298
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
3299 if (x->nb_profiled_args() > 0) {
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
3300 profile_arguments(x);
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
3301 }
d13d7aba8c12 8023657: New type profiling points: arguments to call
roland
parents: 12868
diff changeset
3302
12962
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3303 // profile parameters on inlined method entry including receiver
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3304 if (x->recv() != NULL || x->nb_profiled_args() > 0) {
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3305 profile_parameters_at_call(x);
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3306 }
5ccbab1c69f3 8026251: New type profiling points: parameters to methods
roland
parents: 12955
diff changeset
3307
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3308 if (x->recv() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3309 LIRItem value(x->recv(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
3310 value.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
3311 recv = new_register(T_OBJECT);
a61af66fc99e Initial load
duke
parents:
diff changeset
3312 __ move(value.result(), recv);
a61af66fc99e Initial load
duke
parents:
diff changeset
3313 }
6266
1d7922586cf6 7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents: 6145
diff changeset
3314 __ profile_call(x->method(), x->bci_of_invoke(), x->callee(), mdo, recv, tmp, x->known_holder());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3315 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3316
12882
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
3317 void LIRGenerator::do_ProfileReturnType(ProfileReturnType* x) {
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
3318 int bci = x->bci_of_invoke();
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
3319 ciMethodData* md = x->method()->method_data_or_null();
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
3320 ciProfileData* data = md->bci_to_data(bci);
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
3321 assert(data->is_CallTypeData() || data->is_VirtualCallTypeData(), "wrong profile data type");
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
3322 ciReturnTypeEntry* ret = data->is_CallTypeData() ? ((ciCallTypeData*)data)->ret() : ((ciVirtualCallTypeData*)data)->ret();
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
3323 LIR_Opr mdp = LIR_OprFact::illegalOpr;
13078
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3324
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3325 bool ignored_will_link;
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3326 ciSignature* signature_at_call = NULL;
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3327 x->method()->get_method_at_bci(bci, ignored_will_link, &signature_at_call);
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3328
17628
add2caa66e7e 8026253: New type profiling points: sparc support
roland
parents: 13078
diff changeset
3329 // The offset within the MDO of the entry to update may be too large
add2caa66e7e 8026253: New type profiling points: sparc support
roland
parents: 13078
diff changeset
3330 // to be used in load/store instructions on some platforms. So have
add2caa66e7e 8026253: New type profiling points: sparc support
roland
parents: 13078
diff changeset
3331 // profile_type() compute the address of the profile in a register.
add2caa66e7e 8026253: New type profiling points: sparc support
roland
parents: 13078
diff changeset
3332 ciKlass* exact = profile_type(md, md->byte_offset_of_slot(data, ret->type_offset()), 0,
13078
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3333 ret->type(), x->ret(), mdp,
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3334 !x->needs_null_check(),
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3335 signature_at_call->return_type()->as_klass(),
e6ba215af802 8027631: "unexpected profiling mismatch" error with new type profiling
roland
parents: 12969
diff changeset
3336 x->callee()->signature()->return_type()->as_klass());
12882
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
3337 if (exact != NULL) {
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
3338 md->set_return_type(bci, exact);
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
3339 }
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
3340 }
ce0cc25bc5e2 8026054: New type profiling points: type of return values at calls
roland
parents: 12875
diff changeset
3341
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3342 void LIRGenerator::do_ProfileInvoke(ProfileInvoke* x) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3343 // We can safely ignore accessors here, since c2 will inline them anyway,
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3344 // accessors are also always mature.
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3345 if (!x->inlinee()->is_accessor()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3346 CodeEmitInfo* info = state_for(x, x->state(), true);
3964
dc45ae774613 7096639: Tiered: Incorrect counter overflow handling for inlined methods
iveresov
parents: 3756
diff changeset
3347 // Notify the runtime very infrequently only to take care of counter overflows
dc45ae774613 7096639: Tiered: Incorrect counter overflow handling for inlined methods
iveresov
parents: 3756
diff changeset
3348 increment_event_counter_impl(info, x->inlinee(), (1 << Tier23InlineeNotifyFreqLog) - 1, InvocationEntryBci, false, true);
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3349 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3350 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3351
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3352 void LIRGenerator::increment_event_counter(CodeEmitInfo* info, int bci, bool backedge) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3353 int freq_log;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3354 int level = compilation()->env()->comp_level();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3355 if (level == CompLevel_limited_profile) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3356 freq_log = (backedge ? Tier2BackedgeNotifyFreqLog : Tier2InvokeNotifyFreqLog);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3357 } else if (level == CompLevel_full_profile) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3358 freq_log = (backedge ? Tier3BackedgeNotifyFreqLog : Tier3InvokeNotifyFreqLog);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3359 } else {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3360 ShouldNotReachHere();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3361 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3362 // Increment the appropriate invocation/backedge counter and notify the runtime.
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3363 increment_event_counter_impl(info, info->scope()->method(), (1 << freq_log) - 1, bci, backedge, true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3364 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3365
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3366 void LIRGenerator::increment_event_counter_impl(CodeEmitInfo* info,
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3367 ciMethod *method, int frequency,
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3368 int bci, bool backedge, bool notify) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3369 assert(frequency == 0 || is_power_of_2(frequency + 1), "Frequency must be x^2 - 1 or 0");
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3370 int level = _compilation->env()->comp_level();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3371 assert(level > CompLevel_simple, "Shouldn't be here");
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3372
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3373 int offset = -1;
10105
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 8869
diff changeset
3374 LIR_Opr counter_holder;
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3375 if (level == CompLevel_limited_profile) {
12868
c775af091fe9 8025566: EXCEPTION_ACCESS_VIOLATION in compiled by C1 String.valueOf method
twisti
parents: 12000
diff changeset
3376 MethodCounters* counters_adr = method->ensure_method_counters();
c775af091fe9 8025566: EXCEPTION_ACCESS_VIOLATION in compiled by C1 String.valueOf method
twisti
parents: 12000
diff changeset
3377 if (counters_adr == NULL) {
c775af091fe9 8025566: EXCEPTION_ACCESS_VIOLATION in compiled by C1 String.valueOf method
twisti
parents: 12000
diff changeset
3378 bailout("method counters allocation failed");
c775af091fe9 8025566: EXCEPTION_ACCESS_VIOLATION in compiled by C1 String.valueOf method
twisti
parents: 12000
diff changeset
3379 return;
c775af091fe9 8025566: EXCEPTION_ACCESS_VIOLATION in compiled by C1 String.valueOf method
twisti
parents: 12000
diff changeset
3380 }
10105
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 8869
diff changeset
3381 counter_holder = new_pointer_register();
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 8869
diff changeset
3382 __ move(LIR_OprFact::intptrConst(counters_adr), counter_holder);
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 8869
diff changeset
3383 offset = in_bytes(backedge ? MethodCounters::backedge_counter_offset() :
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 8869
diff changeset
3384 MethodCounters::invocation_counter_offset());
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3385 } else if (level == CompLevel_full_profile) {
10105
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 8869
diff changeset
3386 counter_holder = new_register(T_METADATA);
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6616
diff changeset
3387 offset = in_bytes(backedge ? MethodData::backedge_counter_offset() :
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6616
diff changeset
3388 MethodData::invocation_counter_offset());
2007
5ddfcf4b079e 7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents: 2002
diff changeset
3389 ciMethodData* md = method->method_data_or_null();
5ddfcf4b079e 7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents: 2002
diff changeset
3390 assert(md != NULL, "Sanity");
6739
8a02ca5e5576 7195816: NPG: Crash in c1_ValueType - ShouldNotReachHere
roland
parents: 6731
diff changeset
3391 __ metadata2reg(md->constant_encoding(), counter_holder);
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3392 } else {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3393 ShouldNotReachHere();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3394 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3395 LIR_Address* counter = new LIR_Address(counter_holder, offset, T_INT);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3396 LIR_Opr result = new_register(T_INT);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3397 __ load(counter, result);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3398 __ add(result, LIR_OprFact::intConst(InvocationCounter::count_increment), result);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3399 __ store(result, counter);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3400 if (notify) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3401 LIR_Opr mask = load_immediate(frequency << InvocationCounter::count_shift, T_INT);
10105
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 8869
diff changeset
3402 LIR_Opr meth = new_register(T_METADATA);
aeaca88565e6 8010862: The Method counter fields used for profiling can be allocated lazily.
jiangli
parents: 8869
diff changeset
3403 __ metadata2reg(method->constant_encoding(), meth);
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3404 __ logical_and(result, mask, result);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3405 __ cmp(lir_cond_equal, result, LIR_OprFact::intConst(0));
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3406 // The bci for info can point to cmp for if's we want the if bci
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3407 CodeStub* overflow = new CounterOverflowStub(info, bci, meth);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3408 __ branch(lir_cond_equal, T_INT, overflow);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3409 __ branch_destination(overflow->continuation());
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3410 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3411 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3412
2166
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3413 void LIRGenerator::do_RuntimeCall(RuntimeCall* x) {
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3414 LIR_OprList* args = new LIR_OprList(x->number_of_arguments());
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3415 BasicTypeList* signature = new BasicTypeList(x->number_of_arguments());
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3416
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3417 if (x->pass_thread()) {
12969
9acbfe04b5c3 8026495: JVM Crashes when started with -XX:+DTraceMethodProbes on Solaris x86_64
iveresov
parents: 12962
diff changeset
3418 signature->append(LP64_ONLY(T_LONG) NOT_LP64(T_INT)); // thread
2166
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3419 args->append(getThreadPointer());
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3420 }
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3421
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3422 for (int i = 0; i < x->number_of_arguments(); i++) {
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3423 Value a = x->argument_at(i);
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3424 LIRItem* item = new LIRItem(a, this);
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3425 item->load_item();
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3426 args->append(item->result());
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3427 signature->append(as_BasicType(a->type()));
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3428 }
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3429
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3430 LIR_Opr result = call_runtime(signature, args, x->entry(), x->type(), NULL);
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3431 if (x->type() == voidType) {
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3432 set_no_result(x);
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3433 } else {
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3434 __ move(result, rlock_result(x));
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3435 }
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3436 }
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3437
9156
acadb114c818 8011648: C1: optimized build is broken after 7153771
roland
parents: 9062
diff changeset
3438 #ifdef ASSERT
8860
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3439 void LIRGenerator::do_Assert(Assert *x) {
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3440 ValueTag tag = x->x()->type()->tag();
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3441 If::Condition cond = x->cond();
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3442
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3443 LIRItem xitem(x->x(), this);
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3444 LIRItem yitem(x->y(), this);
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3445 LIRItem* xin = &xitem;
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3446 LIRItem* yin = &yitem;
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3447
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3448 assert(tag == intTag, "Only integer assertions are valid!");
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3449
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3450 xin->load_item();
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3451 yin->dont_load_item();
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3452
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3453 set_no_result(x);
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3454
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3455 LIR_Opr left = xin->result();
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3456 LIR_Opr right = yin->result();
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3457
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3458 __ lir_assert(lir_cond(x->cond()), left, right, x->message(), true);
9156
acadb114c818 8011648: C1: optimized build is broken after 7153771
roland
parents: 9062
diff changeset
3459 }
8860
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3460 #endif
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3461
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3462 void LIRGenerator::do_RangeCheckPredicate(RangeCheckPredicate *x) {
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3463
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3464
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3465 Instruction *a = x->x();
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3466 Instruction *b = x->y();
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3467 if (!a || StressRangeCheckElimination) {
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3468 assert(!b || StressRangeCheckElimination, "B must also be null");
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3469
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3470 CodeEmitInfo *info = state_for(x, x->state());
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3471 CodeStub* stub = new PredicateFailedStub(info);
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3472
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3473 __ jump(stub);
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3474 } else if (a->type()->as_IntConstant() && b->type()->as_IntConstant()) {
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3475 int a_int = a->type()->as_IntConstant()->value();
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3476 int b_int = b->type()->as_IntConstant()->value();
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3477
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3478 bool ok = false;
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3479
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3480 switch(x->cond()) {
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3481 case Instruction::eql: ok = (a_int == b_int); break;
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3482 case Instruction::neq: ok = (a_int != b_int); break;
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3483 case Instruction::lss: ok = (a_int < b_int); break;
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3484 case Instruction::leq: ok = (a_int <= b_int); break;
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3485 case Instruction::gtr: ok = (a_int > b_int); break;
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3486 case Instruction::geq: ok = (a_int >= b_int); break;
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3487 case Instruction::aeq: ok = ((unsigned int)a_int >= (unsigned int)b_int); break;
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3488 case Instruction::beq: ok = ((unsigned int)a_int <= (unsigned int)b_int); break;
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3489 default: ShouldNotReachHere();
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3490 }
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3491
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3492 if (ok) {
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3493
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3494 CodeEmitInfo *info = state_for(x, x->state());
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3495 CodeStub* stub = new PredicateFailedStub(info);
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3496
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3497 __ jump(stub);
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3498 }
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3499 } else {
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3500
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3501 ValueTag tag = x->x()->type()->tag();
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3502 If::Condition cond = x->cond();
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3503 LIRItem xitem(x->x(), this);
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3504 LIRItem yitem(x->y(), this);
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3505 LIRItem* xin = &xitem;
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3506 LIRItem* yin = &yitem;
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3507
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3508 assert(tag == intTag, "Only integer deoptimizations are valid!");
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3509
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3510 xin->load_item();
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3511 yin->dont_load_item();
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3512 set_no_result(x);
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3513
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3514 LIR_Opr left = xin->result();
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3515 LIR_Opr right = yin->result();
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3516
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3517 CodeEmitInfo *info = state_for(x, x->state());
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3518 CodeStub* stub = new PredicateFailedStub(info);
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3519
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3520 __ cmp(lir_cond(cond), left, right);
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3521 __ branch(lir_cond(cond), right->type(), stub);
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3522 }
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3523 }
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3524
46f6f063b272 7153771: array bound check elimination for c1
roland
parents: 8001
diff changeset
3525
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3526 LIR_Opr LIRGenerator::call_runtime(Value arg1, address entry, ValueType* result_type, CodeEmitInfo* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3527 LIRItemList args(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3528 LIRItem value(arg1, this);
a61af66fc99e Initial load
duke
parents:
diff changeset
3529 args.append(&value);
a61af66fc99e Initial load
duke
parents:
diff changeset
3530 BasicTypeList signature;
a61af66fc99e Initial load
duke
parents:
diff changeset
3531 signature.append(as_BasicType(arg1->type()));
a61af66fc99e Initial load
duke
parents:
diff changeset
3532
a61af66fc99e Initial load
duke
parents:
diff changeset
3533 return call_runtime(&signature, &args, entry, result_type, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
3534 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3535
a61af66fc99e Initial load
duke
parents:
diff changeset
3536
a61af66fc99e Initial load
duke
parents:
diff changeset
3537 LIR_Opr LIRGenerator::call_runtime(Value arg1, Value arg2, address entry, ValueType* result_type, CodeEmitInfo* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3538 LIRItemList args(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
3539 LIRItem value1(arg1, this);
a61af66fc99e Initial load
duke
parents:
diff changeset
3540 LIRItem value2(arg2, this);
a61af66fc99e Initial load
duke
parents:
diff changeset
3541 args.append(&value1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3542 args.append(&value2);
a61af66fc99e Initial load
duke
parents:
diff changeset
3543 BasicTypeList signature;
a61af66fc99e Initial load
duke
parents:
diff changeset
3544 signature.append(as_BasicType(arg1->type()));
a61af66fc99e Initial load
duke
parents:
diff changeset
3545 signature.append(as_BasicType(arg2->type()));
a61af66fc99e Initial load
duke
parents:
diff changeset
3546
a61af66fc99e Initial load
duke
parents:
diff changeset
3547 return call_runtime(&signature, &args, entry, result_type, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
3548 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3549
a61af66fc99e Initial load
duke
parents:
diff changeset
3550
a61af66fc99e Initial load
duke
parents:
diff changeset
3551 LIR_Opr LIRGenerator::call_runtime(BasicTypeArray* signature, LIR_OprList* args,
a61af66fc99e Initial load
duke
parents:
diff changeset
3552 address entry, ValueType* result_type, CodeEmitInfo* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3553 // get a result register
a61af66fc99e Initial load
duke
parents:
diff changeset
3554 LIR_Opr phys_reg = LIR_OprFact::illegalOpr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3555 LIR_Opr result = LIR_OprFact::illegalOpr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3556 if (result_type->tag() != voidTag) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3557 result = new_register(result_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
3558 phys_reg = result_register_for(result_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
3559 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3560
a61af66fc99e Initial load
duke
parents:
diff changeset
3561 // move the arguments into the correct location
a61af66fc99e Initial load
duke
parents:
diff changeset
3562 CallingConvention* cc = frame_map()->c_calling_convention(signature);
a61af66fc99e Initial load
duke
parents:
diff changeset
3563 assert(cc->length() == args->length(), "argument mismatch");
a61af66fc99e Initial load
duke
parents:
diff changeset
3564 for (int i = 0; i < args->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3565 LIR_Opr arg = args->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3566 LIR_Opr loc = cc->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3567 if (loc->is_register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3568 __ move(arg, loc);
a61af66fc99e Initial load
duke
parents:
diff changeset
3569 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3570 LIR_Address* addr = loc->as_address_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
3571 // if (!can_store_as_constant(arg)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3572 // LIR_Opr tmp = new_register(arg->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
3573 // __ move(arg, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
3574 // arg = tmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
3575 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
3576 if (addr->type() == T_LONG || addr->type() == T_DOUBLE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3577 __ unaligned_move(arg, addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
3578 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3579 __ move(arg, addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
3580 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3581 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3582 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3583
a61af66fc99e Initial load
duke
parents:
diff changeset
3584 if (info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3585 __ call_runtime(entry, getThreadTemp(), phys_reg, cc->args(), info);
a61af66fc99e Initial load
duke
parents:
diff changeset
3586 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3587 __ call_runtime_leaf(entry, getThreadTemp(), phys_reg, cc->args());
a61af66fc99e Initial load
duke
parents:
diff changeset
3588 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3589 if (result->is_valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3590 __ move(phys_reg, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
3591 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3592 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
3593 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3594
a61af66fc99e Initial load
duke
parents:
diff changeset
3595
a61af66fc99e Initial load
duke
parents:
diff changeset
3596 LIR_Opr LIRGenerator::call_runtime(BasicTypeArray* signature, LIRItemList* args,
a61af66fc99e Initial load
duke
parents:
diff changeset
3597 address entry, ValueType* result_type, CodeEmitInfo* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3598 // get a result register
a61af66fc99e Initial load
duke
parents:
diff changeset
3599 LIR_Opr phys_reg = LIR_OprFact::illegalOpr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3600 LIR_Opr result = LIR_OprFact::illegalOpr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3601 if (result_type->tag() != voidTag) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3602 result = new_register(result_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
3603 phys_reg = result_register_for(result_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
3604 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3605
a61af66fc99e Initial load
duke
parents:
diff changeset
3606 // move the arguments into the correct location
a61af66fc99e Initial load
duke
parents:
diff changeset
3607 CallingConvention* cc = frame_map()->c_calling_convention(signature);
a61af66fc99e Initial load
duke
parents:
diff changeset
3608
a61af66fc99e Initial load
duke
parents:
diff changeset
3609 assert(cc->length() == args->length(), "argument mismatch");
a61af66fc99e Initial load
duke
parents:
diff changeset
3610 for (int i = 0; i < args->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3611 LIRItem* arg = args->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3612 LIR_Opr loc = cc->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3613 if (loc->is_register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3614 arg->load_item_force(loc);
a61af66fc99e Initial load
duke
parents:
diff changeset
3615 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3616 LIR_Address* addr = loc->as_address_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
3617 arg->load_for_store(addr->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
3618 if (addr->type() == T_LONG || addr->type() == T_DOUBLE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3619 __ unaligned_move(arg->result(), addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
3620 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3621 __ move(arg->result(), addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
3622 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3623 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3624 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3625
a61af66fc99e Initial load
duke
parents:
diff changeset
3626 if (info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3627 __ call_runtime(entry, getThreadTemp(), phys_reg, cc->args(), info);
a61af66fc99e Initial load
duke
parents:
diff changeset
3628 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3629 __ call_runtime_leaf(entry, getThreadTemp(), phys_reg, cc->args());
a61af66fc99e Initial load
duke
parents:
diff changeset
3630 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3631 if (result->is_valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3632 __ move(phys_reg, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
3633 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3634 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
3635 }
4966
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4816
diff changeset
3636
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4816
diff changeset
3637 void LIRGenerator::do_MemBar(MemBar* x) {
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4816
diff changeset
3638 if (os::is_MP()) {
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4816
diff changeset
3639 LIR_Code code = x->code();
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4816
diff changeset
3640 switch(code) {
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4816
diff changeset
3641 case lir_membar_acquire : __ membar_acquire(); break;
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4816
diff changeset
3642 case lir_membar_release : __ membar_release(); break;
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4816
diff changeset
3643 case lir_membar : __ membar(); break;
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4816
diff changeset
3644 case lir_membar_loadload : __ membar_loadload(); break;
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4816
diff changeset
3645 case lir_membar_storestore: __ membar_storestore(); break;
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4816
diff changeset
3646 case lir_membar_loadstore : __ membar_loadstore(); break;
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4816
diff changeset
3647 case lir_membar_storeload : __ membar_storeload(); break;
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4816
diff changeset
3648 default : ShouldNotReachHere(); break;
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4816
diff changeset
3649 }
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4816
diff changeset
3650 }
701a83c86f28 7120481: storeStore barrier in constructor with final field
jiangli
parents: 4816
diff changeset
3651 }