annotate src/share/vm/c1/c1_LIRGenerator.cpp @ 4710:41406797186b

7113012: G1: rename not-fully-young GCs as "mixed" Summary: Renamed partially-young GCs as mixed and fully-young GCs as young. Change all external output that includes those terms (GC log and GC ergo log) as well as any comments, fields, methods, etc. The changeset also includes very minor code tidying up (added some curly brackets). Reviewed-by: johnc, brutisso
author tonyp
date Fri, 16 Dec 2011 02:14:27 -0500
parents 973293defacd
children 04b9a2566eec 069ab3f976d3
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
2166
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
2 * Copyright (c) 2005, 2011, 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/ciCPCache.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1873
diff changeset
34 #include "ci/ciInstance.hpp"
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
a61af66fc99e Initial load
duke
parents:
diff changeset
464 void LIRGenerator::jobject2reg_with_patching(LIR_Opr r, ciObject* obj, CodeEmitInfo* info) {
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");
a61af66fc99e Initial load
duke
parents:
diff changeset
467 __ oop2reg_patch(NULL, r, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
468 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
469 // no patching needed
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 819
diff changeset
470 __ oop2reg(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) {
a61af66fc99e Initial load
duke
parents:
diff changeset
660 jobject2reg_with_patching(klass_reg, klass, info);
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) {
a61af66fc99e Initial load
duke
parents:
diff changeset
923 assert(type2size[t] == type2size[value->type()], "size mismatch");
a61af66fc99e Initial load
duke
parents:
diff changeset
924 if (!value->is_register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
925 // force into a register
a61af66fc99e Initial load
duke
parents:
diff changeset
926 LIR_Opr r = new_register(value->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
927 __ move(value, r);
a61af66fc99e Initial load
duke
parents:
diff changeset
928 value = r;
a61af66fc99e Initial load
duke
parents:
diff changeset
929 }
a61af66fc99e Initial load
duke
parents:
diff changeset
930
a61af66fc99e Initial load
duke
parents:
diff changeset
931 // create a spill location
a61af66fc99e Initial load
duke
parents:
diff changeset
932 LIR_Opr tmp = new_register(t);
a61af66fc99e Initial load
duke
parents:
diff changeset
933 set_vreg_flag(tmp, LIRGenerator::must_start_in_memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
934
a61af66fc99e Initial load
duke
parents:
diff changeset
935 // move from register to spill
a61af66fc99e Initial load
duke
parents:
diff changeset
936 __ move(value, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
937 return tmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
938 }
a61af66fc99e Initial load
duke
parents:
diff changeset
939
a61af66fc99e Initial load
duke
parents:
diff changeset
940 void LIRGenerator::profile_branch(If* if_instr, If::Condition cond) {
a61af66fc99e Initial load
duke
parents:
diff changeset
941 if (if_instr->should_profile()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
942 ciMethod* method = if_instr->profiled_method();
a61af66fc99e Initial load
duke
parents:
diff changeset
943 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
944 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
945 assert(md != NULL, "Sanity");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
946 ciProfileData* data = md->bci_to_data(if_instr->profiled_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
947 assert(data != NULL, "must have profiling data");
a61af66fc99e Initial load
duke
parents:
diff changeset
948 assert(data->is_BranchData(), "need BranchData for two-way branches");
a61af66fc99e Initial load
duke
parents:
diff changeset
949 int taken_count_offset = md->byte_offset_of_slot(data, BranchData::taken_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
950 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
951 if (if_instr->is_swapped()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
952 int t = taken_count_offset;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
953 taken_count_offset = not_taken_count_offset;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
954 not_taken_count_offset = t;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
955 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
956
0
a61af66fc99e Initial load
duke
parents:
diff changeset
957 LIR_Opr md_reg = new_register(T_OBJECT);
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
958 __ oop2reg(md->constant_encoding(), md_reg);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
959
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
960 LIR_Opr data_offset_reg = new_pointer_register();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
961 __ cmove(lir_cond(cond),
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
962 LIR_OprFact::intptrConst(taken_count_offset),
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
963 LIR_OprFact::intptrConst(not_taken_count_offset),
2089
037c727f35fb 7009231: C1: Incorrect CAS code for longs on SPARC 32bit
iveresov
parents: 2007
diff changeset
964 data_offset_reg, as_BasicType(if_instr->x()->type()));
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
965
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
966 // MDO cells are intptr_t, so the data_reg width is arch-dependent.
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
967 LIR_Opr data_reg = new_pointer_register();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
968 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
969 __ move(data_addr, data_reg);
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
970 // Use leal instead of add to avoid destroying condition codes on x86
0
a61af66fc99e Initial load
duke
parents:
diff changeset
971 LIR_Address* fake_incr_value = new LIR_Address(data_reg, DataLayout::counter_increment, T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
972 __ leal(LIR_OprFact::address(fake_incr_value), data_reg);
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
973 __ move(data_reg, data_addr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
974 }
a61af66fc99e Initial load
duke
parents:
diff changeset
975 }
a61af66fc99e Initial load
duke
parents:
diff changeset
976
a61af66fc99e Initial load
duke
parents:
diff changeset
977 // Phi technique:
a61af66fc99e Initial load
duke
parents:
diff changeset
978 // This is about passing live values from one basic block to the other.
a61af66fc99e Initial load
duke
parents:
diff changeset
979 // In code generated with Java it is rather rare that more than one
a61af66fc99e Initial load
duke
parents:
diff changeset
980 // value is on the stack from one basic block to the other.
a61af66fc99e Initial load
duke
parents:
diff changeset
981 // We optimize our technique for efficient passing of one value
a61af66fc99e Initial load
duke
parents:
diff changeset
982 // (of type long, int, double..) but it can be extended.
a61af66fc99e Initial load
duke
parents:
diff changeset
983 // When entering or leaving a basic block, all registers and all spill
a61af66fc99e Initial load
duke
parents:
diff changeset
984 // slots are release and empty. We use the released registers
a61af66fc99e Initial load
duke
parents:
diff changeset
985 // and spill slots to pass the live values from one block
a61af66fc99e Initial load
duke
parents:
diff changeset
986 // to the other. The topmost value, i.e., the value on TOS of expression
a61af66fc99e Initial load
duke
parents:
diff changeset
987 // stack is passed in registers. All other values are stored in spilling
a61af66fc99e Initial load
duke
parents:
diff changeset
988 // area. Every Phi has an index which designates its spill slot
a61af66fc99e Initial load
duke
parents:
diff changeset
989 // At exit of a basic block, we fill the register(s) and spill slots.
a61af66fc99e Initial load
duke
parents:
diff changeset
990 // At entry of a basic block, the block_prolog sets up the content of phi nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
991 // and locks necessary registers and spilling slots.
a61af66fc99e Initial load
duke
parents:
diff changeset
992
a61af66fc99e Initial load
duke
parents:
diff changeset
993
a61af66fc99e Initial load
duke
parents:
diff changeset
994 // move current value to referenced phi function
a61af66fc99e Initial load
duke
parents:
diff changeset
995 void LIRGenerator::move_to_phi(PhiResolver* resolver, Value cur_val, Value sux_val) {
a61af66fc99e Initial load
duke
parents:
diff changeset
996 Phi* phi = sux_val->as_Phi();
a61af66fc99e Initial load
duke
parents:
diff changeset
997 // cur_val can be null without phi being null in conjunction with inlining
a61af66fc99e Initial load
duke
parents:
diff changeset
998 if (phi != NULL && cur_val != NULL && cur_val != phi && !phi->is_illegal()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
999 LIR_Opr operand = cur_val->operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 if (cur_val->operand()->is_illegal()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 assert(cur_val->as_Constant() != NULL || cur_val->as_Local() != NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 "these can be produced lazily");
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 operand = operand_for_instruction(cur_val);
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 resolver->move(operand, operand_for_instruction(phi));
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1008
a61af66fc99e Initial load
duke
parents:
diff changeset
1009
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 // Moves all stack values into their PHI position
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 void LIRGenerator::move_to_phi(ValueStack* cur_state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 BlockBegin* bb = block();
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 if (bb->number_of_sux() == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 BlockBegin* sux = bb->sux_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 assert(sux->number_of_preds() > 0, "invalid CFG");
a61af66fc99e Initial load
duke
parents:
diff changeset
1016
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 // a block with only one predecessor never has phi functions
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 if (sux->number_of_preds() > 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 int max_phis = cur_state->stack_size() + cur_state->locals_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 PhiResolver resolver(this, _virtual_register_number + max_phis * 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1021
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 ValueStack* sux_state = sux->state();
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 Value sux_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 int index;
a61af66fc99e Initial load
duke
parents:
diff changeset
1025
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
1026 assert(cur_state->scope() == sux_state->scope(), "not matching");
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
1027 assert(cur_state->locals_size() == sux_state->locals_size(), "not matching");
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
1028 assert(cur_state->stack_size() == sux_state->stack_size(), "not matching");
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
1029
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 for_each_stack_value(sux_state, index, sux_value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 move_to_phi(&resolver, cur_state->stack_at(index), sux_value);
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1033
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 for_each_local_value(sux_state, index, sux_value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 move_to_phi(&resolver, cur_state->local_at(index), sux_value);
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1037
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 assert(cur_state->caller_state() == sux_state->caller_state(), "caller states must be equal");
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1042
a61af66fc99e Initial load
duke
parents:
diff changeset
1043
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 LIR_Opr LIRGenerator::new_register(BasicType type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 int vreg = _virtual_register_number;
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 // add a little fudge factor for the bailout, since the bailout is
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 // only checked periodically. This gives a few extra registers to
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 // hand out before we really run out, which helps us keep from
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 // tripping over assertions.
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 if (vreg + 20 >= LIR_OprDesc::vreg_max) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 bailout("out of virtual registers");
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 if (vreg + 2 >= LIR_OprDesc::vreg_max) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 // wrap it around
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 _virtual_register_number = LIR_OprDesc::vreg_base;
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 _virtual_register_number += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 return LIR_OprFact::virtual_register(vreg, type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1060
a61af66fc99e Initial load
duke
parents:
diff changeset
1061
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 // Try to lock using register in hint
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 LIR_Opr LIRGenerator::rlock(Value instr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 return new_register(instr->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1066
a61af66fc99e Initial load
duke
parents:
diff changeset
1067
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 // does an rlock and sets result
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 LIR_Opr LIRGenerator::rlock_result(Value x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 LIR_Opr reg = rlock(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 set_result(x, reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 return reg;
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1074
a61af66fc99e Initial load
duke
parents:
diff changeset
1075
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 // does an rlock and sets result
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 LIR_Opr LIRGenerator::rlock_result(Value x, BasicType type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 LIR_Opr reg;
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 switch (type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 case T_BYTE:
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 case T_BOOLEAN:
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 reg = rlock_byte(type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 reg = rlock(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1088
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 set_result(x, reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 return reg;
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1092
a61af66fc99e Initial load
duke
parents:
diff changeset
1093
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 //---------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 ciObject* LIRGenerator::get_jobject_constant(Value value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 ObjectType* oc = value->type()->as_ObjectType();
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 if (oc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 return oc->constant_value();
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1102
a61af66fc99e Initial load
duke
parents:
diff changeset
1103
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 void LIRGenerator::do_ExceptionObject(ExceptionObject* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 assert(block()->is_set(BlockBegin::exception_entry_flag), "ExceptionObject only allowed in exception handler block");
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 assert(block()->next() == x, "ExceptionObject must be first instruction of block");
a61af66fc99e Initial load
duke
parents:
diff changeset
1107
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 // no moves are created for phi functions at the begin of exception
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 // handlers, so assign operands manually here
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 for_each_phi_fun(block(), phi,
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 operand_for_instruction(phi));
a61af66fc99e Initial load
duke
parents:
diff changeset
1112
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 LIR_Opr thread_reg = getThreadPointer();
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1114 __ 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
1115 exceptionOopOpr());
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1116 __ move_wide(LIR_OprFact::oopConst(NULL),
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1117 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
1118 __ move_wide(LIR_OprFact::oopConst(NULL),
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1119 new LIR_Address(thread_reg, in_bytes(JavaThread::exception_pc_offset()), T_OBJECT));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1120
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 LIR_Opr result = new_register(T_OBJECT);
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 __ move(exceptionOopOpr(), result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 set_result(x, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1125
a61af66fc99e Initial load
duke
parents:
diff changeset
1126
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 // visitor functions
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1136
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 void LIRGenerator::do_Phi(Phi* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 // phi functions are never visited directly
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1141
a61af66fc99e Initial load
duke
parents:
diff changeset
1142
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 // 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
1144 void LIRGenerator::do_Constant(Constant* x) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
1145 if (x->state_before() != NULL) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 // Any constant with a ValueStack requires patching so emit the patch here
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 LIR_Opr reg = rlock_result(x);
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
1148 CodeEmitInfo* info = state_for(x, x->state_before());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 __ oop2reg_patch(NULL, reg, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 } else if (x->use_count() > 1 && !can_inline_as_constant(x)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 if (!x->is_pinned()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 // unpinned constants are handled specially so that they can be
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 // put into registers when they are used multiple times within a
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 // block. After the block completes their operand will be
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 // cleared so that other blocks can't refer to that register.
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 set_result(x, load_constant(x));
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 LIR_Opr res = x->operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 if (!res->is_valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 res = LIR_OprFact::value_type(x->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 if (res->is_constant()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 LIR_Opr reg = rlock_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 __ move(res, reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 set_result(x, res);
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 set_result(x, LIR_OprFact::value_type(x->type()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1173
a61af66fc99e Initial load
duke
parents:
diff changeset
1174
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 void LIRGenerator::do_Local(Local* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 // operand_for_instruction has the side effect of setting the result
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 // so there's no need to do it here.
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 operand_for_instruction(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1180
a61af66fc99e Initial load
duke
parents:
diff changeset
1181
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 void LIRGenerator::do_IfInstanceOf(IfInstanceOf* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 Unimplemented();
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1185
a61af66fc99e Initial load
duke
parents:
diff changeset
1186
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 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
1188 if (compilation()->env()->dtrace_method_probes()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 BasicTypeList signature;
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1190 signature.append(LP64_ONLY(T_LONG) NOT_LP64(T_INT)); // thread
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 signature.append(T_OBJECT); // methodOop
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 LIR_OprList* args = new LIR_OprList();
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 args->append(getThreadPointer());
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 LIR_Opr meth = new_register(T_OBJECT);
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 819
diff changeset
1195 __ oop2reg(method()->constant_encoding(), meth);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 args->append(meth);
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 call_runtime(&signature, args, CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), voidType, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1199
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 if (x->type()->is_void()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 __ return_op(LIR_OprFact::illegalOpr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 LIR_Opr reg = result_register_for(x->type(), /*callee=*/true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 LIRItem result(x->result(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1205
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 result.load_item_force(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 __ return_op(result.result());
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 set_no_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1211
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1212 // Examble: ref.get()
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1213 // 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
1214 void LIRGenerator::do_Reference_get(Intrinsic* x) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1215
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1216 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
1217 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
1218
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1219 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
1220
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1221 LIRItem reference(x->argument_at(0), this);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1222 reference.load_item();
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1223
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1224 // 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
1225 CodeEmitInfo* info = NULL;
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1226 if (x->needs_null_check()) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1227 info = state_for(x);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1228 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1229
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1230 LIR_Address* referent_field_adr =
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1231 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
1232
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1233 LIR_Opr result = rlock_result(x);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1234
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1235 __ load(referent_field_adr, result, info);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1236
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1237 // 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
1238 pre_barrier(LIR_OprFact::illegalOpr /* addr_opr */,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1239 result /* pre_val */,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1240 false /* do_load */,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1241 false /* patch */,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1242 NULL /* info */);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1243 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1244
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 // Example: object.getClass ()
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 void LIRGenerator::do_getClass(Intrinsic* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 assert(x->number_of_arguments() == 1, "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
1248
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 LIRItem rcvr(x->argument_at(0), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 rcvr.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 LIR_Opr result = rlock_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1252
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 // need to perform the null check on the rcvr
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 CodeEmitInfo* info = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 if (x->needs_null_check()) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
1256 info = state_for(x);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 __ move(new LIR_Address(rcvr.result(), oopDesc::klass_offset_in_bytes(), T_OBJECT), result, info);
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1259 __ move_wide(new LIR_Address(result, Klass::java_mirror_offset_in_bytes() +
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1260 klassOopDesc::klass_part_offset_in_bytes(), T_OBJECT), result);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1262
a61af66fc99e Initial load
duke
parents:
diff changeset
1263
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 // Example: Thread.currentThread()
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 void LIRGenerator::do_currentThread(Intrinsic* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 assert(x->number_of_arguments() == 0, "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 LIR_Opr reg = rlock_result(x);
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
1268 __ move_wide(new LIR_Address(getThreadPointer(), in_bytes(JavaThread::threadObj_offset()), T_OBJECT), reg);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1270
a61af66fc99e Initial load
duke
parents:
diff changeset
1271
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 void LIRGenerator::do_RegisterFinalizer(Intrinsic* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 assert(x->number_of_arguments() == 1, "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 LIRItem receiver(x->argument_at(0), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1275
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 receiver.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 BasicTypeList signature;
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 signature.append(T_OBJECT); // receiver
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 LIR_OprList* args = new LIR_OprList();
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 args->append(receiver.result());
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 CodeEmitInfo* info = state_for(x, x->state());
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 call_runtime(&signature, args,
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 CAST_FROM_FN_PTR(address, Runtime1::entry_for(Runtime1::register_finalizer_id)),
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 voidType, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1285
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 set_no_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1288
a61af66fc99e Initial load
duke
parents:
diff changeset
1289
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 //------------------------local access--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1291
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 LIR_Opr LIRGenerator::operand_for_instruction(Instruction* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 if (x->operand()->is_illegal()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 Constant* c = x->as_Constant();
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 if (c != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 x->set_operand(LIR_OprFact::value_type(c->type()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 assert(x->as_Phi() || x->as_Local() != NULL, "only for Phi and Local");
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 // allocate a virtual register for this local or phi
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 x->set_operand(rlock(x));
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 _instruction_for_operand.at_put_grow(x->operand()->vreg_number(), x, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 return x->operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1306
a61af66fc99e Initial load
duke
parents:
diff changeset
1307
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 Instruction* LIRGenerator::instruction_for_opr(LIR_Opr opr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 if (opr->is_virtual()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 return instruction_for_vreg(opr->vreg_number());
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1314
a61af66fc99e Initial load
duke
parents:
diff changeset
1315
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 Instruction* LIRGenerator::instruction_for_vreg(int reg_num) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 if (reg_num < _instruction_for_operand.length()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 return _instruction_for_operand.at(reg_num);
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1322
a61af66fc99e Initial load
duke
parents:
diff changeset
1323
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 void LIRGenerator::set_vreg_flag(int vreg_num, VregFlag f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 if (_vreg_flags.size_in_bits() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 BitMap2D temp(100, num_vreg_flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 temp.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 _vreg_flags = temp;
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 _vreg_flags.at_put_grow(vreg_num, f, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1332
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 bool LIRGenerator::is_vreg_flag_set(int vreg_num, VregFlag f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 if (!_vreg_flags.is_valid_index(vreg_num, f)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 return _vreg_flags.at(vreg_num, f);
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1339
a61af66fc99e Initial load
duke
parents:
diff changeset
1340
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 // Block local constant handling. This code is useful for keeping
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 // unpinned constants and constants which aren't exposed in the IR in
a61af66fc99e Initial load
duke
parents:
diff changeset
1343 // registers. Unpinned Constant instructions have their operands
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 // cleared when the block is finished so that other blocks can't end
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 // up referring to their registers.
a61af66fc99e Initial load
duke
parents:
diff changeset
1346
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 LIR_Opr LIRGenerator::load_constant(Constant* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 assert(!x->is_pinned(), "only for unpinned constants");
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 _unpinned_constants.append(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 return load_constant(LIR_OprFact::value_type(x->type())->as_constant_ptr());
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 LIR_Opr LIRGenerator::load_constant(LIR_Const* c) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 BasicType t = c->type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 for (int i = 0; i < _constants.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 LIR_Const* other = _constants.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 if (t == other->type()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 switch (t) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 case T_INT:
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 case T_FLOAT:
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 if (c->as_jint_bits() != other->as_jint_bits()) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 case T_LONG:
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 case T_DOUBLE:
486
a738a625039a 6757316: load_constant() produces a wrong long constant, with high a low words swapped
never
parents: 380
diff changeset
1366 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
1367 if (c->as_jint_lo_bits() != other->as_jint_lo_bits()) continue;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 case T_OBJECT:
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 if (c->as_jobject() != other->as_jobject()) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 return _reg_for_constants.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1376
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 LIR_Opr result = new_register(t);
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 __ move((LIR_Opr)c, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 _constants.append(c);
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 _reg_for_constants.append(result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1383
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 // Various barriers
a61af66fc99e Initial load
duke
parents:
diff changeset
1385
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1386 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
1387 bool do_load, bool patch, CodeEmitInfo* info) {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1388 // Do the pre-write barrier, if any.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1389 switch (_bs->kind()) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1390 #ifndef SERIALGC
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1391 case BarrierSet::G1SATBCT:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1392 case BarrierSet::G1SATBCTLogging:
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1393 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
1394 break;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1395 #endif // SERIALGC
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1396 case BarrierSet::CardTableModRef:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1397 case BarrierSet::CardTableExtension:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1398 // No pre barriers
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1399 break;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1400 case BarrierSet::ModRef:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1401 case BarrierSet::Other:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1402 // No pre barriers
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1403 break;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1404 default :
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1405 ShouldNotReachHere();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1406
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1407 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1408 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1409
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 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
1411 switch (_bs->kind()) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1412 #ifndef SERIALGC
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1413 case BarrierSet::G1SATBCT:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1414 case BarrierSet::G1SATBCTLogging:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1415 G1SATBCardTableModRef_post_barrier(addr, new_val);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1416 break;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1417 #endif // SERIALGC
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1418 case BarrierSet::CardTableModRef:
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 case BarrierSet::CardTableExtension:
a61af66fc99e Initial load
duke
parents:
diff changeset
1420 CardTableModRef_post_barrier(addr, new_val);
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 case BarrierSet::ModRef:
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 case BarrierSet::Other:
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 // No post barriers
a61af66fc99e Initial load
duke
parents:
diff changeset
1425 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1426 default :
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1430
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1431 ////////////////////////////////////////////////////////////////////////
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1432 #ifndef SERIALGC
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1433
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1434 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
1435 bool do_load, bool patch, CodeEmitInfo* info) {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1436 // First we test whether marking is in progress.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1437 BasicType flag_type;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1438 if (in_bytes(PtrQueue::byte_width_of_active()) == 4) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1439 flag_type = T_INT;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1440 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1441 guarantee(in_bytes(PtrQueue::byte_width_of_active()) == 1,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1442 "Assumption");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1443 flag_type = T_BYTE;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1444 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1445 LIR_Opr thrd = getThreadPointer();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1446 LIR_Address* mark_active_flag_addr =
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1447 new LIR_Address(thrd,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1448 in_bytes(JavaThread::satb_mark_queue_offset() +
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1449 PtrQueue::byte_offset_of_active()),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1450 flag_type);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1451 // Read the marking-in-progress flag.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1452 LIR_Opr flag_val = new_register(T_INT);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1453 __ load(mark_active_flag_addr, flag_val);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1454 __ 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
1455
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1456 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
1457
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1458 CodeStub* slow;
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1459
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1460 if (do_load) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1461 assert(pre_val == LIR_OprFact::illegalOpr, "sanity");
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1462 assert(addr_opr != LIR_OprFact::illegalOpr, "sanity");
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1463
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1464 if (patch)
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1465 pre_val_patch_code = lir_patch_normal;
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1466
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1467 pre_val = new_register(T_OBJECT);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1468
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1469 if (!addr_opr->is_address()) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1470 assert(addr_opr->is_register(), "must be");
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1471 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
1472 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1473 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
1474 } else {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1475 assert(addr_opr == LIR_OprFact::illegalOpr, "sanity");
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1476 assert(pre_val->is_register(), "must be");
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1477 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
1478 assert(info == NULL, "sanity");
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1479
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1480 slow = new G1PreBarrierStub(pre_val);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1481 }
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1482
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1483 __ branch(lir_cond_notEqual, T_INT, slow);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1484 __ branch_destination(slow->continuation());
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1485 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1486
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1487 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
1488 // 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
1489 if (new_val->is_constant() &&
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1490 new_val->as_constant_ptr()->as_jobject() == NULL) return;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1491
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1492 if (!new_val->is_register()) {
1572
87fc6aca31ab 6955349: C1: Make G1 barriers work with x64
iveresov
parents: 1564
diff changeset
1493 LIR_Opr new_val_reg = new_register(T_OBJECT);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1494 if (new_val->is_constant()) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1495 __ move(new_val, new_val_reg);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1496 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1497 __ leal(new_val, new_val_reg);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1498 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1499 new_val = new_val_reg;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1500 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1501 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
1502
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1503 if (addr->is_address()) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1504 LIR_Address* address = addr->as_address_ptr();
2464
d86923d96dca 7034967: C1: assert(false) failed: error (assembler_sparc.cpp:2043)
iveresov
parents: 2446
diff changeset
1505 LIR_Opr ptr = new_pointer_register();
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1506 if (!address->index()->is_valid() && address->disp() == 0) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1507 __ move(address->base(), ptr);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1508 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1509 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
1510 __ leal(addr, ptr);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1511 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1512 addr = ptr;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1513 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1514 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
1515
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1516 LIR_Opr xor_res = new_pointer_register();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1517 LIR_Opr xor_shift_res = new_pointer_register();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1518 if (TwoOperandLIRForm ) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1519 __ move(addr, xor_res);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1520 __ logical_xor(xor_res, new_val, xor_res);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1521 __ move(xor_res, xor_shift_res);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1522 __ unsigned_shift_right(xor_shift_res,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1523 LIR_OprFact::intConst(HeapRegion::LogOfHRGrainBytes),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1524 xor_shift_res,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1525 LIR_OprDesc::illegalOpr());
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 __ logical_xor(addr, new_val, xor_res);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1528 __ unsigned_shift_right(xor_res,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1529 LIR_OprFact::intConst(HeapRegion::LogOfHRGrainBytes),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1530 xor_shift_res,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1531 LIR_OprDesc::illegalOpr());
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
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1534 if (!new_val->is_register()) {
1572
87fc6aca31ab 6955349: C1: Make G1 barriers work with x64
iveresov
parents: 1564
diff changeset
1535 LIR_Opr new_val_reg = new_register(T_OBJECT);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1536 __ leal(new_val, new_val_reg);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1537 new_val = new_val_reg;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1538 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1539 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
1540
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1541 __ 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
1542
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1543 CodeStub* slow = new G1PostBarrierStub(addr, new_val);
1572
87fc6aca31ab 6955349: C1: Make G1 barriers work with x64
iveresov
parents: 1564
diff changeset
1544 __ 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
1545 __ branch_destination(slow->continuation());
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1546 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1547
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1548 #endif // SERIALGC
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1549 ////////////////////////////////////////////////////////////////////////
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1550
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1551 void LIRGenerator::CardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1552
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1553 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
1554 LIR_Const* card_table_base = new LIR_Const(((CardTableModRefBS*)_bs)->byte_map_base);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1555 if (addr->is_address()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1556 LIR_Address* address = addr->as_address_ptr();
2464
d86923d96dca 7034967: C1: assert(false) failed: error (assembler_sparc.cpp:2043)
iveresov
parents: 2446
diff changeset
1557 // 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
1558 // 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
1559 LIR_Opr ptr = new_pointer_register();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1560 if (!address->index()->is_valid() && address->disp() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1561 __ move(address->base(), ptr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1562 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1563 assert(address->disp() != max_jint, "lea doesn't support patched addresses!");
a61af66fc99e Initial load
duke
parents:
diff changeset
1564 __ leal(addr, ptr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1565 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1566 addr = ptr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1567 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1568 assert(addr->is_register(), "must be a register at this point");
a61af66fc99e Initial load
duke
parents:
diff changeset
1569
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1570 #ifdef ARM
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1571 // TODO: ARM - move to platform-dependent code
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1572 LIR_Opr tmp = FrameMap::R14_opr;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1573 if (VM_Version::supports_movw()) {
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1574 __ move((LIR_Opr)card_table_base, tmp);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1575 } else {
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1576 __ 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
1577 }
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1578
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1579 CardTableModRefBS* ct = (CardTableModRefBS*)_bs;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1580 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
1581 if(((int)ct->byte_map_base & 0xff) == 0) {
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1582 __ move(tmp, card_addr);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1583 } else {
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1584 LIR_Opr tmp_zero = new_register(T_INT);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1585 __ move(LIR_OprFact::intConst(0), tmp_zero);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1586 __ move(tmp_zero, card_addr);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1587 }
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1588 #else // ARM
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1589 LIR_Opr tmp = new_pointer_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
1590 if (TwoOperandLIRForm) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1591 __ move(addr, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1592 __ unsigned_shift_right(tmp, CardTableModRefBS::card_shift, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1593 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1594 __ unsigned_shift_right(addr, CardTableModRefBS::card_shift, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1595 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 if (can_inline_as_constant(card_table_base)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 __ move(LIR_OprFact::intConst(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
1598 new LIR_Address(tmp, card_table_base->as_jint(), T_BYTE));
a61af66fc99e Initial load
duke
parents:
diff changeset
1599 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1600 __ move(LIR_OprFact::intConst(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
1601 new LIR_Address(tmp, load_constant(card_table_base),
a61af66fc99e Initial load
duke
parents:
diff changeset
1602 T_BYTE));
a61af66fc99e Initial load
duke
parents:
diff changeset
1603 }
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1604 #endif // ARM
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1605 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1606
a61af66fc99e Initial load
duke
parents:
diff changeset
1607
a61af66fc99e Initial load
duke
parents:
diff changeset
1608 //------------------------field access--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1609
a61af66fc99e Initial load
duke
parents:
diff changeset
1610 // Comment copied form templateTable_i486.cpp
a61af66fc99e Initial load
duke
parents:
diff changeset
1611 // ----------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1612 // Volatile variables demand their effects be made known to all CPU's in
a61af66fc99e Initial load
duke
parents:
diff changeset
1613 // order. Store buffers on most chips allow reads & writes to reorder; the
a61af66fc99e Initial load
duke
parents:
diff changeset
1614 // JMM's ReadAfterWrite.java test fails in -Xint mode without some kind of
a61af66fc99e Initial load
duke
parents:
diff changeset
1615 // memory barrier (i.e., it's not sufficient that the interpreter does not
a61af66fc99e Initial load
duke
parents:
diff changeset
1616 // reorder volatile references, the hardware also must not reorder them).
a61af66fc99e Initial load
duke
parents:
diff changeset
1617 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1618 // According to the new Java Memory Model (JMM):
a61af66fc99e Initial load
duke
parents:
diff changeset
1619 // (1) All volatiles are serialized wrt to each other.
a61af66fc99e Initial load
duke
parents:
diff changeset
1620 // ALSO reads & writes act as aquire & release, so:
a61af66fc99e Initial load
duke
parents:
diff changeset
1621 // (2) A read cannot let unrelated NON-volatile memory refs that happen after
a61af66fc99e Initial load
duke
parents:
diff changeset
1622 // the read float up to before the read. It's OK for non-volatile memory refs
a61af66fc99e Initial load
duke
parents:
diff changeset
1623 // that happen before the volatile read to float down below it.
a61af66fc99e Initial load
duke
parents:
diff changeset
1624 // (3) Similar a volatile write cannot let unrelated NON-volatile memory refs
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 // that happen BEFORE the write float down to after the write. It's OK for
a61af66fc99e Initial load
duke
parents:
diff changeset
1626 // non-volatile memory refs that happen after the volatile write to float up
a61af66fc99e Initial load
duke
parents:
diff changeset
1627 // before it.
a61af66fc99e Initial load
duke
parents:
diff changeset
1628 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1629 // We only put in barriers around volatile refs (they are expensive), not
a61af66fc99e Initial load
duke
parents:
diff changeset
1630 // _between_ memory refs (that would require us to track the flavor of the
a61af66fc99e Initial load
duke
parents:
diff changeset
1631 // previous memory refs). Requirements (2) and (3) require some barriers
a61af66fc99e Initial load
duke
parents:
diff changeset
1632 // before volatile stores and after volatile loads. These nearly cover
a61af66fc99e Initial load
duke
parents:
diff changeset
1633 // requirement (1) but miss the volatile-store-volatile-load case. This final
a61af66fc99e Initial load
duke
parents:
diff changeset
1634 // case is placed after volatile-stores although it could just as well go
a61af66fc99e Initial load
duke
parents:
diff changeset
1635 // before volatile-loads.
a61af66fc99e Initial load
duke
parents:
diff changeset
1636
a61af66fc99e Initial load
duke
parents:
diff changeset
1637
a61af66fc99e Initial load
duke
parents:
diff changeset
1638 void LIRGenerator::do_StoreField(StoreField* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1639 bool needs_patching = x->needs_patching();
a61af66fc99e Initial load
duke
parents:
diff changeset
1640 bool is_volatile = x->field()->is_volatile();
a61af66fc99e Initial load
duke
parents:
diff changeset
1641 BasicType field_type = x->field_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1642 bool is_oop = (field_type == T_ARRAY || field_type == T_OBJECT);
a61af66fc99e Initial load
duke
parents:
diff changeset
1643
a61af66fc99e Initial load
duke
parents:
diff changeset
1644 CodeEmitInfo* info = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1645 if (needs_patching) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 assert(x->explicit_null_check() == NULL, "can't fold null check into patching field access");
a61af66fc99e Initial load
duke
parents:
diff changeset
1647 info = state_for(x, x->state_before());
a61af66fc99e Initial load
duke
parents:
diff changeset
1648 } else if (x->needs_null_check()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1649 NullCheck* nc = x->explicit_null_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
1650 if (nc == NULL) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
1651 info = state_for(x);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1652 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 info = state_for(nc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1654 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1655 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1656
a61af66fc99e Initial load
duke
parents:
diff changeset
1657
a61af66fc99e Initial load
duke
parents:
diff changeset
1658 LIRItem object(x->obj(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1659 LIRItem value(x->value(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1660
a61af66fc99e Initial load
duke
parents:
diff changeset
1661 object.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1662
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 if (is_volatile || needs_patching) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 // load item if field is volatile (fewer special cases for volatiles)
a61af66fc99e Initial load
duke
parents:
diff changeset
1665 // load item if field not initialized
a61af66fc99e Initial load
duke
parents:
diff changeset
1666 // load item if field not constant
a61af66fc99e Initial load
duke
parents:
diff changeset
1667 // because of code patching we cannot inline constants
a61af66fc99e Initial load
duke
parents:
diff changeset
1668 if (field_type == T_BYTE || field_type == T_BOOLEAN) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1669 value.load_byte_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1670 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 value.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1672 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1673 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1674 value.load_for_store(field_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1675 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1676
a61af66fc99e Initial load
duke
parents:
diff changeset
1677 set_no_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1678
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
1679 #ifndef PRODUCT
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1680 if (PrintNotLoaded && needs_patching) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1681 tty->print_cr(" ###class not loaded at store_%s bci %d",
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
1682 x->is_static() ? "static" : "field", x->printable_bci());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1683 }
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
1684 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1685
a61af66fc99e Initial load
duke
parents:
diff changeset
1686 if (x->needs_null_check() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1687 (needs_patching ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 MacroAssembler::needs_explicit_null_check(x->offset()))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 // emit an explicit null check because the offset is too large
a61af66fc99e Initial load
duke
parents:
diff changeset
1690 __ null_check(object.result(), new CodeEmitInfo(info));
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1692
a61af66fc99e Initial load
duke
parents:
diff changeset
1693 LIR_Address* address;
a61af66fc99e Initial load
duke
parents:
diff changeset
1694 if (needs_patching) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1695 // we need to patch the offset in the instruction so don't allow
a61af66fc99e Initial load
duke
parents:
diff changeset
1696 // generate_address to try to be smart about emitting the -1.
a61af66fc99e Initial load
duke
parents:
diff changeset
1697 // Otherwise the patching code won't know how to find the
a61af66fc99e Initial load
duke
parents:
diff changeset
1698 // instruction to patch.
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1699 address = new LIR_Address(object.result(), PATCHED_ADDR, field_type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1701 address = generate_address(object.result(), x->offset(), field_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1702 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1703
a61af66fc99e Initial load
duke
parents:
diff changeset
1704 if (is_volatile && os::is_MP()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1705 __ membar_release();
a61af66fc99e Initial load
duke
parents:
diff changeset
1706 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1707
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1708 if (is_oop) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1709 // Do the pre-write barrier, if any.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1710 pre_barrier(LIR_OprFact::address(address),
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1711 LIR_OprFact::illegalOpr /* pre_val */,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
1712 true /* do_load*/,
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1713 needs_patching,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1714 (info ? new CodeEmitInfo(info) : NULL));
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1715 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1716
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
1717 if (is_volatile && !needs_patching) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 volatile_field_store(value.result(), address, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1719 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1720 LIR_PatchCode patch_code = needs_patching ? lir_patch_normal : lir_patch_none;
a61af66fc99e Initial load
duke
parents:
diff changeset
1721 __ store(value.result(), address, info, patch_code);
a61af66fc99e Initial load
duke
parents:
diff changeset
1722 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1723
a61af66fc99e Initial load
duke
parents:
diff changeset
1724 if (is_oop) {
819
c6386080541b 6849574: VM crash using NonBlockingHashMap (high_scale_lib)
never
parents: 780
diff changeset
1725 // Store to object so mark the card of the header
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1726 post_barrier(object.result(), value.result());
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1728
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 if (is_volatile && os::is_MP()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1730 __ membar();
a61af66fc99e Initial load
duke
parents:
diff changeset
1731 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1732 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1733
a61af66fc99e Initial load
duke
parents:
diff changeset
1734
a61af66fc99e Initial load
duke
parents:
diff changeset
1735 void LIRGenerator::do_LoadField(LoadField* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1736 bool needs_patching = x->needs_patching();
a61af66fc99e Initial load
duke
parents:
diff changeset
1737 bool is_volatile = x->field()->is_volatile();
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 BasicType field_type = x->field_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1739
a61af66fc99e Initial load
duke
parents:
diff changeset
1740 CodeEmitInfo* info = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1741 if (needs_patching) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1742 assert(x->explicit_null_check() == NULL, "can't fold null check into patching field access");
a61af66fc99e Initial load
duke
parents:
diff changeset
1743 info = state_for(x, x->state_before());
a61af66fc99e Initial load
duke
parents:
diff changeset
1744 } else if (x->needs_null_check()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1745 NullCheck* nc = x->explicit_null_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
1746 if (nc == NULL) {
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
1747 info = state_for(x);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1748 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1749 info = state_for(nc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1750 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1752
a61af66fc99e Initial load
duke
parents:
diff changeset
1753 LIRItem object(x->obj(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1754
a61af66fc99e Initial load
duke
parents:
diff changeset
1755 object.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1756
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
1757 #ifndef PRODUCT
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 if (PrintNotLoaded && needs_patching) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1759 tty->print_cr(" ###class not loaded at load_%s bci %d",
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
1760 x->is_static() ? "static" : "field", x->printable_bci());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 }
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
1762 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1763
a61af66fc99e Initial load
duke
parents:
diff changeset
1764 if (x->needs_null_check() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1765 (needs_patching ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1766 MacroAssembler::needs_explicit_null_check(x->offset()))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1767 // emit an explicit null check because the offset is too large
a61af66fc99e Initial load
duke
parents:
diff changeset
1768 __ null_check(object.result(), new CodeEmitInfo(info));
a61af66fc99e Initial load
duke
parents:
diff changeset
1769 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1770
a61af66fc99e Initial load
duke
parents:
diff changeset
1771 LIR_Opr reg = rlock_result(x, field_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1772 LIR_Address* address;
a61af66fc99e Initial load
duke
parents:
diff changeset
1773 if (needs_patching) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1774 // we need to patch the offset in the instruction so don't allow
a61af66fc99e Initial load
duke
parents:
diff changeset
1775 // generate_address to try to be smart about emitting the -1.
a61af66fc99e Initial load
duke
parents:
diff changeset
1776 // Otherwise the patching code won't know how to find the
a61af66fc99e Initial load
duke
parents:
diff changeset
1777 // instruction to patch.
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1778 address = new LIR_Address(object.result(), PATCHED_ADDR, field_type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1779 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1780 address = generate_address(object.result(), x->offset(), field_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1781 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1782
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
1783 if (is_volatile && !needs_patching) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1784 volatile_field_load(address, reg, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1785 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1786 LIR_PatchCode patch_code = needs_patching ? lir_patch_normal : lir_patch_none;
a61af66fc99e Initial load
duke
parents:
diff changeset
1787 __ load(address, reg, info, patch_code);
a61af66fc99e Initial load
duke
parents:
diff changeset
1788 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1789
a61af66fc99e Initial load
duke
parents:
diff changeset
1790 if (is_volatile && os::is_MP()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 __ membar_acquire();
a61af66fc99e Initial load
duke
parents:
diff changeset
1792 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1793 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1794
a61af66fc99e Initial load
duke
parents:
diff changeset
1795
a61af66fc99e Initial load
duke
parents:
diff changeset
1796 //------------------------java.nio.Buffer.checkIndex------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1797
a61af66fc99e Initial load
duke
parents:
diff changeset
1798 // int java.nio.Buffer.checkIndex(int)
a61af66fc99e Initial load
duke
parents:
diff changeset
1799 void LIRGenerator::do_NIOCheckIndex(Intrinsic* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 // NOTE: by the time we are in checkIndex() we are guaranteed that
a61af66fc99e Initial load
duke
parents:
diff changeset
1801 // the buffer is non-null (because checkIndex is package-private and
a61af66fc99e Initial load
duke
parents:
diff changeset
1802 // only called from within other methods in the buffer).
a61af66fc99e Initial load
duke
parents:
diff changeset
1803 assert(x->number_of_arguments() == 2, "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
1804 LIRItem buf (x->argument_at(0), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1805 LIRItem index(x->argument_at(1), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1806 buf.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1807 index.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1808
a61af66fc99e Initial load
duke
parents:
diff changeset
1809 LIR_Opr result = rlock_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 if (GenerateRangeChecks) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1811 CodeEmitInfo* info = state_for(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1812 CodeStub* stub = new RangeCheckStub(info, index.result(), true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1813 if (index.result()->is_constant()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1814 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
1815 __ branch(lir_cond_belowEqual, T_INT, stub);
a61af66fc99e Initial load
duke
parents:
diff changeset
1816 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1817 cmp_reg_mem(lir_cond_aboveEqual, index.result(), buf.result(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1818 java_nio_Buffer::limit_offset(), T_INT, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1819 __ branch(lir_cond_aboveEqual, T_INT, stub);
a61af66fc99e Initial load
duke
parents:
diff changeset
1820 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1821 __ move(index.result(), result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1822 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1823 // Just load the index into the result register
a61af66fc99e Initial load
duke
parents:
diff changeset
1824 __ move(index.result(), result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1825 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1826 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1827
a61af66fc99e Initial load
duke
parents:
diff changeset
1828
a61af66fc99e Initial load
duke
parents:
diff changeset
1829 //------------------------array access--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1830
a61af66fc99e Initial load
duke
parents:
diff changeset
1831
a61af66fc99e Initial load
duke
parents:
diff changeset
1832 void LIRGenerator::do_ArrayLength(ArrayLength* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1833 LIRItem array(x->array(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1834 array.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1835 LIR_Opr reg = rlock_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1836
a61af66fc99e Initial load
duke
parents:
diff changeset
1837 CodeEmitInfo* info = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1838 if (x->needs_null_check()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1839 NullCheck* nc = x->explicit_null_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
1840 if (nc == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1841 info = state_for(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1842 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1843 info = state_for(nc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1844 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1845 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1846 __ 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
1847 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1848
a61af66fc99e Initial load
duke
parents:
diff changeset
1849
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 void LIRGenerator::do_LoadIndexed(LoadIndexed* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1851 bool use_length = x->length() != NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1852 LIRItem array(x->array(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1853 LIRItem index(x->index(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1854 LIRItem length(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1855 bool needs_range_check = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1856
a61af66fc99e Initial load
duke
parents:
diff changeset
1857 if (use_length) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1858 needs_range_check = x->compute_needs_range_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
1859 if (needs_range_check) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1860 length.set_instruction(x->length());
a61af66fc99e Initial load
duke
parents:
diff changeset
1861 length.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1862 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1863 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1864
a61af66fc99e Initial load
duke
parents:
diff changeset
1865 array.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1866 if (index.is_constant() && can_inline_as_constant(x->index())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1867 // let it be a constant
a61af66fc99e Initial load
duke
parents:
diff changeset
1868 index.dont_load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1869 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1870 index.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1871 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1872
a61af66fc99e Initial load
duke
parents:
diff changeset
1873 CodeEmitInfo* range_check_info = state_for(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1874 CodeEmitInfo* null_check_info = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1875 if (x->needs_null_check()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1876 NullCheck* nc = x->explicit_null_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
1877 if (nc != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1878 null_check_info = state_for(nc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1879 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1880 null_check_info = range_check_info;
a61af66fc99e Initial load
duke
parents:
diff changeset
1881 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1882 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1883
a61af66fc99e Initial load
duke
parents:
diff changeset
1884 // emit array address setup early so it schedules better
a61af66fc99e Initial load
duke
parents:
diff changeset
1885 LIR_Address* array_addr = emit_array_address(array.result(), index.result(), x->elt_type(), false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1886
a61af66fc99e Initial load
duke
parents:
diff changeset
1887 if (GenerateRangeChecks && needs_range_check) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1888 if (use_length) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1889 // TODO: use a (modified) version of array_range_check that does not require a
a61af66fc99e Initial load
duke
parents:
diff changeset
1890 // constant length to be loaded to a register
a61af66fc99e Initial load
duke
parents:
diff changeset
1891 __ cmp(lir_cond_belowEqual, length.result(), index.result());
a61af66fc99e Initial load
duke
parents:
diff changeset
1892 __ branch(lir_cond_belowEqual, T_INT, new RangeCheckStub(range_check_info, index.result()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1893 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1894 array_range_check(array.result(), index.result(), null_check_info, range_check_info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1895 // The range check performs the null check, so clear it out for the load
a61af66fc99e Initial load
duke
parents:
diff changeset
1896 null_check_info = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1897 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1898 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1899
a61af66fc99e Initial load
duke
parents:
diff changeset
1900 __ move(array_addr, rlock_result(x, x->elt_type()), null_check_info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1901 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1902
a61af66fc99e Initial load
duke
parents:
diff changeset
1903
a61af66fc99e Initial load
duke
parents:
diff changeset
1904 void LIRGenerator::do_NullCheck(NullCheck* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1905 if (x->can_trap()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1906 LIRItem value(x->obj(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1907 value.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1908 CodeEmitInfo* info = state_for(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 __ null_check(value.result(), info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 }
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 void LIRGenerator::do_Throw(Throw* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1915 LIRItem exception(x->exception(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 exception.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1917 set_no_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1918 LIR_Opr exception_opr = exception.result();
a61af66fc99e Initial load
duke
parents:
diff changeset
1919 CodeEmitInfo* info = state_for(x, x->state());
a61af66fc99e Initial load
duke
parents:
diff changeset
1920
a61af66fc99e Initial load
duke
parents:
diff changeset
1921 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1922 if (PrintC1Statistics) {
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
1923 increment_counter(Runtime1::throw_count_address(), T_INT);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1924 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1925 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1926
a61af66fc99e Initial load
duke
parents:
diff changeset
1927 // check if the instruction has an xhandler in any of the nested scopes
a61af66fc99e Initial load
duke
parents:
diff changeset
1928 bool unwind = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1929 if (info->exception_handlers()->length() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1930 // this throw is not inside an xhandler
a61af66fc99e Initial load
duke
parents:
diff changeset
1931 unwind = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1932 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1933 // get some idea of the throw type
a61af66fc99e Initial load
duke
parents:
diff changeset
1934 bool type_is_exact = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1935 ciType* throw_type = x->exception()->exact_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1936 if (throw_type == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1937 type_is_exact = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1938 throw_type = x->exception()->declared_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1939 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1940 if (throw_type != NULL && throw_type->is_instance_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1941 ciInstanceKlass* throw_klass = (ciInstanceKlass*)throw_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
1942 unwind = !x->exception_handlers()->could_catch(throw_klass, type_is_exact);
a61af66fc99e Initial load
duke
parents:
diff changeset
1943 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1944 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1945
a61af66fc99e Initial load
duke
parents:
diff changeset
1946 // do null check before moving exception oop into fixed register
a61af66fc99e Initial load
duke
parents:
diff changeset
1947 // to avoid a fixed interval with an oop during the null check.
a61af66fc99e Initial load
duke
parents:
diff changeset
1948 // Use a copy of the CodeEmitInfo because debug information is
a61af66fc99e Initial load
duke
parents:
diff changeset
1949 // different for null_check and throw.
a61af66fc99e Initial load
duke
parents:
diff changeset
1950 if (GenerateCompilerNullChecks &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1951 (x->exception()->as_NewInstance() == NULL && x->exception()->as_ExceptionObject() == NULL)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1952 // 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
1953 __ null_check(exception_opr, new CodeEmitInfo(info, x->state()->copy(ValueStack::ExceptionState, x->state()->bci())));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1954 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1955
1378
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1304
diff changeset
1956 if (compilation()->env()->jvmti_can_post_on_exceptions()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1957 // we need to go through the exception lookup path to get JVMTI
a61af66fc99e Initial load
duke
parents:
diff changeset
1958 // notification done
a61af66fc99e Initial load
duke
parents:
diff changeset
1959 unwind = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1960 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1961
a61af66fc99e Initial load
duke
parents:
diff changeset
1962 // move exception oop into fixed register
a61af66fc99e Initial load
duke
parents:
diff changeset
1963 __ move(exception_opr, exceptionOopOpr());
a61af66fc99e Initial load
duke
parents:
diff changeset
1964
a61af66fc99e Initial load
duke
parents:
diff changeset
1965 if (unwind) {
1378
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1304
diff changeset
1966 __ unwind_exception(exceptionOopOpr());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1967 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1968 __ throw_exception(exceptionPcOpr(), exceptionOopOpr(), info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1969 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1970 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1971
a61af66fc99e Initial load
duke
parents:
diff changeset
1972
a61af66fc99e Initial load
duke
parents:
diff changeset
1973 void LIRGenerator::do_RoundFP(RoundFP* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1974 LIRItem input(x->input(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1975 input.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1976 LIR_Opr input_opr = input.result();
a61af66fc99e Initial load
duke
parents:
diff changeset
1977 assert(input_opr->is_register(), "why round if value is not in a register?");
a61af66fc99e Initial load
duke
parents:
diff changeset
1978 assert(input_opr->is_single_fpu() || input_opr->is_double_fpu(), "input should be floating-point value");
a61af66fc99e Initial load
duke
parents:
diff changeset
1979 if (input_opr->is_single_fpu()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1980 set_result(x, round_item(input_opr)); // This code path not currently taken
a61af66fc99e Initial load
duke
parents:
diff changeset
1981 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1982 LIR_Opr result = new_register(T_DOUBLE);
a61af66fc99e Initial load
duke
parents:
diff changeset
1983 set_vreg_flag(result, must_start_in_memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
1984 __ roundfp(input_opr, LIR_OprFact::illegalOpr, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1985 set_result(x, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1986 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1987 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1988
a61af66fc99e Initial load
duke
parents:
diff changeset
1989 void LIRGenerator::do_UnsafeGetRaw(UnsafeGetRaw* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1990 LIRItem base(x->base(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1991 LIRItem idx(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1992
a61af66fc99e Initial load
duke
parents:
diff changeset
1993 base.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1994 if (x->has_index()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1995 idx.set_instruction(x->index());
a61af66fc99e Initial load
duke
parents:
diff changeset
1996 idx.load_nonconstant();
a61af66fc99e Initial load
duke
parents:
diff changeset
1997 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1998
a61af66fc99e Initial load
duke
parents:
diff changeset
1999 LIR_Opr reg = rlock_result(x, x->basic_type());
a61af66fc99e Initial load
duke
parents:
diff changeset
2000
a61af66fc99e Initial load
duke
parents:
diff changeset
2001 int log2_scale = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2002 if (x->has_index()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2003 assert(x->index()->type()->tag() == intTag, "should not find non-int index");
a61af66fc99e Initial load
duke
parents:
diff changeset
2004 log2_scale = x->log2_scale();
a61af66fc99e Initial load
duke
parents:
diff changeset
2005 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2006
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 assert(!x->has_index() || idx.value() == x->index(), "should match");
a61af66fc99e Initial load
duke
parents:
diff changeset
2008
a61af66fc99e Initial load
duke
parents:
diff changeset
2009 LIR_Opr base_op = base.result();
a61af66fc99e Initial load
duke
parents:
diff changeset
2010 #ifndef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
2011 if (x->base()->type()->tag() == longTag) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2012 base_op = new_register(T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
2013 __ convert(Bytecodes::_l2i, base.result(), base_op);
a61af66fc99e Initial load
duke
parents:
diff changeset
2014 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2015 assert(x->base()->type()->tag() == intTag, "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
2016 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2017 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2018
a61af66fc99e Initial load
duke
parents:
diff changeset
2019 BasicType dst_type = x->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2020 LIR_Opr index_op = idx.result();
a61af66fc99e Initial load
duke
parents:
diff changeset
2021
a61af66fc99e Initial load
duke
parents:
diff changeset
2022 LIR_Address* addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
2023 if (index_op->is_constant()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2024 assert(log2_scale == 0, "must not have a scale");
a61af66fc99e Initial load
duke
parents:
diff changeset
2025 addr = new LIR_Address(base_op, index_op->as_jint(), dst_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2026 } else {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
2027 #ifdef X86
1060
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2028 #ifdef _LP64
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2029 if (!index_op->is_illegal() && index_op->type() == T_INT) {
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2030 LIR_Opr tmp = new_pointer_register();
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2031 __ convert(Bytecodes::_i2l, index_op, tmp);
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2032 index_op = tmp;
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2033 }
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2034 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2035 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
2036 #elif defined(ARM)
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
2037 addr = generate_address(base_op, index_op, log2_scale, 0, dst_type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2038 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
2039 if (index_op->is_illegal() || log2_scale == 0) {
1060
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2040 #ifdef _LP64
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2041 if (!index_op->is_illegal() && index_op->type() == T_INT) {
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2042 LIR_Opr tmp = new_pointer_register();
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2043 __ convert(Bytecodes::_i2l, index_op, tmp);
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2044 index_op = tmp;
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2045 }
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2046 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2047 addr = new LIR_Address(base_op, index_op, dst_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2048 } else {
1060
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2049 LIR_Opr tmp = new_pointer_register();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2050 __ shift_left(index_op, log2_scale, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2051 addr = new LIR_Address(base_op, tmp, dst_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2052 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2053 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2054 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2055
a61af66fc99e Initial load
duke
parents:
diff changeset
2056 if (x->may_be_unaligned() && (dst_type == T_LONG || dst_type == T_DOUBLE)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2057 __ unaligned_move(addr, reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2058 } else {
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2059 if (dst_type == T_OBJECT && x->is_wide()) {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2060 __ move_wide(addr, reg);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2061 } else {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2062 __ move(addr, reg);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2063 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2064 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2065 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2066
a61af66fc99e Initial load
duke
parents:
diff changeset
2067
a61af66fc99e Initial load
duke
parents:
diff changeset
2068 void LIRGenerator::do_UnsafePutRaw(UnsafePutRaw* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2069 int log2_scale = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2070 BasicType type = x->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2071
a61af66fc99e Initial load
duke
parents:
diff changeset
2072 if (x->has_index()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2073 assert(x->index()->type()->tag() == intTag, "should not find non-int index");
a61af66fc99e Initial load
duke
parents:
diff changeset
2074 log2_scale = x->log2_scale();
a61af66fc99e Initial load
duke
parents:
diff changeset
2075 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2076
a61af66fc99e Initial load
duke
parents:
diff changeset
2077 LIRItem base(x->base(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2078 LIRItem value(x->value(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2079 LIRItem idx(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2080
a61af66fc99e Initial load
duke
parents:
diff changeset
2081 base.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2082 if (x->has_index()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2083 idx.set_instruction(x->index());
a61af66fc99e Initial load
duke
parents:
diff changeset
2084 idx.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2085 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2086
a61af66fc99e Initial load
duke
parents:
diff changeset
2087 if (type == T_BYTE || type == T_BOOLEAN) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2088 value.load_byte_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2089 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2090 value.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2091 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2092
a61af66fc99e Initial load
duke
parents:
diff changeset
2093 set_no_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2094
a61af66fc99e Initial load
duke
parents:
diff changeset
2095 LIR_Opr base_op = base.result();
a61af66fc99e Initial load
duke
parents:
diff changeset
2096 #ifndef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
2097 if (x->base()->type()->tag() == longTag) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2098 base_op = new_register(T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
2099 __ convert(Bytecodes::_l2i, base.result(), base_op);
a61af66fc99e Initial load
duke
parents:
diff changeset
2100 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2101 assert(x->base()->type()->tag() == intTag, "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
2102 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2103 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2104
a61af66fc99e Initial load
duke
parents:
diff changeset
2105 LIR_Opr index_op = idx.result();
a61af66fc99e Initial load
duke
parents:
diff changeset
2106 if (log2_scale != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2107 // 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
2108 index_op = new_pointer_register();
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2109 #ifdef _LP64
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2110 if(idx.result()->type() == T_INT) {
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2111 __ convert(Bytecodes::_i2l, idx.result(), index_op);
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2112 } else {
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2113 #endif
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
2114 // TODO: ARM also allows embedded shift in the address
1060
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2115 __ move(idx.result(), index_op);
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2116 #ifdef _LP64
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2117 }
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2118 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2119 __ shift_left(index_op, log2_scale, index_op);
a61af66fc99e Initial load
duke
parents:
diff changeset
2120 }
1060
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2121 #ifdef _LP64
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2122 else if(!index_op->is_illegal() && index_op->type() == T_INT) {
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2123 LIR_Opr tmp = new_pointer_register();
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2124 __ convert(Bytecodes::_i2l, index_op, tmp);
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2125 index_op = tmp;
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2126 }
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
2127 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2128
a61af66fc99e Initial load
duke
parents:
diff changeset
2129 LIR_Address* addr = new LIR_Address(base_op, index_op, x->basic_type());
a61af66fc99e Initial load
duke
parents:
diff changeset
2130 __ move(value.result(), addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2131 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2132
a61af66fc99e Initial load
duke
parents:
diff changeset
2133
a61af66fc99e Initial load
duke
parents:
diff changeset
2134 void LIRGenerator::do_UnsafeGetObject(UnsafeGetObject* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2135 BasicType type = x->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2136 LIRItem src(x->object(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2137 LIRItem off(x->offset(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2138
a61af66fc99e Initial load
duke
parents:
diff changeset
2139 off.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2140 src.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2141
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2142 LIR_Opr reg = rlock_result(x, x->basic_type());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2143
2123
df307487d610 7010665: Misplaced membar in C1 implementation of Unsafe.get/putXXX
dholmes
parents: 2007
diff changeset
2144 get_Object_unsafe(reg, 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
2145
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2146 #ifndef SERIALGC
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2147 // 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
2148 // 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
2149 // 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
2150 // 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
2151 //
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2152 // 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
2153 //
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2154 // 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
2155 // if (src != NULL) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2156 // if (klass(src)->reference_type() != REF_NONE) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2157 // pre_barrier(..., reg, ...);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2158 // }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2159 // }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2160 // }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2161 //
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2162 // The first non-constant check of either the offset or
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2163 // the src operand will be done here; the remainder
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2164 // will take place in the generated code stub.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2165
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2166 if (UseG1GC && type == T_OBJECT) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2167 bool gen_code_stub = true; // Assume we need to generate the slow code stub.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2168 bool gen_offset_check = true; // Assume the code stub has to generate the offset guard.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2169 bool gen_source_check = true; // Assume the code stub has to check the src object for null.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2170
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2171 if (off.is_constant()) {
3254
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2172 jlong off_con = (off.type()->is_int() ?
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2173 (jlong) off.get_jint_constant() :
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2174 off.get_jlong_constant());
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2175
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2176
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2177 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
2178 // 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
2179 // 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
2180 // skip generation of the code stub.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2181 gen_code_stub = false;
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2182 } else {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2183 // 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
2184 // 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
2185 gen_offset_check = false;
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2186 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2187 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2188
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2189 // We don't need to generate stub if the source object is an array
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2190 if (gen_code_stub && src.type()->is_array()) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2191 gen_code_stub = false;
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2192 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2193
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2194 if (gen_code_stub) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2195 // 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
2196 if (src.is_constant()) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2197 ciObject* src_con = src.get_jobject_constant();
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 if (src_con->is_null_object()) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2200 // 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
2201 // generating the code stub.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2202 gen_code_stub = false;
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2203 } else {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2204 // 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
2205 // 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
2206 // null object check.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2207 gen_source_check = false;
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2208 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2209 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2210 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2211
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2212 if (gen_code_stub) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2213 // Temoraries.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2214 LIR_Opr src_klass = new_register(T_OBJECT);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2215
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2216 // Get the thread pointer for the pre-barrier
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2217 LIR_Opr thread = getThreadPointer();
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2218
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2219 CodeStub* stub;
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2220
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2221 // 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
2222 // the offset check.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2223 if (gen_offset_check) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2224 // if (offset == referent_offset) -> slow code stub
3254
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2225 // 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
2226 // referent_offset constant; otherwise we need to move
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2227 // referent_offset into a temporary register and generate
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2228 // a reg-reg compare.
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2229
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2230 LIR_Opr referent_off;
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2231
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2232 if (off.type()->is_int()) {
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2233 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
2234 } else {
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2235 assert(off.type()->is_long(), "what else?");
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2236 referent_off = new_register(T_LONG);
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2237 __ 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
2238 }
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2239
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2240 __ cmp(lir_cond_equal, off.result(), referent_off);
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2241
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2242 // Optionally generate "src == null" check.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2243 stub = new G1UnsafeGetObjSATBBarrierStub(reg, src.result(),
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2244 src_klass, thread,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2245 gen_source_check);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2246
3254
59766fd005ff 7035117: G1: nsk/stress/jni/jnistress002 fails with assertion failure
johnc
parents: 3249
diff changeset
2247 __ branch(lir_cond_equal, as_BasicType(off.type()), stub);
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2248 } else {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2249 if (gen_source_check) {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2250 // offset is a const and equals referent offset
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2251 // if (source != null) -> slow code stub
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2252 __ cmp(lir_cond_notEqual, src.result(), LIR_OprFact::oopConst(NULL));
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2253
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2254 // Since we are generating the "if src == null" guard here,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2255 // there is no need to generate the "src == null" check again.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2256 stub = new G1UnsafeGetObjSATBBarrierStub(reg, src.result(),
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2257 src_klass, thread,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2258 false);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2259
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2260 __ branch(lir_cond_notEqual, T_OBJECT, stub);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2261 } else {
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2262 // We have statically determined that offset == referent_offset
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2263 // && src != null so we unconditionally branch to code stub
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2264 // to perform the guards and record reg in the SATB log buffer.
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2265
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2266 stub = new G1UnsafeGetObjSATBBarrierStub(reg, src.result(),
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2267 src_klass, thread,
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2268 false);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2269
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2270 __ branch(lir_cond_always, T_ILLEGAL, stub);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2271 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2272 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2273
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2274 // Continuation point
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2275 __ branch_destination(stub->continuation());
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2276 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2277 }
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2278 #endif // SERIALGC
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2279
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2280 if (x->is_volatile() && os::is_MP()) __ membar_acquire();
a61af66fc99e Initial load
duke
parents:
diff changeset
2281 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2282
a61af66fc99e Initial load
duke
parents:
diff changeset
2283
a61af66fc99e Initial load
duke
parents:
diff changeset
2284 void LIRGenerator::do_UnsafePutObject(UnsafePutObject* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2285 BasicType type = x->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2286 LIRItem src(x->object(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2287 LIRItem off(x->offset(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2288 LIRItem data(x->value(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2289
a61af66fc99e Initial load
duke
parents:
diff changeset
2290 src.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2291 if (type == T_BOOLEAN || type == T_BYTE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2292 data.load_byte_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2293 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2294 data.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2295 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2296 off.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2297
a61af66fc99e Initial load
duke
parents:
diff changeset
2298 set_no_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2299
a61af66fc99e Initial load
duke
parents:
diff changeset
2300 if (x->is_volatile() && os::is_MP()) __ membar_release();
a61af66fc99e Initial load
duke
parents:
diff changeset
2301 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
2302 if (x->is_volatile() && os::is_MP()) __ membar();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2303 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2304
a61af66fc99e Initial load
duke
parents:
diff changeset
2305
a61af66fc99e Initial load
duke
parents:
diff changeset
2306 void LIRGenerator::do_UnsafePrefetch(UnsafePrefetch* x, bool is_store) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2307 LIRItem src(x->object(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2308 LIRItem off(x->offset(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2309
a61af66fc99e Initial load
duke
parents:
diff changeset
2310 src.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2311 if (off.is_constant() && can_inline_as_constant(x->offset())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2312 // let it be a constant
a61af66fc99e Initial load
duke
parents:
diff changeset
2313 off.dont_load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2314 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2315 off.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2316 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2317
a61af66fc99e Initial load
duke
parents:
diff changeset
2318 set_no_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2319
a61af66fc99e Initial load
duke
parents:
diff changeset
2320 LIR_Address* addr = generate_address(src.result(), off.result(), 0, 0, T_BYTE);
a61af66fc99e Initial load
duke
parents:
diff changeset
2321 __ prefetch(addr, is_store);
a61af66fc99e Initial load
duke
parents:
diff changeset
2322 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2323
a61af66fc99e Initial load
duke
parents:
diff changeset
2324
a61af66fc99e Initial load
duke
parents:
diff changeset
2325 void LIRGenerator::do_UnsafePrefetchRead(UnsafePrefetchRead* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2326 do_UnsafePrefetch(x, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2327 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2328
a61af66fc99e Initial load
duke
parents:
diff changeset
2329
a61af66fc99e Initial load
duke
parents:
diff changeset
2330 void LIRGenerator::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2331 do_UnsafePrefetch(x, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
2332 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2333
a61af66fc99e Initial load
duke
parents:
diff changeset
2334
a61af66fc99e Initial load
duke
parents:
diff changeset
2335 void LIRGenerator::do_SwitchRanges(SwitchRangeArray* x, LIR_Opr value, BlockBegin* default_sux) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2336 int lng = x->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
2337
a61af66fc99e Initial load
duke
parents:
diff changeset
2338 for (int i = 0; i < lng; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2339 SwitchRange* one_range = x->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2340 int low_key = one_range->low_key();
a61af66fc99e Initial load
duke
parents:
diff changeset
2341 int high_key = one_range->high_key();
a61af66fc99e Initial load
duke
parents:
diff changeset
2342 BlockBegin* dest = one_range->sux();
a61af66fc99e Initial load
duke
parents:
diff changeset
2343 if (low_key == high_key) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2344 __ cmp(lir_cond_equal, value, low_key);
a61af66fc99e Initial load
duke
parents:
diff changeset
2345 __ branch(lir_cond_equal, T_INT, dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
2346 } else if (high_key - low_key == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2347 __ cmp(lir_cond_equal, value, low_key);
a61af66fc99e Initial load
duke
parents:
diff changeset
2348 __ branch(lir_cond_equal, T_INT, dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
2349 __ cmp(lir_cond_equal, value, high_key);
a61af66fc99e Initial load
duke
parents:
diff changeset
2350 __ branch(lir_cond_equal, T_INT, dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
2351 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2352 LabelObj* L = new LabelObj();
a61af66fc99e Initial load
duke
parents:
diff changeset
2353 __ cmp(lir_cond_less, value, low_key);
a61af66fc99e Initial load
duke
parents:
diff changeset
2354 __ branch(lir_cond_less, L->label());
a61af66fc99e Initial load
duke
parents:
diff changeset
2355 __ cmp(lir_cond_lessEqual, value, high_key);
a61af66fc99e Initial load
duke
parents:
diff changeset
2356 __ branch(lir_cond_lessEqual, T_INT, dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
2357 __ branch_destination(L->label());
a61af66fc99e Initial load
duke
parents:
diff changeset
2358 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2359 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2360 __ jump(default_sux);
a61af66fc99e Initial load
duke
parents:
diff changeset
2361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2362
a61af66fc99e Initial load
duke
parents:
diff changeset
2363
a61af66fc99e Initial load
duke
parents:
diff changeset
2364 SwitchRangeArray* LIRGenerator::create_lookup_ranges(TableSwitch* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2365 SwitchRangeList* res = new SwitchRangeList();
a61af66fc99e Initial load
duke
parents:
diff changeset
2366 int len = x->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
2367 if (len > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2368 BlockBegin* sux = x->sux_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2369 int key = x->lo_key();
a61af66fc99e Initial load
duke
parents:
diff changeset
2370 BlockBegin* default_sux = x->default_sux();
a61af66fc99e Initial load
duke
parents:
diff changeset
2371 SwitchRange* range = new SwitchRange(key, sux);
a61af66fc99e Initial load
duke
parents:
diff changeset
2372 for (int i = 0; i < len; i++, key++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2373 BlockBegin* new_sux = x->sux_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2374 if (sux == new_sux) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2375 // still in same range
a61af66fc99e Initial load
duke
parents:
diff changeset
2376 range->set_high_key(key);
a61af66fc99e Initial load
duke
parents:
diff changeset
2377 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2378 // skip tests which explicitly dispatch to the default
a61af66fc99e Initial load
duke
parents:
diff changeset
2379 if (sux != default_sux) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2380 res->append(range);
a61af66fc99e Initial load
duke
parents:
diff changeset
2381 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2382 range = new SwitchRange(key, new_sux);
a61af66fc99e Initial load
duke
parents:
diff changeset
2383 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2384 sux = new_sux;
a61af66fc99e Initial load
duke
parents:
diff changeset
2385 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2386 if (res->length() == 0 || res->last() != range) res->append(range);
a61af66fc99e Initial load
duke
parents:
diff changeset
2387 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2388 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
2389 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2390
a61af66fc99e Initial load
duke
parents:
diff changeset
2391
a61af66fc99e Initial load
duke
parents:
diff changeset
2392 // we expect the keys to be sorted by increasing value
a61af66fc99e Initial load
duke
parents:
diff changeset
2393 SwitchRangeArray* LIRGenerator::create_lookup_ranges(LookupSwitch* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2394 SwitchRangeList* res = new SwitchRangeList();
a61af66fc99e Initial load
duke
parents:
diff changeset
2395 int len = x->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
2396 if (len > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2397 BlockBegin* default_sux = x->default_sux();
a61af66fc99e Initial load
duke
parents:
diff changeset
2398 int key = x->key_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2399 BlockBegin* sux = x->sux_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2400 SwitchRange* range = new SwitchRange(key, sux);
a61af66fc99e Initial load
duke
parents:
diff changeset
2401 for (int i = 1; i < len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2402 int new_key = x->key_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2403 BlockBegin* new_sux = x->sux_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2404 if (key+1 == new_key && sux == new_sux) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2405 // still in same range
a61af66fc99e Initial load
duke
parents:
diff changeset
2406 range->set_high_key(new_key);
a61af66fc99e Initial load
duke
parents:
diff changeset
2407 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2408 // skip tests which explicitly dispatch to the default
a61af66fc99e Initial load
duke
parents:
diff changeset
2409 if (range->sux() != default_sux) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2410 res->append(range);
a61af66fc99e Initial load
duke
parents:
diff changeset
2411 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2412 range = new SwitchRange(new_key, new_sux);
a61af66fc99e Initial load
duke
parents:
diff changeset
2413 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2414 key = new_key;
a61af66fc99e Initial load
duke
parents:
diff changeset
2415 sux = new_sux;
a61af66fc99e Initial load
duke
parents:
diff changeset
2416 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2417 if (res->length() == 0 || res->last() != range) res->append(range);
a61af66fc99e Initial load
duke
parents:
diff changeset
2418 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2419 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
2420 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2421
a61af66fc99e Initial load
duke
parents:
diff changeset
2422
a61af66fc99e Initial load
duke
parents:
diff changeset
2423 void LIRGenerator::do_TableSwitch(TableSwitch* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2424 LIRItem tag(x->tag(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2425 tag.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2426 set_no_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2427
a61af66fc99e Initial load
duke
parents:
diff changeset
2428 if (x->is_safepoint()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2429 __ safepoint(safepoint_poll_register(), state_for(x, x->state_before()));
a61af66fc99e Initial load
duke
parents:
diff changeset
2430 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2431
a61af66fc99e Initial load
duke
parents:
diff changeset
2432 // move values into phi locations
a61af66fc99e Initial load
duke
parents:
diff changeset
2433 move_to_phi(x->state());
a61af66fc99e Initial load
duke
parents:
diff changeset
2434
a61af66fc99e Initial load
duke
parents:
diff changeset
2435 int lo_key = x->lo_key();
a61af66fc99e Initial load
duke
parents:
diff changeset
2436 int hi_key = x->hi_key();
a61af66fc99e Initial load
duke
parents:
diff changeset
2437 int len = x->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
2438 LIR_Opr value = tag.result();
a61af66fc99e Initial load
duke
parents:
diff changeset
2439 if (UseTableRanges) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2440 do_SwitchRanges(create_lookup_ranges(x), value, x->default_sux());
a61af66fc99e Initial load
duke
parents:
diff changeset
2441 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2442 for (int i = 0; i < len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2443 __ cmp(lir_cond_equal, value, i + lo_key);
a61af66fc99e Initial load
duke
parents:
diff changeset
2444 __ branch(lir_cond_equal, T_INT, x->sux_at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
2445 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2446 __ jump(x->default_sux());
a61af66fc99e Initial load
duke
parents:
diff changeset
2447 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2448 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2449
a61af66fc99e Initial load
duke
parents:
diff changeset
2450
a61af66fc99e Initial load
duke
parents:
diff changeset
2451 void LIRGenerator::do_LookupSwitch(LookupSwitch* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2452 LIRItem tag(x->tag(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2453 tag.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2454 set_no_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2455
a61af66fc99e Initial load
duke
parents:
diff changeset
2456 if (x->is_safepoint()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2457 __ safepoint(safepoint_poll_register(), state_for(x, x->state_before()));
a61af66fc99e Initial load
duke
parents:
diff changeset
2458 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2459
a61af66fc99e Initial load
duke
parents:
diff changeset
2460 // move values into phi locations
a61af66fc99e Initial load
duke
parents:
diff changeset
2461 move_to_phi(x->state());
a61af66fc99e Initial load
duke
parents:
diff changeset
2462
a61af66fc99e Initial load
duke
parents:
diff changeset
2463 LIR_Opr value = tag.result();
a61af66fc99e Initial load
duke
parents:
diff changeset
2464 if (UseTableRanges) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2465 do_SwitchRanges(create_lookup_ranges(x), value, x->default_sux());
a61af66fc99e Initial load
duke
parents:
diff changeset
2466 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2467 int len = x->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
2468 for (int i = 0; i < len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2469 __ cmp(lir_cond_equal, value, x->key_at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
2470 __ branch(lir_cond_equal, T_INT, x->sux_at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
2471 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2472 __ jump(x->default_sux());
a61af66fc99e Initial load
duke
parents:
diff changeset
2473 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2474 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2475
a61af66fc99e Initial load
duke
parents:
diff changeset
2476
a61af66fc99e Initial load
duke
parents:
diff changeset
2477 void LIRGenerator::do_Goto(Goto* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2478 set_no_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2479
a61af66fc99e Initial load
duke
parents:
diff changeset
2480 if (block()->next()->as_OsrEntry()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2481 // need to free up storage used for OSR entry point
a61af66fc99e Initial load
duke
parents:
diff changeset
2482 LIR_Opr osrBuffer = block()->next()->operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
2483 BasicTypeList signature;
a61af66fc99e Initial load
duke
parents:
diff changeset
2484 signature.append(T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
2485 CallingConvention* cc = frame_map()->c_calling_convention(&signature);
a61af66fc99e Initial load
duke
parents:
diff changeset
2486 __ move(osrBuffer, cc->args()->at(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
2487 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::OSR_migration_end),
a61af66fc99e Initial load
duke
parents:
diff changeset
2488 getThreadTemp(), LIR_OprFact::illegalOpr, cc->args());
a61af66fc99e Initial load
duke
parents:
diff changeset
2489 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2490
a61af66fc99e Initial load
duke
parents:
diff changeset
2491 if (x->is_safepoint()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2492 ValueStack* state = x->state_before() ? x->state_before() : x->state();
a61af66fc99e Initial load
duke
parents:
diff changeset
2493
a61af66fc99e Initial load
duke
parents:
diff changeset
2494 // increment backedge counter if needed
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2495 CodeEmitInfo* info = state_for(x, state);
3997
940513efe83a 7097679: Tiered: events with bad bci to Gotos reduced from Ifs
iveresov
parents: 3964
diff changeset
2496 increment_backedge_counter(info, x->profiled_bci());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2497 CodeEmitInfo* safepoint_info = state_for(x, state);
a61af66fc99e Initial load
duke
parents:
diff changeset
2498 __ safepoint(safepoint_poll_register(), safepoint_info);
a61af66fc99e Initial load
duke
parents:
diff changeset
2499 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2500
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2501 // Gotos can be folded Ifs, handle this case.
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2502 if (x->should_profile()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2503 ciMethod* method = x->profiled_method();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2504 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
2505 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
2506 assert(md != NULL, "Sanity");
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2507 ciProfileData* data = md->bci_to_data(x->profiled_bci());
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2508 assert(data != NULL, "must have profiling data");
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2509 int offset;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2510 if (x->direction() == Goto::taken) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2511 assert(data->is_BranchData(), "need BranchData for two-way branches");
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2512 offset = md->byte_offset_of_slot(data, BranchData::taken_offset());
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2513 } else if (x->direction() == Goto::not_taken) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2514 assert(data->is_BranchData(), "need BranchData for two-way branches");
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2515 offset = md->byte_offset_of_slot(data, BranchData::not_taken_offset());
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2516 } else {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2517 assert(data->is_JumpData(), "need JumpData for branches");
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2518 offset = md->byte_offset_of_slot(data, JumpData::taken_offset());
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2519 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2520 LIR_Opr md_reg = new_register(T_OBJECT);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2521 __ oop2reg(md->constant_encoding(), md_reg);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2522
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2523 increment_counter(new LIR_Address(md_reg, offset,
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2524 NOT_LP64(T_INT) LP64_ONLY(T_LONG)), DataLayout::counter_increment);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2525 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2526
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2527 // emit phi-instruction move after safepoint since this simplifies
a61af66fc99e Initial load
duke
parents:
diff changeset
2528 // describing the state as the safepoint.
a61af66fc99e Initial load
duke
parents:
diff changeset
2529 move_to_phi(x->state());
a61af66fc99e Initial load
duke
parents:
diff changeset
2530
a61af66fc99e Initial load
duke
parents:
diff changeset
2531 __ jump(x->default_sux());
a61af66fc99e Initial load
duke
parents:
diff changeset
2532 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2533
a61af66fc99e Initial load
duke
parents:
diff changeset
2534
a61af66fc99e Initial load
duke
parents:
diff changeset
2535 void LIRGenerator::do_Base(Base* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2536 __ std_entry(LIR_OprFact::illegalOpr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2537 // Emit moves from physical registers / stack slots to virtual registers
a61af66fc99e Initial load
duke
parents:
diff changeset
2538 CallingConvention* args = compilation()->frame_map()->incoming_arguments();
a61af66fc99e Initial load
duke
parents:
diff changeset
2539 IRScope* irScope = compilation()->hir()->top_scope();
a61af66fc99e Initial load
duke
parents:
diff changeset
2540 int java_index = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2541 for (int i = 0; i < args->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2542 LIR_Opr src = args->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2543 assert(!src->is_illegal(), "check");
a61af66fc99e Initial load
duke
parents:
diff changeset
2544 BasicType t = src->type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2545
a61af66fc99e Initial load
duke
parents:
diff changeset
2546 // Types which are smaller than int are passed as int, so
a61af66fc99e Initial load
duke
parents:
diff changeset
2547 // correct the type which passed.
a61af66fc99e Initial load
duke
parents:
diff changeset
2548 switch (t) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2549 case T_BYTE:
a61af66fc99e Initial load
duke
parents:
diff changeset
2550 case T_BOOLEAN:
a61af66fc99e Initial load
duke
parents:
diff changeset
2551 case T_SHORT:
a61af66fc99e Initial load
duke
parents:
diff changeset
2552 case T_CHAR:
a61af66fc99e Initial load
duke
parents:
diff changeset
2553 t = T_INT;
a61af66fc99e Initial load
duke
parents:
diff changeset
2554 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2555 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2556
a61af66fc99e Initial load
duke
parents:
diff changeset
2557 LIR_Opr dest = new_register(t);
a61af66fc99e Initial load
duke
parents:
diff changeset
2558 __ move(src, dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
2559
a61af66fc99e Initial load
duke
parents:
diff changeset
2560 // Assign new location to Local instruction for this local
a61af66fc99e Initial load
duke
parents:
diff changeset
2561 Local* local = x->state()->local_at(java_index)->as_Local();
a61af66fc99e Initial load
duke
parents:
diff changeset
2562 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
2563 #ifndef __SOFTFP__
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
2564 // The java calling convention passes double as long and float as int.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2565 assert(as_ValueType(t)->tag() == local->type()->tag(), "check");
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
2566 #endif // __SOFTFP__
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2567 local->set_operand(dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
2568 _instruction_for_operand.at_put_grow(dest->vreg_number(), local, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2569 java_index += type2size[t];
a61af66fc99e Initial load
duke
parents:
diff changeset
2570 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2571
780
c96bf21b756f 6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents: 579
diff changeset
2572 if (compilation()->env()->dtrace_method_probes()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2573 BasicTypeList signature;
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2574 signature.append(LP64_ONLY(T_LONG) NOT_LP64(T_INT)); // thread
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2575 signature.append(T_OBJECT); // methodOop
a61af66fc99e Initial load
duke
parents:
diff changeset
2576 LIR_OprList* args = new LIR_OprList();
a61af66fc99e Initial load
duke
parents:
diff changeset
2577 args->append(getThreadPointer());
a61af66fc99e Initial load
duke
parents:
diff changeset
2578 LIR_Opr meth = new_register(T_OBJECT);
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 819
diff changeset
2579 __ oop2reg(method()->constant_encoding(), meth);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2580 args->append(meth);
a61af66fc99e Initial load
duke
parents:
diff changeset
2581 call_runtime(&signature, args, CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry), voidType, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2582 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2583
a61af66fc99e Initial load
duke
parents:
diff changeset
2584 if (method()->is_synchronized()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2585 LIR_Opr obj;
a61af66fc99e Initial load
duke
parents:
diff changeset
2586 if (method()->is_static()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2587 obj = new_register(T_OBJECT);
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 819
diff changeset
2588 __ oop2reg(method()->holder()->java_mirror()->constant_encoding(), obj);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2589 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2590 Local* receiver = x->state()->local_at(0)->as_Local();
a61af66fc99e Initial load
duke
parents:
diff changeset
2591 assert(receiver != NULL, "must already exist");
a61af66fc99e Initial load
duke
parents:
diff changeset
2592 obj = receiver->operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
2593 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2594 assert(obj->is_valid(), "must be valid");
a61af66fc99e Initial load
duke
parents:
diff changeset
2595
a61af66fc99e Initial load
duke
parents:
diff changeset
2596 if (method()->is_synchronized() && GenerateSynchronizationCode) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2597 LIR_Opr lock = new_register(T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
2598 __ load_stack_address_monitor(0, lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
2599
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
2600 CodeEmitInfo* info = new CodeEmitInfo(scope()->start()->state()->copy(ValueStack::StateBefore, SynchronizationEntryBCI), NULL);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2601 CodeStub* slow_path = new MonitorEnterStub(obj, lock, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
2602
a61af66fc99e Initial load
duke
parents:
diff changeset
2603 // receiver is guaranteed non-NULL so don't need CodeEmitInfo
a61af66fc99e Initial load
duke
parents:
diff changeset
2604 __ lock_object(syncTempOpr(), obj, lock, new_register(T_OBJECT), slow_path, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2605 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2606 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2607
a61af66fc99e Initial load
duke
parents:
diff changeset
2608 // increment invocation counters if needed
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2609 if (!method()->is_accessor()) { // Accessors do not have MDOs, so no counting.
1825
80c9354976b0 6988346: 6986046 breaks tiered
iveresov
parents: 1819
diff changeset
2610 CodeEmitInfo* info = new CodeEmitInfo(scope()->start()->state()->copy(ValueStack::StateBefore, SynchronizationEntryBCI), NULL);
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2611 increment_invocation_counter(info);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2612 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2613
a61af66fc99e Initial load
duke
parents:
diff changeset
2614 // all blocks with a successor must end with an unconditional jump
a61af66fc99e Initial load
duke
parents:
diff changeset
2615 // to the successor even if they are consecutive
a61af66fc99e Initial load
duke
parents:
diff changeset
2616 __ jump(x->default_sux());
a61af66fc99e Initial load
duke
parents:
diff changeset
2617 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2618
a61af66fc99e Initial load
duke
parents:
diff changeset
2619
a61af66fc99e Initial load
duke
parents:
diff changeset
2620 void LIRGenerator::do_OsrEntry(OsrEntry* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2621 // construct our frame and model the production of incoming pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
2622 // to the OSR buffer.
a61af66fc99e Initial load
duke
parents:
diff changeset
2623 __ osr_entry(LIR_Assembler::osrBufferPointer());
a61af66fc99e Initial load
duke
parents:
diff changeset
2624 LIR_Opr result = rlock_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2625 __ move(LIR_Assembler::osrBufferPointer(), result);
a61af66fc99e Initial load
duke
parents:
diff changeset
2626 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2627
a61af66fc99e Initial load
duke
parents:
diff changeset
2628
a61af66fc99e Initial load
duke
parents:
diff changeset
2629 void LIRGenerator::invoke_load_arguments(Invoke* x, LIRItemList* args, const LIR_OprList* arg_list) {
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2630 int i = (x->has_receiver() || x->is_invokedynamic()) ? 1 : 0;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2631 for (; i < args->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2632 LIRItem* param = args->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2633 LIR_Opr loc = arg_list->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2634 if (loc->is_register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2635 param->load_item_force(loc);
a61af66fc99e Initial load
duke
parents:
diff changeset
2636 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2637 LIR_Address* addr = loc->as_address_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2638 param->load_for_store(addr->type());
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2639 if (addr->type() == T_OBJECT) {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2640 __ move_wide(param->result(), addr);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2641 } else
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2642 if (addr->type() == T_LONG || addr->type() == T_DOUBLE) {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2643 __ unaligned_move(param->result(), addr);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2644 } else {
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2645 __ move(param->result(), addr);
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2646 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2647 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2648 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2649
a61af66fc99e Initial load
duke
parents:
diff changeset
2650 if (x->has_receiver()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2651 LIRItem* receiver = args->at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2652 LIR_Opr loc = arg_list->at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2653 if (loc->is_register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2654 receiver->load_item_force(loc);
a61af66fc99e Initial load
duke
parents:
diff changeset
2655 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2656 assert(loc->is_address(), "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
2657 receiver->load_for_store(T_OBJECT);
2002
ac637b7220d1 6985015: C1 needs to support compressed oops
iveresov
parents: 1972
diff changeset
2658 __ move_wide(receiver->result(), loc->as_address_ptr());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2659 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2660 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2661 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2662
a61af66fc99e Initial load
duke
parents:
diff changeset
2663
a61af66fc99e Initial load
duke
parents:
diff changeset
2664 // Visits all arguments, returns appropriate items without loading them
a61af66fc99e Initial load
duke
parents:
diff changeset
2665 LIRItemList* LIRGenerator::invoke_visit_arguments(Invoke* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2666 LIRItemList* argument_items = new LIRItemList();
a61af66fc99e Initial load
duke
parents:
diff changeset
2667 if (x->has_receiver()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2668 LIRItem* receiver = new LIRItem(x->receiver(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2669 argument_items->append(receiver);
a61af66fc99e Initial load
duke
parents:
diff changeset
2670 }
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2671 if (x->is_invokedynamic()) {
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2672 // Insert a dummy for the synthetic MethodHandle argument.
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2673 argument_items->append(NULL);
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2674 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2675 int idx = x->has_receiver() ? 1 : 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2676 for (int i = 0; i < x->number_of_arguments(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2677 LIRItem* param = new LIRItem(x->argument_at(i), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2678 argument_items->append(param);
a61af66fc99e Initial load
duke
parents:
diff changeset
2679 idx += (param->type()->is_double_word() ? 2 : 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2680 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2681 return argument_items;
a61af66fc99e Initial load
duke
parents:
diff changeset
2682 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2683
a61af66fc99e Initial load
duke
parents:
diff changeset
2684
a61af66fc99e Initial load
duke
parents:
diff changeset
2685 // The invoke with receiver has following phases:
a61af66fc99e Initial load
duke
parents:
diff changeset
2686 // a) traverse and load/lock receiver;
a61af66fc99e Initial load
duke
parents:
diff changeset
2687 // b) traverse all arguments -> item-array (invoke_visit_argument)
a61af66fc99e Initial load
duke
parents:
diff changeset
2688 // c) push receiver on stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2689 // d) load each of the items and push on stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2690 // e) unlock receiver
a61af66fc99e Initial load
duke
parents:
diff changeset
2691 // f) move receiver into receiver-register %o0
a61af66fc99e Initial load
duke
parents:
diff changeset
2692 // g) lock result registers and emit call operation
a61af66fc99e Initial load
duke
parents:
diff changeset
2693 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2694 // Before issuing a call, we must spill-save all values on stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2695 // that are in caller-save register. "spill-save" moves thos registers
a61af66fc99e Initial load
duke
parents:
diff changeset
2696 // either in a free callee-save register or spills them if no free
a61af66fc99e Initial load
duke
parents:
diff changeset
2697 // callee save register is available.
a61af66fc99e Initial load
duke
parents:
diff changeset
2698 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2699 // The problem is where to invoke spill-save.
a61af66fc99e Initial load
duke
parents:
diff changeset
2700 // - if invoked between e) and f), we may lock callee save
a61af66fc99e Initial load
duke
parents:
diff changeset
2701 // register in "spill-save" that destroys the receiver register
a61af66fc99e Initial load
duke
parents:
diff changeset
2702 // before f) is executed
a61af66fc99e Initial load
duke
parents:
diff changeset
2703 // - if we rearange the f) to be earlier, by loading %o0, it
a61af66fc99e Initial load
duke
parents:
diff changeset
2704 // may destroy a value on the stack that is currently in %o0
a61af66fc99e Initial load
duke
parents:
diff changeset
2705 // and is waiting to be spilled
a61af66fc99e Initial load
duke
parents:
diff changeset
2706 // - if we keep the receiver locked while doing spill-save,
a61af66fc99e Initial load
duke
parents:
diff changeset
2707 // we cannot spill it as it is spill-locked
a61af66fc99e Initial load
duke
parents:
diff changeset
2708 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2709 void LIRGenerator::do_Invoke(Invoke* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2710 CallingConvention* cc = frame_map()->java_calling_convention(x->signature(), true);
a61af66fc99e Initial load
duke
parents:
diff changeset
2711
a61af66fc99e Initial load
duke
parents:
diff changeset
2712 LIR_OprList* arg_list = cc->args();
a61af66fc99e Initial load
duke
parents:
diff changeset
2713 LIRItemList* args = invoke_visit_arguments(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2714 LIR_Opr receiver = LIR_OprFact::illegalOpr;
a61af66fc99e Initial load
duke
parents:
diff changeset
2715
a61af66fc99e Initial load
duke
parents:
diff changeset
2716 // setup result register
a61af66fc99e Initial load
duke
parents:
diff changeset
2717 LIR_Opr result_register = LIR_OprFact::illegalOpr;
a61af66fc99e Initial load
duke
parents:
diff changeset
2718 if (x->type() != voidType) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2719 result_register = result_register_for(x->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
2720 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2721
a61af66fc99e Initial load
duke
parents:
diff changeset
2722 CodeEmitInfo* info = state_for(x, x->state());
a61af66fc99e Initial load
duke
parents:
diff changeset
2723
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2724 // invokedynamics can deoptimize.
1304
76c1d7d13ec5 6932091: JSR 292 x86 code cleanup
twisti
parents: 1295
diff changeset
2725 CodeEmitInfo* deopt_info = x->is_invokedynamic() ? state_for(x, x->state_before()) : NULL;
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2726
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2727 invoke_load_arguments(x, args, arg_list);
a61af66fc99e Initial load
duke
parents:
diff changeset
2728
a61af66fc99e Initial load
duke
parents:
diff changeset
2729 if (x->has_receiver()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2730 args->at(0)->load_item_force(LIR_Assembler::receiverOpr());
a61af66fc99e Initial load
duke
parents:
diff changeset
2731 receiver = args->at(0)->result();
a61af66fc99e Initial load
duke
parents:
diff changeset
2732 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2733
a61af66fc99e Initial load
duke
parents:
diff changeset
2734 // emit invoke code
a61af66fc99e Initial load
duke
parents:
diff changeset
2735 bool optimized = x->target_is_loaded() && x->target_is_final();
a61af66fc99e Initial load
duke
parents:
diff changeset
2736 assert(receiver->is_illegal() || receiver->is_equal(LIR_Assembler::receiverOpr()), "must match");
a61af66fc99e Initial load
duke
parents:
diff changeset
2737
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2738 // JSR 292
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2739 // Preserve the SP over MethodHandle call sites.
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2740 ciMethod* target = x->target();
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2741 if (target->is_method_handle_invoke()) {
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2742 info->set_is_method_handle_invoke(true);
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2743 __ 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
2744 }
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2745
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2746 switch (x->code()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2747 case Bytecodes::_invokestatic:
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2748 __ call_static(target, result_register,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2749 SharedRuntime::get_resolve_static_call_stub(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2750 arg_list, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
2751 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2752 case Bytecodes::_invokespecial:
a61af66fc99e Initial load
duke
parents:
diff changeset
2753 case Bytecodes::_invokevirtual:
a61af66fc99e Initial load
duke
parents:
diff changeset
2754 case Bytecodes::_invokeinterface:
a61af66fc99e Initial load
duke
parents:
diff changeset
2755 // for final target we still produce an inline cache, in order
a61af66fc99e Initial load
duke
parents:
diff changeset
2756 // to be able to call mixed mode
a61af66fc99e Initial load
duke
parents:
diff changeset
2757 if (x->code() == Bytecodes::_invokespecial || optimized) {
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2758 __ call_opt_virtual(target, receiver, result_register,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2759 SharedRuntime::get_resolve_opt_virtual_call_stub(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2760 arg_list, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
2761 } else if (x->vtable_index() < 0) {
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2762 __ call_icvirtual(target, receiver, result_register,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2763 SharedRuntime::get_resolve_virtual_call_stub(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2764 arg_list, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
2765 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2766 int entry_offset = instanceKlass::vtable_start_offset() + x->vtable_index() * vtableEntry::size();
a61af66fc99e Initial load
duke
parents:
diff changeset
2767 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
2768 __ call_virtual(target, receiver, result_register, vtable_offset, arg_list, info);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2769 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2770 break;
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2771 case Bytecodes::_invokedynamic: {
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2772 ciBytecodeStream bcs(x->scope()->method());
1819
f02a8bbe6ed4 6986046: C1 valuestack cleanup
roland
parents: 1816
diff changeset
2773 bcs.force_bci(x->state()->bci());
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2774 assert(bcs.cur_bc() == Bytecodes::_invokedynamic, "wrong stream");
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2775 ciCPCache* cpcache = bcs.get_cpcache();
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2776
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2777 // Get CallSite offset from constant pool cache pointer.
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2778 int index = bcs.get_method_index();
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2779 size_t call_site_offset = cpcache->get_f1_offset(index);
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2780
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2781 // If this invokedynamic call site hasn't been executed yet in
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2782 // the interpreter, the CallSite object in the constant pool
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2783 // cache is still null and we need to deoptimize.
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2784 if (cpcache->is_f1_null_at(index)) {
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2785 // Cannot re-use same xhandlers for multiple CodeEmitInfos, so
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2786 // clone all handlers. This is handled transparently in other
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2787 // places by the CodeEmitInfo cloning logic but is handled
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2788 // specially here because a stub isn't being used.
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2789 x->set_exception_handlers(new XHandlers(x->exception_handlers()));
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2790
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2791 DeoptimizeStub* deopt_stub = new DeoptimizeStub(deopt_info);
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2792 __ jump(deopt_stub);
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2793 }
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2794
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2795 // Use the receiver register for the synthetic MethodHandle
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2796 // argument.
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2797 receiver = LIR_Assembler::receiverOpr();
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2798 LIR_Opr tmp = new_register(objectType);
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2799
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2800 // Load CallSite object from constant pool cache.
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2801 __ oop2reg(cpcache->constant_encoding(), tmp);
3756
c8f2186acf6d 7053520: JSR292: crash in invokedynamic with C1 using tiered and compressed oops
twisti
parents: 3255
diff changeset
2802 __ move_wide(new LIR_Address(tmp, call_site_offset, T_OBJECT), tmp);
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2803
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2804 // Load target MethodHandle from CallSite object.
2357
8033953d67ff 7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents: 2352
diff changeset
2805 __ load(new LIR_Address(tmp, java_lang_invoke_CallSite::target_offset_in_bytes(), T_OBJECT), receiver);
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2806
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2807 __ call_dynamic(target, receiver, result_register,
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2808 SharedRuntime::get_resolve_opt_virtual_call_stub(),
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2809 arg_list, info);
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2810 break;
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2811 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2812 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
2813 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
2814 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2815 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2816
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2817 // JSR 292
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2818 // Restore the SP after MethodHandle call sites.
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2819 if (target->is_method_handle_invoke()) {
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2820 __ 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
2821 }
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2822
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2823 if (x->type()->is_float() || x->type()->is_double()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2824 // Force rounding of results from non-strictfp when in strictfp
a61af66fc99e Initial load
duke
parents:
diff changeset
2825 // scope (or when we don't know the strictness of the callee, to
a61af66fc99e Initial load
duke
parents:
diff changeset
2826 // be safe.)
a61af66fc99e Initial load
duke
parents:
diff changeset
2827 if (method()->is_strict()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2828 if (!x->target_is_loaded() || !x->target_is_strictfp()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2829 result_register = round_item(result_register);
a61af66fc99e Initial load
duke
parents:
diff changeset
2830 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2831 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2832 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2833
a61af66fc99e Initial load
duke
parents:
diff changeset
2834 if (result_register->is_valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2835 LIR_Opr result = rlock_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2836 __ move(result_register, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
2837 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2838 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2839
a61af66fc99e Initial load
duke
parents:
diff changeset
2840
a61af66fc99e Initial load
duke
parents:
diff changeset
2841 void LIRGenerator::do_FPIntrinsics(Intrinsic* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2842 assert(x->number_of_arguments() == 1, "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
2843 LIRItem value (x->argument_at(0), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2844 LIR_Opr reg = rlock_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2845 value.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2846 LIR_Opr tmp = force_to_spill(value.result(), as_BasicType(x->type()));
a61af66fc99e Initial load
duke
parents:
diff changeset
2847 __ move(tmp, reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2848 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2849
a61af66fc99e Initial load
duke
parents:
diff changeset
2850
a61af66fc99e Initial load
duke
parents:
diff changeset
2851
a61af66fc99e Initial load
duke
parents:
diff changeset
2852 // Code for : x->x() {x->cond()} x->y() ? x->tval() : x->fval()
a61af66fc99e Initial load
duke
parents:
diff changeset
2853 void LIRGenerator::do_IfOp(IfOp* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2854 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2855 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2856 ValueTag xtag = x->x()->type()->tag();
a61af66fc99e Initial load
duke
parents:
diff changeset
2857 ValueTag ttag = x->tval()->type()->tag();
a61af66fc99e Initial load
duke
parents:
diff changeset
2858 assert(xtag == intTag || xtag == objectTag, "cannot handle others");
a61af66fc99e Initial load
duke
parents:
diff changeset
2859 assert(ttag == addressTag || ttag == intTag || ttag == objectTag || ttag == longTag, "cannot handle others");
a61af66fc99e Initial load
duke
parents:
diff changeset
2860 assert(ttag == x->fval()->type()->tag(), "cannot handle others");
a61af66fc99e Initial load
duke
parents:
diff changeset
2861 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2862 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2863
a61af66fc99e Initial load
duke
parents:
diff changeset
2864 LIRItem left(x->x(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2865 LIRItem right(x->y(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2866 left.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2867 if (can_inline_as_constant(right.value())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2868 right.dont_load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2869 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2870 right.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2871 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2872
a61af66fc99e Initial load
duke
parents:
diff changeset
2873 LIRItem t_val(x->tval(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2874 LIRItem f_val(x->fval(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2875 t_val.dont_load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2876 f_val.dont_load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2877 LIR_Opr reg = rlock_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2878
a61af66fc99e Initial load
duke
parents:
diff changeset
2879 __ 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
2880 __ 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
2881 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2882
a61af66fc99e Initial load
duke
parents:
diff changeset
2883
a61af66fc99e Initial load
duke
parents:
diff changeset
2884 void LIRGenerator::do_Intrinsic(Intrinsic* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2885 switch (x->id()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2886 case vmIntrinsics::_intBitsToFloat :
a61af66fc99e Initial load
duke
parents:
diff changeset
2887 case vmIntrinsics::_doubleToRawLongBits :
a61af66fc99e Initial load
duke
parents:
diff changeset
2888 case vmIntrinsics::_longBitsToDouble :
a61af66fc99e Initial load
duke
parents:
diff changeset
2889 case vmIntrinsics::_floatToRawIntBits : {
a61af66fc99e Initial load
duke
parents:
diff changeset
2890 do_FPIntrinsics(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2891 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2892 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2893
a61af66fc99e Initial load
duke
parents:
diff changeset
2894 case vmIntrinsics::_currentTimeMillis: {
a61af66fc99e Initial load
duke
parents:
diff changeset
2895 assert(x->number_of_arguments() == 0, "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
2896 LIR_Opr reg = result_register_for(x->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
2897 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, os::javaTimeMillis), getThreadTemp(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2898 reg, new LIR_OprList());
a61af66fc99e Initial load
duke
parents:
diff changeset
2899 LIR_Opr result = rlock_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2900 __ move(reg, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
2901 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2902 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2903
a61af66fc99e Initial load
duke
parents:
diff changeset
2904 case vmIntrinsics::_nanoTime: {
a61af66fc99e Initial load
duke
parents:
diff changeset
2905 assert(x->number_of_arguments() == 0, "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
2906 LIR_Opr reg = result_register_for(x->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
2907 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, os::javaTimeNanos), getThreadTemp(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2908 reg, new LIR_OprList());
a61af66fc99e Initial load
duke
parents:
diff changeset
2909 LIR_Opr result = rlock_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2910 __ move(reg, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
2911 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2912 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2913
a61af66fc99e Initial load
duke
parents:
diff changeset
2914 case vmIntrinsics::_Object_init: do_RegisterFinalizer(x); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2915 case vmIntrinsics::_getClass: do_getClass(x); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2916 case vmIntrinsics::_currentThread: do_currentThread(x); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2917
a61af66fc99e Initial load
duke
parents:
diff changeset
2918 case vmIntrinsics::_dlog: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2919 case vmIntrinsics::_dlog10: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2920 case vmIntrinsics::_dabs: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2921 case vmIntrinsics::_dsqrt: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2922 case vmIntrinsics::_dtan: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2923 case vmIntrinsics::_dsin : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2924 case vmIntrinsics::_dcos : do_MathIntrinsic(x); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2925 case vmIntrinsics::_arraycopy: do_ArrayCopy(x); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2926
a61af66fc99e Initial load
duke
parents:
diff changeset
2927 // java.nio.Buffer.checkIndex
a61af66fc99e Initial load
duke
parents:
diff changeset
2928 case vmIntrinsics::_checkIndex: do_NIOCheckIndex(x); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2929
a61af66fc99e Initial load
duke
parents:
diff changeset
2930 case vmIntrinsics::_compareAndSwapObject:
a61af66fc99e Initial load
duke
parents:
diff changeset
2931 do_CompareAndSwap(x, objectType);
a61af66fc99e Initial load
duke
parents:
diff changeset
2932 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2933 case vmIntrinsics::_compareAndSwapInt:
a61af66fc99e Initial load
duke
parents:
diff changeset
2934 do_CompareAndSwap(x, intType);
a61af66fc99e Initial load
duke
parents:
diff changeset
2935 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2936 case vmIntrinsics::_compareAndSwapLong:
a61af66fc99e Initial load
duke
parents:
diff changeset
2937 do_CompareAndSwap(x, longType);
a61af66fc99e Initial load
duke
parents:
diff changeset
2938 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2939
a61af66fc99e Initial load
duke
parents:
diff changeset
2940 // sun.misc.AtomicLongCSImpl.attemptUpdate
a61af66fc99e Initial load
duke
parents:
diff changeset
2941 case vmIntrinsics::_attemptUpdate:
a61af66fc99e Initial load
duke
parents:
diff changeset
2942 do_AttemptUpdate(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2943 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2944
3249
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2945 case vmIntrinsics::_Reference_get:
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2946 do_Reference_get(x);
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2947 break;
e1162778c1c8 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 2357
diff changeset
2948
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2949 default: ShouldNotReachHere(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2950 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2951 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2952
a61af66fc99e Initial load
duke
parents:
diff changeset
2953 void LIRGenerator::do_ProfileCall(ProfileCall* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2954 // Need recv in a temporary register so it interferes with the other temporaries
a61af66fc99e Initial load
duke
parents:
diff changeset
2955 LIR_Opr recv = LIR_OprFact::illegalOpr;
a61af66fc99e Initial load
duke
parents:
diff changeset
2956 LIR_Opr mdo = new_register(T_OBJECT);
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2957 // tmp is used to hold the counters on SPARC
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2958 LIR_Opr tmp = new_pointer_register();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2959 if (x->recv() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2960 LIRItem value(x->recv(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2961 value.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2962 recv = new_register(T_OBJECT);
a61af66fc99e Initial load
duke
parents:
diff changeset
2963 __ move(value.result(), recv);
a61af66fc99e Initial load
duke
parents:
diff changeset
2964 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2965 __ profile_call(x->method(), x->bci_of_invoke(), mdo, recv, tmp, x->known_holder());
a61af66fc99e Initial load
duke
parents:
diff changeset
2966 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2967
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2968 void LIRGenerator::do_ProfileInvoke(ProfileInvoke* x) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2969 // We can safely ignore accessors here, since c2 will inline them anyway,
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2970 // accessors are also always mature.
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2971 if (!x->inlinee()->is_accessor()) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2972 CodeEmitInfo* info = state_for(x, x->state(), true);
3964
dc45ae774613 7096639: Tiered: Incorrect counter overflow handling for inlined methods
iveresov
parents: 3756
diff changeset
2973 // 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
2974 increment_event_counter_impl(info, x->inlinee(), (1 << Tier23InlineeNotifyFreqLog) - 1, InvocationEntryBci, false, true);
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2975 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2976 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2977
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2978 void LIRGenerator::increment_event_counter(CodeEmitInfo* info, int bci, bool backedge) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2979 int freq_log;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2980 int level = compilation()->env()->comp_level();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2981 if (level == CompLevel_limited_profile) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2982 freq_log = (backedge ? Tier2BackedgeNotifyFreqLog : Tier2InvokeNotifyFreqLog);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2983 } else if (level == CompLevel_full_profile) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2984 freq_log = (backedge ? Tier3BackedgeNotifyFreqLog : Tier3InvokeNotifyFreqLog);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2985 } else {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2986 ShouldNotReachHere();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2987 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2988 // Increment the appropriate invocation/backedge counter and notify the runtime.
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2989 increment_event_counter_impl(info, info->scope()->method(), (1 << freq_log) - 1, bci, backedge, true);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2990 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2991
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2992 void LIRGenerator::increment_event_counter_impl(CodeEmitInfo* info,
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2993 ciMethod *method, int frequency,
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2994 int bci, bool backedge, bool notify) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2995 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
2996 int level = _compilation->env()->comp_level();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2997 assert(level > CompLevel_simple, "Shouldn't be here");
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2998
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
2999 int offset = -1;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3000 LIR_Opr counter_holder = new_register(T_OBJECT);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3001 LIR_Opr meth;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3002 if (level == CompLevel_limited_profile) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3003 offset = in_bytes(backedge ? methodOopDesc::backedge_counter_offset() :
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3004 methodOopDesc::invocation_counter_offset());
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3005 __ oop2reg(method->constant_encoding(), counter_holder);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3006 meth = counter_holder;
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3007 } else if (level == CompLevel_full_profile) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3008 offset = in_bytes(backedge ? methodDataOopDesc::backedge_counter_offset() :
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3009 methodDataOopDesc::invocation_counter_offset());
2007
5ddfcf4b079e 7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents: 2002
diff changeset
3010 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
3011 assert(md != NULL, "Sanity");
5ddfcf4b079e 7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents: 2002
diff changeset
3012 __ oop2reg(md->constant_encoding(), counter_holder);
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3013 meth = new_register(T_OBJECT);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3014 __ oop2reg(method->constant_encoding(), meth);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3015 } else {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3016 ShouldNotReachHere();
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3017 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3018 LIR_Address* counter = new LIR_Address(counter_holder, offset, T_INT);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3019 LIR_Opr result = new_register(T_INT);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3020 __ load(counter, result);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3021 __ add(result, LIR_OprFact::intConst(InvocationCounter::count_increment), result);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3022 __ store(result, counter);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3023 if (notify) {
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3024 LIR_Opr mask = load_immediate(frequency << InvocationCounter::count_shift, T_INT);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3025 __ logical_and(result, mask, result);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3026 __ cmp(lir_cond_equal, result, LIR_OprFact::intConst(0));
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3027 // 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
3028 CodeStub* overflow = new CounterOverflowStub(info, bci, meth);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3029 __ branch(lir_cond_equal, T_INT, overflow);
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3030 __ branch_destination(overflow->continuation());
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3031 }
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1681
diff changeset
3032 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3033
2166
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3034 void LIRGenerator::do_RuntimeCall(RuntimeCall* x) {
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3035 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
3036 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
3037
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3038 if (x->pass_thread()) {
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3039 signature->append(T_ADDRESS);
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3040 args->append(getThreadPointer());
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3041 }
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3042
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3043 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
3044 Value a = x->argument_at(i);
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3045 LIRItem* item = new LIRItem(a, this);
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3046 item->load_item();
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3047 args->append(item->result());
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3048 signature->append(as_BasicType(a->type()));
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3049 }
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3050
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3051 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
3052 if (x->type() == voidType) {
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3053 set_no_result(x);
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3054 } else {
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3055 __ move(result, rlock_result(x));
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3056 }
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3057 }
403dc4c1d7f5 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 2089
diff changeset
3058
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3059 LIR_Opr LIRGenerator::call_runtime(Value arg1, address entry, ValueType* result_type, CodeEmitInfo* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3060 LIRItemList args(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3061 LIRItem value(arg1, this);
a61af66fc99e Initial load
duke
parents:
diff changeset
3062 args.append(&value);
a61af66fc99e Initial load
duke
parents:
diff changeset
3063 BasicTypeList signature;
a61af66fc99e Initial load
duke
parents:
diff changeset
3064 signature.append(as_BasicType(arg1->type()));
a61af66fc99e Initial load
duke
parents:
diff changeset
3065
a61af66fc99e Initial load
duke
parents:
diff changeset
3066 return call_runtime(&signature, &args, entry, result_type, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
3067 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3068
a61af66fc99e Initial load
duke
parents:
diff changeset
3069
a61af66fc99e Initial load
duke
parents:
diff changeset
3070 LIR_Opr LIRGenerator::call_runtime(Value arg1, Value arg2, address entry, ValueType* result_type, CodeEmitInfo* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3071 LIRItemList args(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
3072 LIRItem value1(arg1, this);
a61af66fc99e Initial load
duke
parents:
diff changeset
3073 LIRItem value2(arg2, this);
a61af66fc99e Initial load
duke
parents:
diff changeset
3074 args.append(&value1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3075 args.append(&value2);
a61af66fc99e Initial load
duke
parents:
diff changeset
3076 BasicTypeList signature;
a61af66fc99e Initial load
duke
parents:
diff changeset
3077 signature.append(as_BasicType(arg1->type()));
a61af66fc99e Initial load
duke
parents:
diff changeset
3078 signature.append(as_BasicType(arg2->type()));
a61af66fc99e Initial load
duke
parents:
diff changeset
3079
a61af66fc99e Initial load
duke
parents:
diff changeset
3080 return call_runtime(&signature, &args, entry, result_type, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
3081 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3082
a61af66fc99e Initial load
duke
parents:
diff changeset
3083
a61af66fc99e Initial load
duke
parents:
diff changeset
3084 LIR_Opr LIRGenerator::call_runtime(BasicTypeArray* signature, LIR_OprList* args,
a61af66fc99e Initial load
duke
parents:
diff changeset
3085 address entry, ValueType* result_type, CodeEmitInfo* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3086 // get a result register
a61af66fc99e Initial load
duke
parents:
diff changeset
3087 LIR_Opr phys_reg = LIR_OprFact::illegalOpr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3088 LIR_Opr result = LIR_OprFact::illegalOpr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3089 if (result_type->tag() != voidTag) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3090 result = new_register(result_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
3091 phys_reg = result_register_for(result_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
3092 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3093
a61af66fc99e Initial load
duke
parents:
diff changeset
3094 // move the arguments into the correct location
a61af66fc99e Initial load
duke
parents:
diff changeset
3095 CallingConvention* cc = frame_map()->c_calling_convention(signature);
a61af66fc99e Initial load
duke
parents:
diff changeset
3096 assert(cc->length() == args->length(), "argument mismatch");
a61af66fc99e Initial load
duke
parents:
diff changeset
3097 for (int i = 0; i < args->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3098 LIR_Opr arg = args->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3099 LIR_Opr loc = cc->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3100 if (loc->is_register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3101 __ move(arg, loc);
a61af66fc99e Initial load
duke
parents:
diff changeset
3102 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3103 LIR_Address* addr = loc->as_address_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
3104 // if (!can_store_as_constant(arg)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3105 // LIR_Opr tmp = new_register(arg->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
3106 // __ move(arg, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
3107 // arg = tmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
3108 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
3109 if (addr->type() == T_LONG || addr->type() == T_DOUBLE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3110 __ unaligned_move(arg, addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
3111 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3112 __ move(arg, addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
3113 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3114 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3115 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3116
a61af66fc99e Initial load
duke
parents:
diff changeset
3117 if (info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3118 __ call_runtime(entry, getThreadTemp(), phys_reg, cc->args(), info);
a61af66fc99e Initial load
duke
parents:
diff changeset
3119 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3120 __ call_runtime_leaf(entry, getThreadTemp(), phys_reg, cc->args());
a61af66fc99e Initial load
duke
parents:
diff changeset
3121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3122 if (result->is_valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3123 __ move(phys_reg, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
3124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3125 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
3126 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3127
a61af66fc99e Initial load
duke
parents:
diff changeset
3128
a61af66fc99e Initial load
duke
parents:
diff changeset
3129 LIR_Opr LIRGenerator::call_runtime(BasicTypeArray* signature, LIRItemList* args,
a61af66fc99e Initial load
duke
parents:
diff changeset
3130 address entry, ValueType* result_type, CodeEmitInfo* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3131 // get a result register
a61af66fc99e Initial load
duke
parents:
diff changeset
3132 LIR_Opr phys_reg = LIR_OprFact::illegalOpr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3133 LIR_Opr result = LIR_OprFact::illegalOpr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3134 if (result_type->tag() != voidTag) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3135 result = new_register(result_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
3136 phys_reg = result_register_for(result_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
3137 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3138
a61af66fc99e Initial load
duke
parents:
diff changeset
3139 // move the arguments into the correct location
a61af66fc99e Initial load
duke
parents:
diff changeset
3140 CallingConvention* cc = frame_map()->c_calling_convention(signature);
a61af66fc99e Initial load
duke
parents:
diff changeset
3141
a61af66fc99e Initial load
duke
parents:
diff changeset
3142 assert(cc->length() == args->length(), "argument mismatch");
a61af66fc99e Initial load
duke
parents:
diff changeset
3143 for (int i = 0; i < args->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3144 LIRItem* arg = args->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3145 LIR_Opr loc = cc->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3146 if (loc->is_register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3147 arg->load_item_force(loc);
a61af66fc99e Initial load
duke
parents:
diff changeset
3148 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3149 LIR_Address* addr = loc->as_address_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
3150 arg->load_for_store(addr->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
3151 if (addr->type() == T_LONG || addr->type() == T_DOUBLE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3152 __ unaligned_move(arg->result(), addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
3153 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3154 __ move(arg->result(), addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
3155 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3156 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3157 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3158
a61af66fc99e Initial load
duke
parents:
diff changeset
3159 if (info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3160 __ call_runtime(entry, getThreadTemp(), phys_reg, cc->args(), info);
a61af66fc99e Initial load
duke
parents:
diff changeset
3161 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3162 __ call_runtime_leaf(entry, getThreadTemp(), phys_reg, cc->args());
a61af66fc99e Initial load
duke
parents:
diff changeset
3163 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3164 if (result->is_valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3165 __ move(phys_reg, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
3166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3167 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
3168 }