annotate src/share/vm/c1/c1_LIRGenerator.cpp @ 6862:8a5ea0a9ccc4

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