annotate src/share/vm/c1/c1_LIRGenerator.cpp @ 1721:413ad0331a0c

6977924: Changes for 6975078 produce build error with certain gcc versions Summary: The changes introduced for 6975078 assign badHeapOopVal to the _allocation field in the ResourceObj class. In 32 bit linux builds with certain versions of gcc this assignment will be flagged as an error while compiling allocation.cpp. In 32 bit builds the constant value badHeapOopVal (which is cast to an intptr_t) is negative. The _allocation field is typed as an unsigned intptr_t and gcc catches this as an error. Reviewed-by: jcoomes, ysr, phh
author johnc
date Wed, 18 Aug 2010 10:59:06 -0700
parents 126ea7725993
children d5d065957597
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1378
diff changeset
2 * Copyright (c) 2005, 2010, 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
a61af66fc99e Initial load
duke
parents:
diff changeset
25 # include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
26 # include "incls/_c1_LIRGenerator.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
29 #define __ gen()->lir(__FILE__, __LINE__)->
a61af66fc99e Initial load
duke
parents:
diff changeset
30 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
31 #define __ gen()->lir()->
a61af66fc99e Initial load
duke
parents:
diff changeset
32 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
33
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
34 // 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
35 #ifdef ARM
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
36 #define PATCHED_ADDR (204)
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
37 #else
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
38 #define PATCHED_ADDR (max_jint)
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
39 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
40
a61af66fc99e Initial load
duke
parents:
diff changeset
41 void PhiResolverState::reset(int max_vregs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
42 // Initialize array sizes
a61af66fc99e Initial load
duke
parents:
diff changeset
43 _virtual_operands.at_put_grow(max_vregs - 1, NULL, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
44 _virtual_operands.trunc_to(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
45 _other_operands.at_put_grow(max_vregs - 1, NULL, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
46 _other_operands.trunc_to(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
47 _vreg_table.at_put_grow(max_vregs - 1, NULL, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
48 _vreg_table.trunc_to(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
49 }
a61af66fc99e Initial load
duke
parents:
diff changeset
50
a61af66fc99e Initial load
duke
parents:
diff changeset
51
a61af66fc99e Initial load
duke
parents:
diff changeset
52
a61af66fc99e Initial load
duke
parents:
diff changeset
53 //--------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
54 // PhiResolver
a61af66fc99e Initial load
duke
parents:
diff changeset
55
a61af66fc99e Initial load
duke
parents:
diff changeset
56 // Resolves cycles:
a61af66fc99e Initial load
duke
parents:
diff changeset
57 //
a61af66fc99e Initial load
duke
parents:
diff changeset
58 // r1 := r2 becomes temp := r1
a61af66fc99e Initial load
duke
parents:
diff changeset
59 // r2 := r1 r1 := r2
a61af66fc99e Initial load
duke
parents:
diff changeset
60 // r2 := temp
a61af66fc99e Initial load
duke
parents:
diff changeset
61 // and orders moves:
a61af66fc99e Initial load
duke
parents:
diff changeset
62 //
a61af66fc99e Initial load
duke
parents:
diff changeset
63 // r2 := r3 becomes r1 := r2
a61af66fc99e Initial load
duke
parents:
diff changeset
64 // r1 := r2 r2 := r3
a61af66fc99e Initial load
duke
parents:
diff changeset
65
a61af66fc99e Initial load
duke
parents:
diff changeset
66 PhiResolver::PhiResolver(LIRGenerator* gen, int max_vregs)
a61af66fc99e Initial load
duke
parents:
diff changeset
67 : _gen(gen)
a61af66fc99e Initial load
duke
parents:
diff changeset
68 , _state(gen->resolver_state())
a61af66fc99e Initial load
duke
parents:
diff changeset
69 , _temp(LIR_OprFact::illegalOpr)
a61af66fc99e Initial load
duke
parents:
diff changeset
70 {
a61af66fc99e Initial load
duke
parents:
diff changeset
71 // reinitialize the shared state arrays
a61af66fc99e Initial load
duke
parents:
diff changeset
72 _state.reset(max_vregs);
a61af66fc99e Initial load
duke
parents:
diff changeset
73 }
a61af66fc99e Initial load
duke
parents:
diff changeset
74
a61af66fc99e Initial load
duke
parents:
diff changeset
75
a61af66fc99e Initial load
duke
parents:
diff changeset
76 void PhiResolver::emit_move(LIR_Opr src, LIR_Opr dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
77 assert(src->is_valid(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
78 assert(dest->is_valid(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
79 __ move(src, dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
80 }
a61af66fc99e Initial load
duke
parents:
diff changeset
81
a61af66fc99e Initial load
duke
parents:
diff changeset
82
a61af66fc99e Initial load
duke
parents:
diff changeset
83 void PhiResolver::move_temp_to(LIR_Opr dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
84 assert(_temp->is_valid(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
85 emit_move(_temp, dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
86 NOT_PRODUCT(_temp = LIR_OprFact::illegalOpr);
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::move_to_temp(LIR_Opr src) {
a61af66fc99e Initial load
duke
parents:
diff changeset
91 assert(_temp->is_illegal(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
92 _temp = _gen->new_register(src->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
93 emit_move(src, _temp);
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 // Traverse assignment graph in depth first order and generate moves in post order
a61af66fc99e Initial load
duke
parents:
diff changeset
98 // ie. two assignments: b := c, a := b start with node c:
a61af66fc99e Initial load
duke
parents:
diff changeset
99 // Call graph: move(NULL, c) -> move(c, b) -> move(b, a)
a61af66fc99e Initial load
duke
parents:
diff changeset
100 // Generates moves in this order: move b to a and move c to b
a61af66fc99e Initial load
duke
parents:
diff changeset
101 // ie. cycle a := b, b := a start with node a
a61af66fc99e Initial load
duke
parents:
diff changeset
102 // Call graph: move(NULL, a) -> move(a, b) -> move(b, a)
a61af66fc99e Initial load
duke
parents:
diff changeset
103 // Generates moves in this order: move b to temp, move a to b, move temp to a
a61af66fc99e Initial load
duke
parents:
diff changeset
104 void PhiResolver::move(ResolveNode* src, ResolveNode* dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
105 if (!dest->visited()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
106 dest->set_visited();
a61af66fc99e Initial load
duke
parents:
diff changeset
107 for (int i = dest->no_of_destinations()-1; i >= 0; i --) {
a61af66fc99e Initial load
duke
parents:
diff changeset
108 move(dest, dest->destination_at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
109 }
a61af66fc99e Initial load
duke
parents:
diff changeset
110 } else if (!dest->start_node()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
111 // cylce in graph detected
a61af66fc99e Initial load
duke
parents:
diff changeset
112 assert(_loop == NULL, "only one loop valid!");
a61af66fc99e Initial load
duke
parents:
diff changeset
113 _loop = dest;
a61af66fc99e Initial load
duke
parents:
diff changeset
114 move_to_temp(src->operand());
a61af66fc99e Initial load
duke
parents:
diff changeset
115 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
116 } // else dest is a start node
a61af66fc99e Initial load
duke
parents:
diff changeset
117
a61af66fc99e Initial load
duke
parents:
diff changeset
118 if (!dest->assigned()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
119 if (_loop == dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
120 move_temp_to(dest->operand());
a61af66fc99e Initial load
duke
parents:
diff changeset
121 dest->set_assigned();
a61af66fc99e Initial load
duke
parents:
diff changeset
122 } else if (src != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
123 emit_move(src->operand(), dest->operand());
a61af66fc99e Initial load
duke
parents:
diff changeset
124 dest->set_assigned();
a61af66fc99e Initial load
duke
parents:
diff changeset
125 }
a61af66fc99e Initial load
duke
parents:
diff changeset
126 }
a61af66fc99e Initial load
duke
parents:
diff changeset
127 }
a61af66fc99e Initial load
duke
parents:
diff changeset
128
a61af66fc99e Initial load
duke
parents:
diff changeset
129
a61af66fc99e Initial load
duke
parents:
diff changeset
130 PhiResolver::~PhiResolver() {
a61af66fc99e Initial load
duke
parents:
diff changeset
131 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
132 // resolve any cycles in moves from and to virtual registers
a61af66fc99e Initial load
duke
parents:
diff changeset
133 for (i = virtual_operands().length() - 1; i >= 0; i --) {
a61af66fc99e Initial load
duke
parents:
diff changeset
134 ResolveNode* node = virtual_operands()[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
135 if (!node->visited()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
136 _loop = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
137 move(NULL, node);
a61af66fc99e Initial load
duke
parents:
diff changeset
138 node->set_start_node();
a61af66fc99e Initial load
duke
parents:
diff changeset
139 assert(_temp->is_illegal(), "move_temp_to() call missing");
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 // generate move for move from non virtual register to abitrary destination
a61af66fc99e Initial load
duke
parents:
diff changeset
144 for (i = other_operands().length() - 1; i >= 0; i --) {
a61af66fc99e Initial load
duke
parents:
diff changeset
145 ResolveNode* node = other_operands()[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
146 for (int j = node->no_of_destinations() - 1; j >= 0; j --) {
a61af66fc99e Initial load
duke
parents:
diff changeset
147 emit_move(node->operand(), node->destination_at(j)->operand());
a61af66fc99e Initial load
duke
parents:
diff changeset
148 }
a61af66fc99e Initial load
duke
parents:
diff changeset
149 }
a61af66fc99e Initial load
duke
parents:
diff changeset
150 }
a61af66fc99e Initial load
duke
parents:
diff changeset
151
a61af66fc99e Initial load
duke
parents:
diff changeset
152
a61af66fc99e Initial load
duke
parents:
diff changeset
153 ResolveNode* PhiResolver::create_node(LIR_Opr opr, bool source) {
a61af66fc99e Initial load
duke
parents:
diff changeset
154 ResolveNode* node;
a61af66fc99e Initial load
duke
parents:
diff changeset
155 if (opr->is_virtual()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
156 int vreg_num = opr->vreg_number();
a61af66fc99e Initial load
duke
parents:
diff changeset
157 node = vreg_table().at_grow(vreg_num, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
158 assert(node == NULL || node->operand() == opr, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
159 if (node == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
160 node = new ResolveNode(opr);
a61af66fc99e Initial load
duke
parents:
diff changeset
161 vreg_table()[vreg_num] = node;
a61af66fc99e Initial load
duke
parents:
diff changeset
162 }
a61af66fc99e Initial load
duke
parents:
diff changeset
163 // Make sure that all virtual operands show up in the list when
a61af66fc99e Initial load
duke
parents:
diff changeset
164 // they are used as the source of a move.
a61af66fc99e Initial load
duke
parents:
diff changeset
165 if (source && !virtual_operands().contains(node)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
166 virtual_operands().append(node);
a61af66fc99e Initial load
duke
parents:
diff changeset
167 }
a61af66fc99e Initial load
duke
parents:
diff changeset
168 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
169 assert(source, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
170 node = new ResolveNode(opr);
a61af66fc99e Initial load
duke
parents:
diff changeset
171 other_operands().append(node);
a61af66fc99e Initial load
duke
parents:
diff changeset
172 }
a61af66fc99e Initial load
duke
parents:
diff changeset
173 return node;
a61af66fc99e Initial load
duke
parents:
diff changeset
174 }
a61af66fc99e Initial load
duke
parents:
diff changeset
175
a61af66fc99e Initial load
duke
parents:
diff changeset
176
a61af66fc99e Initial load
duke
parents:
diff changeset
177 void PhiResolver::move(LIR_Opr src, LIR_Opr dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
178 assert(dest->is_virtual(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
179 // tty->print("move "); src->print(); tty->print(" to "); dest->print(); tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
180 assert(src->is_valid(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
181 assert(dest->is_valid(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
182 ResolveNode* source = source_node(src);
a61af66fc99e Initial load
duke
parents:
diff changeset
183 source->append(destination_node(dest));
a61af66fc99e Initial load
duke
parents:
diff changeset
184 }
a61af66fc99e Initial load
duke
parents:
diff changeset
185
a61af66fc99e Initial load
duke
parents:
diff changeset
186
a61af66fc99e Initial load
duke
parents:
diff changeset
187 //--------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
188 // LIRItem
a61af66fc99e Initial load
duke
parents:
diff changeset
189
a61af66fc99e Initial load
duke
parents:
diff changeset
190 void LIRItem::set_result(LIR_Opr opr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
191 assert(value()->operand()->is_illegal() || value()->operand()->is_constant(), "operand should never change");
a61af66fc99e Initial load
duke
parents:
diff changeset
192 value()->set_operand(opr);
a61af66fc99e Initial load
duke
parents:
diff changeset
193
a61af66fc99e Initial load
duke
parents:
diff changeset
194 if (opr->is_virtual()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
195 _gen->_instruction_for_operand.at_put_grow(opr->vreg_number(), value(), NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
196 }
a61af66fc99e Initial load
duke
parents:
diff changeset
197
a61af66fc99e Initial load
duke
parents:
diff changeset
198 _result = opr;
a61af66fc99e Initial load
duke
parents:
diff changeset
199 }
a61af66fc99e Initial load
duke
parents:
diff changeset
200
a61af66fc99e Initial load
duke
parents:
diff changeset
201 void LIRItem::load_item() {
a61af66fc99e Initial load
duke
parents:
diff changeset
202 if (result()->is_illegal()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
203 // update the items result
a61af66fc99e Initial load
duke
parents:
diff changeset
204 _result = value()->operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
205 }
a61af66fc99e Initial load
duke
parents:
diff changeset
206 if (!result()->is_register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
207 LIR_Opr reg = _gen->new_register(value()->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
208 __ move(result(), reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
209 if (result()->is_constant()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
210 _result = reg;
a61af66fc99e Initial load
duke
parents:
diff changeset
211 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
212 set_result(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
213 }
a61af66fc99e Initial load
duke
parents:
diff changeset
214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
215 }
a61af66fc99e Initial load
duke
parents:
diff changeset
216
a61af66fc99e Initial load
duke
parents:
diff changeset
217
a61af66fc99e Initial load
duke
parents:
diff changeset
218 void LIRItem::load_for_store(BasicType type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
219 if (_gen->can_store_as_constant(value(), type)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
220 _result = value()->operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
221 if (!_result->is_constant()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
222 _result = LIR_OprFact::value_type(value()->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
223 }
a61af66fc99e Initial load
duke
parents:
diff changeset
224 } else if (type == T_BYTE || type == T_BOOLEAN) {
a61af66fc99e Initial load
duke
parents:
diff changeset
225 load_byte_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
226 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
227 load_item();
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 void LIRItem::load_item_force(LIR_Opr reg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
232 LIR_Opr r = result();
a61af66fc99e Initial load
duke
parents:
diff changeset
233 if (r != reg) {
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
234 #if !defined(ARM) && !defined(E500V2)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
235 if (r->type() != reg->type()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
236 // moves between different types need an intervening spill slot
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
237 r = _gen->force_to_spill(r, reg->type());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
238 }
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
239 #endif
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
240 __ move(r, reg);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
241 _result = reg;
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 ciObject* LIRItem::get_jobject_constant() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
246 ObjectType* oc = type()->as_ObjectType();
a61af66fc99e Initial load
duke
parents:
diff changeset
247 if (oc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
248 return oc->constant_value();
a61af66fc99e Initial load
duke
parents:
diff changeset
249 }
a61af66fc99e Initial load
duke
parents:
diff changeset
250 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
251 }
a61af66fc99e Initial load
duke
parents:
diff changeset
252
a61af66fc99e Initial load
duke
parents:
diff changeset
253
a61af66fc99e Initial load
duke
parents:
diff changeset
254 jint LIRItem::get_jint_constant() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
255 assert(is_constant() && value() != NULL, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
256 assert(type()->as_IntConstant() != NULL, "type check");
a61af66fc99e Initial load
duke
parents:
diff changeset
257 return type()->as_IntConstant()->value();
a61af66fc99e Initial load
duke
parents:
diff changeset
258 }
a61af66fc99e Initial load
duke
parents:
diff changeset
259
a61af66fc99e Initial load
duke
parents:
diff changeset
260
a61af66fc99e Initial load
duke
parents:
diff changeset
261 jint LIRItem::get_address_constant() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
262 assert(is_constant() && value() != NULL, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
263 assert(type()->as_AddressConstant() != NULL, "type check");
a61af66fc99e Initial load
duke
parents:
diff changeset
264 return type()->as_AddressConstant()->value();
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 jfloat LIRItem::get_jfloat_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_FloatConstant() != NULL, "type check");
a61af66fc99e Initial load
duke
parents:
diff changeset
271 return type()->as_FloatConstant()->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 jdouble LIRItem::get_jdouble_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_DoubleConstant() != NULL, "type check");
a61af66fc99e Initial load
duke
parents:
diff changeset
278 return type()->as_DoubleConstant()->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 jlong LIRItem::get_jlong_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_LongConstant() != NULL, "type check");
a61af66fc99e Initial load
duke
parents:
diff changeset
285 return type()->as_LongConstant()->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
a61af66fc99e Initial load
duke
parents:
diff changeset
290 //--------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
291
a61af66fc99e Initial load
duke
parents:
diff changeset
292
a61af66fc99e Initial load
duke
parents:
diff changeset
293 void LIRGenerator::init() {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
294 _bs = Universe::heap()->barrier_set();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
295 }
a61af66fc99e Initial load
duke
parents:
diff changeset
296
a61af66fc99e Initial load
duke
parents:
diff changeset
297
a61af66fc99e Initial load
duke
parents:
diff changeset
298 void LIRGenerator::block_do_prolog(BlockBegin* block) {
a61af66fc99e Initial load
duke
parents:
diff changeset
299 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
300 if (PrintIRWithLIR) {
a61af66fc99e Initial load
duke
parents:
diff changeset
301 block->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
302 }
a61af66fc99e Initial load
duke
parents:
diff changeset
303 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
304
a61af66fc99e Initial load
duke
parents:
diff changeset
305 // set up the list of LIR instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
306 assert(block->lir() == NULL, "LIR list already computed for this block");
a61af66fc99e Initial load
duke
parents:
diff changeset
307 _lir = new LIR_List(compilation(), block);
a61af66fc99e Initial load
duke
parents:
diff changeset
308 block->set_lir(_lir);
a61af66fc99e Initial load
duke
parents:
diff changeset
309
a61af66fc99e Initial load
duke
parents:
diff changeset
310 __ branch_destination(block->label());
a61af66fc99e Initial load
duke
parents:
diff changeset
311
a61af66fc99e Initial load
duke
parents:
diff changeset
312 if (LIRTraceExecution &&
1584
b812ff5abc73 6958292: C1: Enable parallel compilation
iveresov
parents: 1579
diff changeset
313 Compilation::current()->hir()->start()->block_id() != block->block_id() &&
0
a61af66fc99e Initial load
duke
parents:
diff changeset
314 !block->is_set(BlockBegin::exception_entry_flag)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
315 assert(block->lir()->instructions_list()->length() == 1, "should come right after br_dst");
a61af66fc99e Initial load
duke
parents:
diff changeset
316 trace_block_entry(block);
a61af66fc99e Initial load
duke
parents:
diff changeset
317 }
a61af66fc99e Initial load
duke
parents:
diff changeset
318 }
a61af66fc99e Initial load
duke
parents:
diff changeset
319
a61af66fc99e Initial load
duke
parents:
diff changeset
320
a61af66fc99e Initial load
duke
parents:
diff changeset
321 void LIRGenerator::block_do_epilog(BlockBegin* block) {
a61af66fc99e Initial load
duke
parents:
diff changeset
322 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
323 if (PrintIRWithLIR) {
a61af66fc99e Initial load
duke
parents:
diff changeset
324 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
325 }
a61af66fc99e Initial load
duke
parents:
diff changeset
326 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
327
a61af66fc99e Initial load
duke
parents:
diff changeset
328 // LIR_Opr for unpinned constants shouldn't be referenced by other
a61af66fc99e Initial load
duke
parents:
diff changeset
329 // blocks so clear them out after processing the block.
a61af66fc99e Initial load
duke
parents:
diff changeset
330 for (int i = 0; i < _unpinned_constants.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
331 _unpinned_constants.at(i)->clear_operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
332 }
a61af66fc99e Initial load
duke
parents:
diff changeset
333 _unpinned_constants.trunc_to(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
334
a61af66fc99e Initial load
duke
parents:
diff changeset
335 // clear our any registers for other local constants
a61af66fc99e Initial load
duke
parents:
diff changeset
336 _constants.trunc_to(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
337 _reg_for_constants.trunc_to(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
338 }
a61af66fc99e Initial load
duke
parents:
diff changeset
339
a61af66fc99e Initial load
duke
parents:
diff changeset
340
a61af66fc99e Initial load
duke
parents:
diff changeset
341 void LIRGenerator::block_do(BlockBegin* block) {
a61af66fc99e Initial load
duke
parents:
diff changeset
342 CHECK_BAILOUT();
a61af66fc99e Initial load
duke
parents:
diff changeset
343
a61af66fc99e Initial load
duke
parents:
diff changeset
344 block_do_prolog(block);
a61af66fc99e Initial load
duke
parents:
diff changeset
345 set_block(block);
a61af66fc99e Initial load
duke
parents:
diff changeset
346
a61af66fc99e Initial load
duke
parents:
diff changeset
347 for (Instruction* instr = block; instr != NULL; instr = instr->next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
348 if (instr->is_pinned()) do_root(instr);
a61af66fc99e Initial load
duke
parents:
diff changeset
349 }
a61af66fc99e Initial load
duke
parents:
diff changeset
350
a61af66fc99e Initial load
duke
parents:
diff changeset
351 set_block(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
352 block_do_epilog(block);
a61af66fc99e Initial load
duke
parents:
diff changeset
353 }
a61af66fc99e Initial load
duke
parents:
diff changeset
354
a61af66fc99e Initial load
duke
parents:
diff changeset
355
a61af66fc99e Initial load
duke
parents:
diff changeset
356 //-------------------------LIRGenerator-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
357
a61af66fc99e Initial load
duke
parents:
diff changeset
358 // This is where the tree-walk starts; instr must be root;
a61af66fc99e Initial load
duke
parents:
diff changeset
359 void LIRGenerator::do_root(Value instr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
360 CHECK_BAILOUT();
a61af66fc99e Initial load
duke
parents:
diff changeset
361
a61af66fc99e Initial load
duke
parents:
diff changeset
362 InstructionMark im(compilation(), instr);
a61af66fc99e Initial load
duke
parents:
diff changeset
363
a61af66fc99e Initial load
duke
parents:
diff changeset
364 assert(instr->is_pinned(), "use only with roots");
a61af66fc99e Initial load
duke
parents:
diff changeset
365 assert(instr->subst() == instr, "shouldn't have missed substitution");
a61af66fc99e Initial load
duke
parents:
diff changeset
366
a61af66fc99e Initial load
duke
parents:
diff changeset
367 instr->visit(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
368
a61af66fc99e Initial load
duke
parents:
diff changeset
369 assert(!instr->has_uses() || instr->operand()->is_valid() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
370 instr->as_Constant() != NULL || bailed_out(), "invalid item set");
a61af66fc99e Initial load
duke
parents:
diff changeset
371 }
a61af66fc99e Initial load
duke
parents:
diff changeset
372
a61af66fc99e Initial load
duke
parents:
diff changeset
373
a61af66fc99e Initial load
duke
parents:
diff changeset
374 // This is called for each node in tree; the walk stops if a root is reached
a61af66fc99e Initial load
duke
parents:
diff changeset
375 void LIRGenerator::walk(Value instr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
376 InstructionMark im(compilation(), instr);
a61af66fc99e Initial load
duke
parents:
diff changeset
377 //stop walk when encounter a root
a61af66fc99e Initial load
duke
parents:
diff changeset
378 if (instr->is_pinned() && instr->as_Phi() == NULL || instr->operand()->is_valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
379 assert(instr->operand() != LIR_OprFact::illegalOpr || instr->as_Constant() != NULL, "this root has not yet been visited");
a61af66fc99e Initial load
duke
parents:
diff changeset
380 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
381 assert(instr->subst() == instr, "shouldn't have missed substitution");
a61af66fc99e Initial load
duke
parents:
diff changeset
382 instr->visit(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
383 // assert(instr->use_count() > 0 || instr->as_Phi() != NULL, "leaf instruction must have a use");
a61af66fc99e Initial load
duke
parents:
diff changeset
384 }
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 CodeEmitInfo* LIRGenerator::state_for(Instruction* x, ValueStack* state, bool ignore_xhandler) {
a61af66fc99e Initial load
duke
parents:
diff changeset
389 int index;
a61af66fc99e Initial load
duke
parents:
diff changeset
390 Value value;
a61af66fc99e Initial load
duke
parents:
diff changeset
391 for_each_stack_value(state, index, value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
392 assert(value->subst() == value, "missed substition");
a61af66fc99e Initial load
duke
parents:
diff changeset
393 if (!value->is_pinned() && value->as_Constant() == NULL && value->as_Local() == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
394 walk(value);
a61af66fc99e Initial load
duke
parents:
diff changeset
395 assert(value->operand()->is_valid(), "must be evaluated now");
a61af66fc99e Initial load
duke
parents:
diff changeset
396 }
a61af66fc99e Initial load
duke
parents:
diff changeset
397 }
a61af66fc99e Initial load
duke
parents:
diff changeset
398 ValueStack* s = state;
a61af66fc99e Initial load
duke
parents:
diff changeset
399 int bci = x->bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
400 for_each_state(s) {
a61af66fc99e Initial load
duke
parents:
diff changeset
401 IRScope* scope = s->scope();
a61af66fc99e Initial load
duke
parents:
diff changeset
402 ciMethod* method = scope->method();
a61af66fc99e Initial load
duke
parents:
diff changeset
403
a61af66fc99e Initial load
duke
parents:
diff changeset
404 MethodLivenessResult liveness = method->liveness_at_bci(bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
405 if (bci == SynchronizationEntryBCI) {
a61af66fc99e Initial load
duke
parents:
diff changeset
406 if (x->as_ExceptionObject() || x->as_Throw()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
407 // all locals are dead on exit from the synthetic unlocker
a61af66fc99e Initial load
duke
parents:
diff changeset
408 liveness.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
409 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
410 assert(x->as_MonitorEnter(), "only other case is MonitorEnter");
a61af66fc99e Initial load
duke
parents:
diff changeset
411 }
a61af66fc99e Initial load
duke
parents:
diff changeset
412 }
a61af66fc99e Initial load
duke
parents:
diff changeset
413 if (!liveness.is_valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
414 // Degenerate or breakpointed method.
a61af66fc99e Initial load
duke
parents:
diff changeset
415 bailout("Degenerate or breakpointed method");
a61af66fc99e Initial load
duke
parents:
diff changeset
416 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
417 assert((int)liveness.size() == s->locals_size(), "error in use of liveness");
a61af66fc99e Initial load
duke
parents:
diff changeset
418 for_each_local_value(s, index, value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
419 assert(value->subst() == value, "missed substition");
a61af66fc99e Initial load
duke
parents:
diff changeset
420 if (liveness.at(index) && !value->type()->is_illegal()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
421 if (!value->is_pinned() && value->as_Constant() == NULL && value->as_Local() == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
422 walk(value);
a61af66fc99e Initial load
duke
parents:
diff changeset
423 assert(value->operand()->is_valid(), "must be evaluated now");
a61af66fc99e Initial load
duke
parents:
diff changeset
424 }
a61af66fc99e Initial load
duke
parents:
diff changeset
425 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
426 // NULL out this local so that linear scan can assume that all non-NULL values are live.
a61af66fc99e Initial load
duke
parents:
diff changeset
427 s->invalidate_local(index);
a61af66fc99e Initial load
duke
parents:
diff changeset
428 }
a61af66fc99e Initial load
duke
parents:
diff changeset
429 }
a61af66fc99e Initial load
duke
parents:
diff changeset
430 }
a61af66fc99e Initial load
duke
parents:
diff changeset
431 bci = scope->caller_bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
432 }
a61af66fc99e Initial load
duke
parents:
diff changeset
433
a61af66fc99e Initial load
duke
parents:
diff changeset
434 return new CodeEmitInfo(x->bci(), state, ignore_xhandler ? NULL : x->exception_handlers());
a61af66fc99e Initial load
duke
parents:
diff changeset
435 }
a61af66fc99e Initial load
duke
parents:
diff changeset
436
a61af66fc99e Initial load
duke
parents:
diff changeset
437
a61af66fc99e Initial load
duke
parents:
diff changeset
438 CodeEmitInfo* LIRGenerator::state_for(Instruction* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
439 return state_for(x, x->lock_stack());
a61af66fc99e Initial load
duke
parents:
diff changeset
440 }
a61af66fc99e Initial load
duke
parents:
diff changeset
441
a61af66fc99e Initial load
duke
parents:
diff changeset
442
a61af66fc99e Initial load
duke
parents:
diff changeset
443 void LIRGenerator::jobject2reg_with_patching(LIR_Opr r, ciObject* obj, CodeEmitInfo* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
444 if (!obj->is_loaded() || PatchALot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
445 assert(info != NULL, "info must be set if class is not loaded");
a61af66fc99e Initial load
duke
parents:
diff changeset
446 __ oop2reg_patch(NULL, r, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
447 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
448 // no patching needed
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 819
diff changeset
449 __ oop2reg(obj->constant_encoding(), r);
0
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 void LIRGenerator::array_range_check(LIR_Opr array, LIR_Opr index,
a61af66fc99e Initial load
duke
parents:
diff changeset
455 CodeEmitInfo* null_check_info, CodeEmitInfo* range_check_info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
456 CodeStub* stub = new RangeCheckStub(range_check_info, index);
a61af66fc99e Initial load
duke
parents:
diff changeset
457 if (index->is_constant()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
458 cmp_mem_int(lir_cond_belowEqual, array, arrayOopDesc::length_offset_in_bytes(),
a61af66fc99e Initial load
duke
parents:
diff changeset
459 index->as_jint(), null_check_info);
a61af66fc99e Initial load
duke
parents:
diff changeset
460 __ branch(lir_cond_belowEqual, T_INT, stub); // forward branch
a61af66fc99e Initial load
duke
parents:
diff changeset
461 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
462 cmp_reg_mem(lir_cond_aboveEqual, index, array,
a61af66fc99e Initial load
duke
parents:
diff changeset
463 arrayOopDesc::length_offset_in_bytes(), T_INT, null_check_info);
a61af66fc99e Initial load
duke
parents:
diff changeset
464 __ branch(lir_cond_aboveEqual, T_INT, stub); // forward branch
a61af66fc99e Initial load
duke
parents:
diff changeset
465 }
a61af66fc99e Initial load
duke
parents:
diff changeset
466 }
a61af66fc99e Initial load
duke
parents:
diff changeset
467
a61af66fc99e Initial load
duke
parents:
diff changeset
468
a61af66fc99e Initial load
duke
parents:
diff changeset
469 void LIRGenerator::nio_range_check(LIR_Opr buffer, LIR_Opr index, LIR_Opr result, CodeEmitInfo* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
470 CodeStub* stub = new RangeCheckStub(info, index, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
471 if (index->is_constant()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
472 cmp_mem_int(lir_cond_belowEqual, buffer, java_nio_Buffer::limit_offset(), index->as_jint(), info);
a61af66fc99e Initial load
duke
parents:
diff changeset
473 __ branch(lir_cond_belowEqual, T_INT, stub); // forward branch
a61af66fc99e Initial load
duke
parents:
diff changeset
474 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
475 cmp_reg_mem(lir_cond_aboveEqual, index, buffer,
a61af66fc99e Initial load
duke
parents:
diff changeset
476 java_nio_Buffer::limit_offset(), T_INT, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
477 __ branch(lir_cond_aboveEqual, T_INT, stub); // forward branch
a61af66fc99e Initial load
duke
parents:
diff changeset
478 }
a61af66fc99e Initial load
duke
parents:
diff changeset
479 __ move(index, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
480 }
a61af66fc99e Initial load
duke
parents:
diff changeset
481
a61af66fc99e Initial load
duke
parents:
diff changeset
482
a61af66fc99e Initial load
duke
parents:
diff changeset
483 // increment a counter returning the incremented value
a61af66fc99e Initial load
duke
parents:
diff changeset
484 LIR_Opr LIRGenerator::increment_and_return_counter(LIR_Opr base, int offset, int increment) {
a61af66fc99e Initial load
duke
parents:
diff changeset
485 LIR_Address* counter = new LIR_Address(base, offset, T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
486 LIR_Opr result = new_register(T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
487 __ load(counter, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
488 __ add(result, LIR_OprFact::intConst(increment), result);
a61af66fc99e Initial load
duke
parents:
diff changeset
489 __ store(result, counter);
a61af66fc99e Initial load
duke
parents:
diff changeset
490 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
491 }
a61af66fc99e Initial load
duke
parents:
diff changeset
492
a61af66fc99e Initial load
duke
parents:
diff changeset
493
a61af66fc99e Initial load
duke
parents:
diff changeset
494 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
495 LIR_Opr result_op = result;
a61af66fc99e Initial load
duke
parents:
diff changeset
496 LIR_Opr left_op = left;
a61af66fc99e Initial load
duke
parents:
diff changeset
497 LIR_Opr right_op = right;
a61af66fc99e Initial load
duke
parents:
diff changeset
498
a61af66fc99e Initial load
duke
parents:
diff changeset
499 if (TwoOperandLIRForm && left_op != result_op) {
a61af66fc99e Initial load
duke
parents:
diff changeset
500 assert(right_op != result_op, "malformed");
a61af66fc99e Initial load
duke
parents:
diff changeset
501 __ move(left_op, result_op);
a61af66fc99e Initial load
duke
parents:
diff changeset
502 left_op = result_op;
a61af66fc99e Initial load
duke
parents:
diff changeset
503 }
a61af66fc99e Initial load
duke
parents:
diff changeset
504
a61af66fc99e Initial load
duke
parents:
diff changeset
505 switch(code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
506 case Bytecodes::_dadd:
a61af66fc99e Initial load
duke
parents:
diff changeset
507 case Bytecodes::_fadd:
a61af66fc99e Initial load
duke
parents:
diff changeset
508 case Bytecodes::_ladd:
a61af66fc99e Initial load
duke
parents:
diff changeset
509 case Bytecodes::_iadd: __ add(left_op, right_op, result_op); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
510 case Bytecodes::_fmul:
a61af66fc99e Initial load
duke
parents:
diff changeset
511 case Bytecodes::_lmul: __ mul(left_op, right_op, result_op); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
512
a61af66fc99e Initial load
duke
parents:
diff changeset
513 case Bytecodes::_dmul:
a61af66fc99e Initial load
duke
parents:
diff changeset
514 {
a61af66fc99e Initial load
duke
parents:
diff changeset
515 if (is_strictfp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
516 __ mul_strictfp(left_op, right_op, result_op, tmp_op); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
517 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
518 __ mul(left_op, right_op, result_op); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
519 }
a61af66fc99e Initial load
duke
parents:
diff changeset
520 }
a61af66fc99e Initial load
duke
parents:
diff changeset
521 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
522
a61af66fc99e Initial load
duke
parents:
diff changeset
523 case Bytecodes::_imul:
a61af66fc99e Initial load
duke
parents:
diff changeset
524 {
a61af66fc99e Initial load
duke
parents:
diff changeset
525 bool did_strength_reduce = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
526
a61af66fc99e Initial load
duke
parents:
diff changeset
527 if (right->is_constant()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
528 int c = right->as_jint();
a61af66fc99e Initial load
duke
parents:
diff changeset
529 if (is_power_of_2(c)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
530 // do not need tmp here
a61af66fc99e Initial load
duke
parents:
diff changeset
531 __ shift_left(left_op, exact_log2(c), result_op);
a61af66fc99e Initial load
duke
parents:
diff changeset
532 did_strength_reduce = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
533 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
534 did_strength_reduce = strength_reduce_multiply(left_op, c, result_op, tmp_op);
a61af66fc99e Initial load
duke
parents:
diff changeset
535 }
a61af66fc99e Initial load
duke
parents:
diff changeset
536 }
a61af66fc99e Initial load
duke
parents:
diff changeset
537 // we couldn't strength reduce so just emit the multiply
a61af66fc99e Initial load
duke
parents:
diff changeset
538 if (!did_strength_reduce) {
a61af66fc99e Initial load
duke
parents:
diff changeset
539 __ mul(left_op, right_op, result_op);
a61af66fc99e Initial load
duke
parents:
diff changeset
540 }
a61af66fc99e Initial load
duke
parents:
diff changeset
541 }
a61af66fc99e Initial load
duke
parents:
diff changeset
542 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
543
a61af66fc99e Initial load
duke
parents:
diff changeset
544 case Bytecodes::_dsub:
a61af66fc99e Initial load
duke
parents:
diff changeset
545 case Bytecodes::_fsub:
a61af66fc99e Initial load
duke
parents:
diff changeset
546 case Bytecodes::_lsub:
a61af66fc99e Initial load
duke
parents:
diff changeset
547 case Bytecodes::_isub: __ sub(left_op, right_op, result_op); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
548
a61af66fc99e Initial load
duke
parents:
diff changeset
549 case Bytecodes::_fdiv: __ div (left_op, right_op, result_op); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
550 // ldiv and lrem are implemented with a direct runtime call
a61af66fc99e Initial load
duke
parents:
diff changeset
551
a61af66fc99e Initial load
duke
parents:
diff changeset
552 case Bytecodes::_ddiv:
a61af66fc99e Initial load
duke
parents:
diff changeset
553 {
a61af66fc99e Initial load
duke
parents:
diff changeset
554 if (is_strictfp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
555 __ div_strictfp (left_op, right_op, result_op, tmp_op); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
556 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
557 __ div (left_op, right_op, result_op); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
558 }
a61af66fc99e Initial load
duke
parents:
diff changeset
559 }
a61af66fc99e Initial load
duke
parents:
diff changeset
560 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
561
a61af66fc99e Initial load
duke
parents:
diff changeset
562 case Bytecodes::_drem:
a61af66fc99e Initial load
duke
parents:
diff changeset
563 case Bytecodes::_frem: __ rem (left_op, right_op, result_op); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
564
a61af66fc99e Initial load
duke
parents:
diff changeset
565 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
566 }
a61af66fc99e Initial load
duke
parents:
diff changeset
567 }
a61af66fc99e Initial load
duke
parents:
diff changeset
568
a61af66fc99e Initial load
duke
parents:
diff changeset
569
a61af66fc99e Initial load
duke
parents:
diff changeset
570 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
571 arithmetic_op(code, result, left, right, false, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
572 }
a61af66fc99e Initial load
duke
parents:
diff changeset
573
a61af66fc99e Initial load
duke
parents:
diff changeset
574
a61af66fc99e Initial load
duke
parents:
diff changeset
575 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
576 arithmetic_op(code, result, left, right, false, LIR_OprFact::illegalOpr, info);
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 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
581 arithmetic_op(code, result, left, right, is_strictfp, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
582 }
a61af66fc99e Initial load
duke
parents:
diff changeset
583
a61af66fc99e Initial load
duke
parents:
diff changeset
584
a61af66fc99e Initial load
duke
parents:
diff changeset
585 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
586 if (TwoOperandLIRForm && value != result_op) {
a61af66fc99e Initial load
duke
parents:
diff changeset
587 assert(count != result_op, "malformed");
a61af66fc99e Initial load
duke
parents:
diff changeset
588 __ move(value, result_op);
a61af66fc99e Initial load
duke
parents:
diff changeset
589 value = result_op;
a61af66fc99e Initial load
duke
parents:
diff changeset
590 }
a61af66fc99e Initial load
duke
parents:
diff changeset
591
a61af66fc99e Initial load
duke
parents:
diff changeset
592 assert(count->is_constant() || count->is_register(), "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
593 switch(code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
594 case Bytecodes::_ishl:
a61af66fc99e Initial load
duke
parents:
diff changeset
595 case Bytecodes::_lshl: __ shift_left(value, count, result_op, tmp); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
596 case Bytecodes::_ishr:
a61af66fc99e Initial load
duke
parents:
diff changeset
597 case Bytecodes::_lshr: __ shift_right(value, count, result_op, tmp); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
598 case Bytecodes::_iushr:
a61af66fc99e Initial load
duke
parents:
diff changeset
599 case Bytecodes::_lushr: __ unsigned_shift_right(value, count, result_op, tmp); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
600 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
601 }
a61af66fc99e Initial load
duke
parents:
diff changeset
602 }
a61af66fc99e Initial load
duke
parents:
diff changeset
603
a61af66fc99e Initial load
duke
parents:
diff changeset
604
a61af66fc99e Initial load
duke
parents:
diff changeset
605 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
606 if (TwoOperandLIRForm && left_op != result_op) {
a61af66fc99e Initial load
duke
parents:
diff changeset
607 assert(right_op != result_op, "malformed");
a61af66fc99e Initial load
duke
parents:
diff changeset
608 __ move(left_op, result_op);
a61af66fc99e Initial load
duke
parents:
diff changeset
609 left_op = result_op;
a61af66fc99e Initial load
duke
parents:
diff changeset
610 }
a61af66fc99e Initial load
duke
parents:
diff changeset
611
a61af66fc99e Initial load
duke
parents:
diff changeset
612 switch(code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
613 case Bytecodes::_iand:
a61af66fc99e Initial load
duke
parents:
diff changeset
614 case Bytecodes::_land: __ logical_and(left_op, right_op, result_op); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
615
a61af66fc99e Initial load
duke
parents:
diff changeset
616 case Bytecodes::_ior:
a61af66fc99e Initial load
duke
parents:
diff changeset
617 case Bytecodes::_lor: __ logical_or(left_op, right_op, result_op); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
618
a61af66fc99e Initial load
duke
parents:
diff changeset
619 case Bytecodes::_ixor:
a61af66fc99e Initial load
duke
parents:
diff changeset
620 case Bytecodes::_lxor: __ logical_xor(left_op, right_op, result_op); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
621
a61af66fc99e Initial load
duke
parents:
diff changeset
622 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
623 }
a61af66fc99e Initial load
duke
parents:
diff changeset
624 }
a61af66fc99e Initial load
duke
parents:
diff changeset
625
a61af66fc99e Initial load
duke
parents:
diff changeset
626
a61af66fc99e Initial load
duke
parents:
diff changeset
627 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
628 if (!GenerateSynchronizationCode) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
629 // for slow path, use debug info for state after successful locking
a61af66fc99e Initial load
duke
parents:
diff changeset
630 CodeStub* slow_path = new MonitorEnterStub(object, lock, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
631 __ load_stack_address_monitor(monitor_no, lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
632 // for handling NullPointerException, use debug info representing just the lock stack before this monitorenter
a61af66fc99e Initial load
duke
parents:
diff changeset
633 __ lock_object(hdr, object, lock, scratch, slow_path, info_for_exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
634 }
a61af66fc99e Initial load
duke
parents:
diff changeset
635
a61af66fc99e Initial load
duke
parents:
diff changeset
636
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
637 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
638 if (!GenerateSynchronizationCode) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
639 // setup registers
a61af66fc99e Initial load
duke
parents:
diff changeset
640 LIR_Opr hdr = lock;
a61af66fc99e Initial load
duke
parents:
diff changeset
641 lock = new_hdr;
a61af66fc99e Initial load
duke
parents:
diff changeset
642 CodeStub* slow_path = new MonitorExitStub(lock, UseFastLocking, monitor_no);
a61af66fc99e Initial load
duke
parents:
diff changeset
643 __ load_stack_address_monitor(monitor_no, lock);
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
644 __ unlock_object(hdr, object, lock, scratch, slow_path);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
645 }
a61af66fc99e Initial load
duke
parents:
diff changeset
646
a61af66fc99e Initial load
duke
parents:
diff changeset
647
a61af66fc99e Initial load
duke
parents:
diff changeset
648 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
649 jobject2reg_with_patching(klass_reg, klass, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
650 // If klass is not loaded we do not know if the klass has finalizers:
a61af66fc99e Initial load
duke
parents:
diff changeset
651 if (UseFastNewInstance && klass->is_loaded()
a61af66fc99e Initial load
duke
parents:
diff changeset
652 && !Klass::layout_helper_needs_slow_path(klass->layout_helper())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
653
a61af66fc99e Initial load
duke
parents:
diff changeset
654 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
655
a61af66fc99e Initial load
duke
parents:
diff changeset
656 CodeStub* slow_path = new NewInstanceStub(klass_reg, dst, klass, info, stub_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
657
a61af66fc99e Initial load
duke
parents:
diff changeset
658 assert(klass->is_loaded(), "must be loaded");
a61af66fc99e Initial load
duke
parents:
diff changeset
659 // allocate space for instance
a61af66fc99e Initial load
duke
parents:
diff changeset
660 assert(klass->size_helper() >= 0, "illegal instance size");
a61af66fc99e Initial load
duke
parents:
diff changeset
661 const int instance_size = align_object_size(klass->size_helper());
a61af66fc99e Initial load
duke
parents:
diff changeset
662 __ allocate_object(dst, scratch1, scratch2, scratch3, scratch4,
a61af66fc99e Initial load
duke
parents:
diff changeset
663 oopDesc::header_size(), instance_size, klass_reg, !klass->is_initialized(), slow_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
664 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
665 CodeStub* slow_path = new NewInstanceStub(klass_reg, dst, klass, info, Runtime1::new_instance_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
666 __ branch(lir_cond_always, T_ILLEGAL, slow_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
667 __ branch_destination(slow_path->continuation());
a61af66fc99e Initial load
duke
parents:
diff changeset
668 }
a61af66fc99e Initial load
duke
parents:
diff changeset
669 }
a61af66fc99e Initial load
duke
parents:
diff changeset
670
a61af66fc99e Initial load
duke
parents:
diff changeset
671
a61af66fc99e Initial load
duke
parents:
diff changeset
672 static bool is_constant_zero(Instruction* inst) {
a61af66fc99e Initial load
duke
parents:
diff changeset
673 IntConstant* c = inst->type()->as_IntConstant();
a61af66fc99e Initial load
duke
parents:
diff changeset
674 if (c) {
a61af66fc99e Initial load
duke
parents:
diff changeset
675 return (c->value() == 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
676 }
a61af66fc99e Initial load
duke
parents:
diff changeset
677 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
678 }
a61af66fc99e Initial load
duke
parents:
diff changeset
679
a61af66fc99e Initial load
duke
parents:
diff changeset
680
a61af66fc99e Initial load
duke
parents:
diff changeset
681 static bool positive_constant(Instruction* inst) {
a61af66fc99e Initial load
duke
parents:
diff changeset
682 IntConstant* c = inst->type()->as_IntConstant();
a61af66fc99e Initial load
duke
parents:
diff changeset
683 if (c) {
a61af66fc99e Initial load
duke
parents:
diff changeset
684 return (c->value() >= 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
685 }
a61af66fc99e Initial load
duke
parents:
diff changeset
686 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
687 }
a61af66fc99e Initial load
duke
parents:
diff changeset
688
a61af66fc99e Initial load
duke
parents:
diff changeset
689
a61af66fc99e Initial load
duke
parents:
diff changeset
690 static ciArrayKlass* as_array_klass(ciType* type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
691 if (type != NULL && type->is_array_klass() && type->is_loaded()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
692 return (ciArrayKlass*)type;
a61af66fc99e Initial load
duke
parents:
diff changeset
693 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
694 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
695 }
a61af66fc99e Initial load
duke
parents:
diff changeset
696 }
a61af66fc99e Initial load
duke
parents:
diff changeset
697
a61af66fc99e Initial load
duke
parents:
diff changeset
698 void LIRGenerator::arraycopy_helper(Intrinsic* x, int* flagsp, ciArrayKlass** expected_typep) {
a61af66fc99e Initial load
duke
parents:
diff changeset
699 Instruction* src = x->argument_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
700 Instruction* src_pos = x->argument_at(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
701 Instruction* dst = x->argument_at(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
702 Instruction* dst_pos = x->argument_at(3);
a61af66fc99e Initial load
duke
parents:
diff changeset
703 Instruction* length = x->argument_at(4);
a61af66fc99e Initial load
duke
parents:
diff changeset
704
a61af66fc99e Initial load
duke
parents:
diff changeset
705 // first try to identify the likely type of the arrays involved
a61af66fc99e Initial load
duke
parents:
diff changeset
706 ciArrayKlass* expected_type = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
707 bool is_exact = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
708 {
a61af66fc99e Initial load
duke
parents:
diff changeset
709 ciArrayKlass* src_exact_type = as_array_klass(src->exact_type());
a61af66fc99e Initial load
duke
parents:
diff changeset
710 ciArrayKlass* src_declared_type = as_array_klass(src->declared_type());
a61af66fc99e Initial load
duke
parents:
diff changeset
711 ciArrayKlass* dst_exact_type = as_array_klass(dst->exact_type());
a61af66fc99e Initial load
duke
parents:
diff changeset
712 ciArrayKlass* dst_declared_type = as_array_klass(dst->declared_type());
a61af66fc99e Initial load
duke
parents:
diff changeset
713 if (src_exact_type != NULL && src_exact_type == dst_exact_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
714 // the types exactly match so the type is fully known
a61af66fc99e Initial load
duke
parents:
diff changeset
715 is_exact = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
716 expected_type = src_exact_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
717 } else if (dst_exact_type != NULL && dst_exact_type->is_obj_array_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
718 ciArrayKlass* dst_type = (ciArrayKlass*) dst_exact_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
719 ciArrayKlass* src_type = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
720 if (src_exact_type != NULL && src_exact_type->is_obj_array_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
721 src_type = (ciArrayKlass*) src_exact_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
722 } else if (src_declared_type != NULL && src_declared_type->is_obj_array_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
723 src_type = (ciArrayKlass*) src_declared_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
724 }
a61af66fc99e Initial load
duke
parents:
diff changeset
725 if (src_type != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
726 if (src_type->element_type()->is_subtype_of(dst_type->element_type())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
727 is_exact = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
728 expected_type = dst_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
729 }
a61af66fc99e Initial load
duke
parents:
diff changeset
730 }
a61af66fc99e Initial load
duke
parents:
diff changeset
731 }
a61af66fc99e Initial load
duke
parents:
diff changeset
732 // at least pass along a good guess
a61af66fc99e Initial load
duke
parents:
diff changeset
733 if (expected_type == NULL) expected_type = dst_exact_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
734 if (expected_type == NULL) expected_type = src_declared_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
735 if (expected_type == NULL) expected_type = dst_declared_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
736 }
a61af66fc99e Initial load
duke
parents:
diff changeset
737
a61af66fc99e Initial load
duke
parents:
diff changeset
738 // if a probable array type has been identified, figure out if any
a61af66fc99e Initial load
duke
parents:
diff changeset
739 // of the required checks for a fast case can be elided.
a61af66fc99e Initial load
duke
parents:
diff changeset
740 int flags = LIR_OpArrayCopy::all_flags;
a61af66fc99e Initial load
duke
parents:
diff changeset
741 if (expected_type != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
742 // try to skip null checks
a61af66fc99e Initial load
duke
parents:
diff changeset
743 if (src->as_NewArray() != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
744 flags &= ~LIR_OpArrayCopy::src_null_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
745 if (dst->as_NewArray() != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
746 flags &= ~LIR_OpArrayCopy::dst_null_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
747
a61af66fc99e Initial load
duke
parents:
diff changeset
748 // check from incoming constant values
a61af66fc99e Initial load
duke
parents:
diff changeset
749 if (positive_constant(src_pos))
a61af66fc99e Initial load
duke
parents:
diff changeset
750 flags &= ~LIR_OpArrayCopy::src_pos_positive_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
751 if (positive_constant(dst_pos))
a61af66fc99e Initial load
duke
parents:
diff changeset
752 flags &= ~LIR_OpArrayCopy::dst_pos_positive_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
753 if (positive_constant(length))
a61af66fc99e Initial load
duke
parents:
diff changeset
754 flags &= ~LIR_OpArrayCopy::length_positive_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
755
a61af66fc99e Initial load
duke
parents:
diff changeset
756 // see if the range check can be elided, which might also imply
a61af66fc99e Initial load
duke
parents:
diff changeset
757 // that src or dst is non-null.
a61af66fc99e Initial load
duke
parents:
diff changeset
758 ArrayLength* al = length->as_ArrayLength();
a61af66fc99e Initial load
duke
parents:
diff changeset
759 if (al != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
760 if (al->array() == src) {
a61af66fc99e Initial load
duke
parents:
diff changeset
761 // it's the length of the source array
a61af66fc99e Initial load
duke
parents:
diff changeset
762 flags &= ~LIR_OpArrayCopy::length_positive_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
763 flags &= ~LIR_OpArrayCopy::src_null_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
764 if (is_constant_zero(src_pos))
a61af66fc99e Initial load
duke
parents:
diff changeset
765 flags &= ~LIR_OpArrayCopy::src_range_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
766 }
a61af66fc99e Initial load
duke
parents:
diff changeset
767 if (al->array() == dst) {
a61af66fc99e Initial load
duke
parents:
diff changeset
768 // it's the length of the destination array
a61af66fc99e Initial load
duke
parents:
diff changeset
769 flags &= ~LIR_OpArrayCopy::length_positive_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
770 flags &= ~LIR_OpArrayCopy::dst_null_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
771 if (is_constant_zero(dst_pos))
a61af66fc99e Initial load
duke
parents:
diff changeset
772 flags &= ~LIR_OpArrayCopy::dst_range_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
773 }
a61af66fc99e Initial load
duke
parents:
diff changeset
774 }
a61af66fc99e Initial load
duke
parents:
diff changeset
775 if (is_exact) {
a61af66fc99e Initial load
duke
parents:
diff changeset
776 flags &= ~LIR_OpArrayCopy::type_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
777 }
a61af66fc99e Initial load
duke
parents:
diff changeset
778 }
a61af66fc99e Initial load
duke
parents:
diff changeset
779
a61af66fc99e Initial load
duke
parents:
diff changeset
780 if (src == dst) {
a61af66fc99e Initial load
duke
parents:
diff changeset
781 // moving within a single array so no type checks are needed
a61af66fc99e Initial load
duke
parents:
diff changeset
782 if (flags & LIR_OpArrayCopy::type_check) {
a61af66fc99e Initial load
duke
parents:
diff changeset
783 flags &= ~LIR_OpArrayCopy::type_check;
a61af66fc99e Initial load
duke
parents:
diff changeset
784 }
a61af66fc99e Initial load
duke
parents:
diff changeset
785 }
a61af66fc99e Initial load
duke
parents:
diff changeset
786 *flagsp = flags;
a61af66fc99e Initial load
duke
parents:
diff changeset
787 *expected_typep = (ciArrayKlass*)expected_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
788 }
a61af66fc99e Initial load
duke
parents:
diff changeset
789
a61af66fc99e Initial load
duke
parents:
diff changeset
790
a61af66fc99e Initial load
duke
parents:
diff changeset
791 LIR_Opr LIRGenerator::round_item(LIR_Opr opr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
792 assert(opr->is_register(), "why spill if item is not register?");
a61af66fc99e Initial load
duke
parents:
diff changeset
793
a61af66fc99e Initial load
duke
parents:
diff changeset
794 if (RoundFPResults && UseSSE < 1 && opr->is_single_fpu()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
795 LIR_Opr result = new_register(T_FLOAT);
a61af66fc99e Initial load
duke
parents:
diff changeset
796 set_vreg_flag(result, must_start_in_memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
797 assert(opr->is_register(), "only a register can be spilled");
a61af66fc99e Initial load
duke
parents:
diff changeset
798 assert(opr->value_type()->is_float(), "rounding only for floats available");
a61af66fc99e Initial load
duke
parents:
diff changeset
799 __ roundfp(opr, LIR_OprFact::illegalOpr, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
800 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
801 }
a61af66fc99e Initial load
duke
parents:
diff changeset
802 return opr;
a61af66fc99e Initial load
duke
parents:
diff changeset
803 }
a61af66fc99e Initial load
duke
parents:
diff changeset
804
a61af66fc99e Initial load
duke
parents:
diff changeset
805
a61af66fc99e Initial load
duke
parents:
diff changeset
806 LIR_Opr LIRGenerator::force_to_spill(LIR_Opr value, BasicType t) {
a61af66fc99e Initial load
duke
parents:
diff changeset
807 assert(type2size[t] == type2size[value->type()], "size mismatch");
a61af66fc99e Initial load
duke
parents:
diff changeset
808 if (!value->is_register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
809 // force into a register
a61af66fc99e Initial load
duke
parents:
diff changeset
810 LIR_Opr r = new_register(value->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
811 __ move(value, r);
a61af66fc99e Initial load
duke
parents:
diff changeset
812 value = r;
a61af66fc99e Initial load
duke
parents:
diff changeset
813 }
a61af66fc99e Initial load
duke
parents:
diff changeset
814
a61af66fc99e Initial load
duke
parents:
diff changeset
815 // create a spill location
a61af66fc99e Initial load
duke
parents:
diff changeset
816 LIR_Opr tmp = new_register(t);
a61af66fc99e Initial load
duke
parents:
diff changeset
817 set_vreg_flag(tmp, LIRGenerator::must_start_in_memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
818
a61af66fc99e Initial load
duke
parents:
diff changeset
819 // move from register to spill
a61af66fc99e Initial load
duke
parents:
diff changeset
820 __ move(value, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
821 return tmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
822 }
a61af66fc99e Initial load
duke
parents:
diff changeset
823
a61af66fc99e Initial load
duke
parents:
diff changeset
824
a61af66fc99e Initial load
duke
parents:
diff changeset
825 void LIRGenerator::profile_branch(If* if_instr, If::Condition cond) {
a61af66fc99e Initial load
duke
parents:
diff changeset
826 if (if_instr->should_profile()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
827 ciMethod* method = if_instr->profiled_method();
a61af66fc99e Initial load
duke
parents:
diff changeset
828 assert(method != NULL, "method should be set if branch is profiled");
a61af66fc99e Initial load
duke
parents:
diff changeset
829 ciMethodData* md = method->method_data();
a61af66fc99e Initial load
duke
parents:
diff changeset
830 if (md == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
831 bailout("out of memory building methodDataOop");
a61af66fc99e Initial load
duke
parents:
diff changeset
832 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
833 }
a61af66fc99e Initial load
duke
parents:
diff changeset
834 ciProfileData* data = md->bci_to_data(if_instr->profiled_bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
835 assert(data != NULL, "must have profiling data");
a61af66fc99e Initial load
duke
parents:
diff changeset
836 assert(data->is_BranchData(), "need BranchData for two-way branches");
a61af66fc99e Initial load
duke
parents:
diff changeset
837 int taken_count_offset = md->byte_offset_of_slot(data, BranchData::taken_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
838 int not_taken_count_offset = md->byte_offset_of_slot(data, BranchData::not_taken_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
839 LIR_Opr md_reg = new_register(T_OBJECT);
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 819
diff changeset
840 __ move(LIR_OprFact::oopConst(md->constant_encoding()), md_reg);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
841 LIR_Opr data_offset_reg = new_register(T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
842 __ cmove(lir_cond(cond),
a61af66fc99e Initial load
duke
parents:
diff changeset
843 LIR_OprFact::intConst(taken_count_offset),
a61af66fc99e Initial load
duke
parents:
diff changeset
844 LIR_OprFact::intConst(not_taken_count_offset),
a61af66fc99e Initial load
duke
parents:
diff changeset
845 data_offset_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
846 LIR_Opr data_reg = new_register(T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
847 LIR_Address* data_addr = new LIR_Address(md_reg, data_offset_reg, T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
848 __ move(LIR_OprFact::address(data_addr), data_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
849 LIR_Address* fake_incr_value = new LIR_Address(data_reg, DataLayout::counter_increment, T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
850 // Use leal instead of add to avoid destroying condition codes on x86
a61af66fc99e Initial load
duke
parents:
diff changeset
851 __ leal(LIR_OprFact::address(fake_incr_value), data_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
852 __ move(data_reg, LIR_OprFact::address(data_addr));
a61af66fc99e Initial load
duke
parents:
diff changeset
853 }
a61af66fc99e Initial load
duke
parents:
diff changeset
854 }
a61af66fc99e Initial load
duke
parents:
diff changeset
855
a61af66fc99e Initial load
duke
parents:
diff changeset
856
a61af66fc99e Initial load
duke
parents:
diff changeset
857 // Phi technique:
a61af66fc99e Initial load
duke
parents:
diff changeset
858 // This is about passing live values from one basic block to the other.
a61af66fc99e Initial load
duke
parents:
diff changeset
859 // In code generated with Java it is rather rare that more than one
a61af66fc99e Initial load
duke
parents:
diff changeset
860 // value is on the stack from one basic block to the other.
a61af66fc99e Initial load
duke
parents:
diff changeset
861 // We optimize our technique for efficient passing of one value
a61af66fc99e Initial load
duke
parents:
diff changeset
862 // (of type long, int, double..) but it can be extended.
a61af66fc99e Initial load
duke
parents:
diff changeset
863 // When entering or leaving a basic block, all registers and all spill
a61af66fc99e Initial load
duke
parents:
diff changeset
864 // slots are release and empty. We use the released registers
a61af66fc99e Initial load
duke
parents:
diff changeset
865 // and spill slots to pass the live values from one block
a61af66fc99e Initial load
duke
parents:
diff changeset
866 // to the other. The topmost value, i.e., the value on TOS of expression
a61af66fc99e Initial load
duke
parents:
diff changeset
867 // stack is passed in registers. All other values are stored in spilling
a61af66fc99e Initial load
duke
parents:
diff changeset
868 // area. Every Phi has an index which designates its spill slot
a61af66fc99e Initial load
duke
parents:
diff changeset
869 // At exit of a basic block, we fill the register(s) and spill slots.
a61af66fc99e Initial load
duke
parents:
diff changeset
870 // At entry of a basic block, the block_prolog sets up the content of phi nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
871 // and locks necessary registers and spilling slots.
a61af66fc99e Initial load
duke
parents:
diff changeset
872
a61af66fc99e Initial load
duke
parents:
diff changeset
873
a61af66fc99e Initial load
duke
parents:
diff changeset
874 // move current value to referenced phi function
a61af66fc99e Initial load
duke
parents:
diff changeset
875 void LIRGenerator::move_to_phi(PhiResolver* resolver, Value cur_val, Value sux_val) {
a61af66fc99e Initial load
duke
parents:
diff changeset
876 Phi* phi = sux_val->as_Phi();
a61af66fc99e Initial load
duke
parents:
diff changeset
877 // cur_val can be null without phi being null in conjunction with inlining
a61af66fc99e Initial load
duke
parents:
diff changeset
878 if (phi != NULL && cur_val != NULL && cur_val != phi && !phi->is_illegal()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
879 LIR_Opr operand = cur_val->operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
880 if (cur_val->operand()->is_illegal()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
881 assert(cur_val->as_Constant() != NULL || cur_val->as_Local() != NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
882 "these can be produced lazily");
a61af66fc99e Initial load
duke
parents:
diff changeset
883 operand = operand_for_instruction(cur_val);
a61af66fc99e Initial load
duke
parents:
diff changeset
884 }
a61af66fc99e Initial load
duke
parents:
diff changeset
885 resolver->move(operand, operand_for_instruction(phi));
a61af66fc99e Initial load
duke
parents:
diff changeset
886 }
a61af66fc99e Initial load
duke
parents:
diff changeset
887 }
a61af66fc99e Initial load
duke
parents:
diff changeset
888
a61af66fc99e Initial load
duke
parents:
diff changeset
889
a61af66fc99e Initial load
duke
parents:
diff changeset
890 // Moves all stack values into their PHI position
a61af66fc99e Initial load
duke
parents:
diff changeset
891 void LIRGenerator::move_to_phi(ValueStack* cur_state) {
a61af66fc99e Initial load
duke
parents:
diff changeset
892 BlockBegin* bb = block();
a61af66fc99e Initial load
duke
parents:
diff changeset
893 if (bb->number_of_sux() == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
894 BlockBegin* sux = bb->sux_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
895 assert(sux->number_of_preds() > 0, "invalid CFG");
a61af66fc99e Initial load
duke
parents:
diff changeset
896
a61af66fc99e Initial load
duke
parents:
diff changeset
897 // a block with only one predecessor never has phi functions
a61af66fc99e Initial load
duke
parents:
diff changeset
898 if (sux->number_of_preds() > 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
899 int max_phis = cur_state->stack_size() + cur_state->locals_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
900 PhiResolver resolver(this, _virtual_register_number + max_phis * 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
901
a61af66fc99e Initial load
duke
parents:
diff changeset
902 ValueStack* sux_state = sux->state();
a61af66fc99e Initial load
duke
parents:
diff changeset
903 Value sux_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
904 int index;
a61af66fc99e Initial load
duke
parents:
diff changeset
905
a61af66fc99e Initial load
duke
parents:
diff changeset
906 for_each_stack_value(sux_state, index, sux_value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
907 move_to_phi(&resolver, cur_state->stack_at(index), sux_value);
a61af66fc99e Initial load
duke
parents:
diff changeset
908 }
a61af66fc99e Initial load
duke
parents:
diff changeset
909
a61af66fc99e Initial load
duke
parents:
diff changeset
910 // Inlining may cause the local state not to match up, so walk up
a61af66fc99e Initial load
duke
parents:
diff changeset
911 // the caller state until we get to the same scope as the
a61af66fc99e Initial load
duke
parents:
diff changeset
912 // successor and then start processing from there.
a61af66fc99e Initial load
duke
parents:
diff changeset
913 while (cur_state->scope() != sux_state->scope()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
914 cur_state = cur_state->caller_state();
a61af66fc99e Initial load
duke
parents:
diff changeset
915 assert(cur_state != NULL, "scopes don't match up");
a61af66fc99e Initial load
duke
parents:
diff changeset
916 }
a61af66fc99e Initial load
duke
parents:
diff changeset
917
a61af66fc99e Initial load
duke
parents:
diff changeset
918 for_each_local_value(sux_state, index, sux_value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
919 move_to_phi(&resolver, cur_state->local_at(index), sux_value);
a61af66fc99e Initial load
duke
parents:
diff changeset
920 }
a61af66fc99e Initial load
duke
parents:
diff changeset
921
a61af66fc99e Initial load
duke
parents:
diff changeset
922 assert(cur_state->caller_state() == sux_state->caller_state(), "caller states must be equal");
a61af66fc99e Initial load
duke
parents:
diff changeset
923 }
a61af66fc99e Initial load
duke
parents:
diff changeset
924 }
a61af66fc99e Initial load
duke
parents:
diff changeset
925 }
a61af66fc99e Initial load
duke
parents:
diff changeset
926
a61af66fc99e Initial load
duke
parents:
diff changeset
927
a61af66fc99e Initial load
duke
parents:
diff changeset
928 LIR_Opr LIRGenerator::new_register(BasicType type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
929 int vreg = _virtual_register_number;
a61af66fc99e Initial load
duke
parents:
diff changeset
930 // add a little fudge factor for the bailout, since the bailout is
a61af66fc99e Initial load
duke
parents:
diff changeset
931 // only checked periodically. This gives a few extra registers to
a61af66fc99e Initial load
duke
parents:
diff changeset
932 // hand out before we really run out, which helps us keep from
a61af66fc99e Initial load
duke
parents:
diff changeset
933 // tripping over assertions.
a61af66fc99e Initial load
duke
parents:
diff changeset
934 if (vreg + 20 >= LIR_OprDesc::vreg_max) {
a61af66fc99e Initial load
duke
parents:
diff changeset
935 bailout("out of virtual registers");
a61af66fc99e Initial load
duke
parents:
diff changeset
936 if (vreg + 2 >= LIR_OprDesc::vreg_max) {
a61af66fc99e Initial load
duke
parents:
diff changeset
937 // wrap it around
a61af66fc99e Initial load
duke
parents:
diff changeset
938 _virtual_register_number = LIR_OprDesc::vreg_base;
a61af66fc99e Initial load
duke
parents:
diff changeset
939 }
a61af66fc99e Initial load
duke
parents:
diff changeset
940 }
a61af66fc99e Initial load
duke
parents:
diff changeset
941 _virtual_register_number += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
942 if (type == T_ADDRESS) type = T_INT;
a61af66fc99e Initial load
duke
parents:
diff changeset
943 return LIR_OprFact::virtual_register(vreg, type);
a61af66fc99e Initial load
duke
parents:
diff changeset
944 }
a61af66fc99e Initial load
duke
parents:
diff changeset
945
a61af66fc99e Initial load
duke
parents:
diff changeset
946
a61af66fc99e Initial load
duke
parents:
diff changeset
947 // Try to lock using register in hint
a61af66fc99e Initial load
duke
parents:
diff changeset
948 LIR_Opr LIRGenerator::rlock(Value instr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
949 return new_register(instr->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
950 }
a61af66fc99e Initial load
duke
parents:
diff changeset
951
a61af66fc99e Initial load
duke
parents:
diff changeset
952
a61af66fc99e Initial load
duke
parents:
diff changeset
953 // does an rlock and sets result
a61af66fc99e Initial load
duke
parents:
diff changeset
954 LIR_Opr LIRGenerator::rlock_result(Value x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
955 LIR_Opr reg = rlock(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
956 set_result(x, reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
957 return reg;
a61af66fc99e Initial load
duke
parents:
diff changeset
958 }
a61af66fc99e Initial load
duke
parents:
diff changeset
959
a61af66fc99e Initial load
duke
parents:
diff changeset
960
a61af66fc99e Initial load
duke
parents:
diff changeset
961 // does an rlock and sets result
a61af66fc99e Initial load
duke
parents:
diff changeset
962 LIR_Opr LIRGenerator::rlock_result(Value x, BasicType type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
963 LIR_Opr reg;
a61af66fc99e Initial load
duke
parents:
diff changeset
964 switch (type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
965 case T_BYTE:
a61af66fc99e Initial load
duke
parents:
diff changeset
966 case T_BOOLEAN:
a61af66fc99e Initial load
duke
parents:
diff changeset
967 reg = rlock_byte(type);
a61af66fc99e Initial load
duke
parents:
diff changeset
968 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
969 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
970 reg = rlock(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
971 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
972 }
a61af66fc99e Initial load
duke
parents:
diff changeset
973
a61af66fc99e Initial load
duke
parents:
diff changeset
974 set_result(x, reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
975 return reg;
a61af66fc99e Initial load
duke
parents:
diff changeset
976 }
a61af66fc99e Initial load
duke
parents:
diff changeset
977
a61af66fc99e Initial load
duke
parents:
diff changeset
978
a61af66fc99e Initial load
duke
parents:
diff changeset
979 //---------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
980 ciObject* LIRGenerator::get_jobject_constant(Value value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
981 ObjectType* oc = value->type()->as_ObjectType();
a61af66fc99e Initial load
duke
parents:
diff changeset
982 if (oc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
983 return oc->constant_value();
a61af66fc99e Initial load
duke
parents:
diff changeset
984 }
a61af66fc99e Initial load
duke
parents:
diff changeset
985 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
986 }
a61af66fc99e Initial load
duke
parents:
diff changeset
987
a61af66fc99e Initial load
duke
parents:
diff changeset
988
a61af66fc99e Initial load
duke
parents:
diff changeset
989 void LIRGenerator::do_ExceptionObject(ExceptionObject* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
990 assert(block()->is_set(BlockBegin::exception_entry_flag), "ExceptionObject only allowed in exception handler block");
a61af66fc99e Initial load
duke
parents:
diff changeset
991 assert(block()->next() == x, "ExceptionObject must be first instruction of block");
a61af66fc99e Initial load
duke
parents:
diff changeset
992
a61af66fc99e Initial load
duke
parents:
diff changeset
993 // no moves are created for phi functions at the begin of exception
a61af66fc99e Initial load
duke
parents:
diff changeset
994 // handlers, so assign operands manually here
a61af66fc99e Initial load
duke
parents:
diff changeset
995 for_each_phi_fun(block(), phi,
a61af66fc99e Initial load
duke
parents:
diff changeset
996 operand_for_instruction(phi));
a61af66fc99e Initial load
duke
parents:
diff changeset
997
a61af66fc99e Initial load
duke
parents:
diff changeset
998 LIR_Opr thread_reg = getThreadPointer();
a61af66fc99e Initial load
duke
parents:
diff changeset
999 __ move(new LIR_Address(thread_reg, in_bytes(JavaThread::exception_oop_offset()), T_OBJECT),
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 exceptionOopOpr());
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 __ move(LIR_OprFact::oopConst(NULL),
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 new LIR_Address(thread_reg, in_bytes(JavaThread::exception_oop_offset()), T_OBJECT));
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 __ move(LIR_OprFact::oopConst(NULL),
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 new LIR_Address(thread_reg, in_bytes(JavaThread::exception_pc_offset()), T_OBJECT));
a61af66fc99e Initial load
duke
parents:
diff changeset
1005
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 LIR_Opr result = new_register(T_OBJECT);
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 __ move(exceptionOopOpr(), result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 set_result(x, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1010
a61af66fc99e Initial load
duke
parents:
diff changeset
1011
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 // visitor functions
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 //----------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1021
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 void LIRGenerator::do_Phi(Phi* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 // phi functions are never visited directly
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1026
a61af66fc99e Initial load
duke
parents:
diff changeset
1027
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 // 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
1029 void LIRGenerator::do_Constant(Constant* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 if (x->state() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 // Any constant with a ValueStack requires patching so emit the patch here
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 LIR_Opr reg = rlock_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 CodeEmitInfo* info = state_for(x, x->state());
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 __ oop2reg_patch(NULL, reg, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 } else if (x->use_count() > 1 && !can_inline_as_constant(x)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 if (!x->is_pinned()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 // unpinned constants are handled specially so that they can be
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 // put into registers when they are used multiple times within a
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 // block. After the block completes their operand will be
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 // cleared so that other blocks can't refer to that register.
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 set_result(x, load_constant(x));
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 LIR_Opr res = x->operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 if (!res->is_valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 res = LIR_OprFact::value_type(x->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 if (res->is_constant()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 LIR_Opr reg = rlock_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 __ move(res, reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 set_result(x, res);
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 set_result(x, LIR_OprFact::value_type(x->type()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1058
a61af66fc99e Initial load
duke
parents:
diff changeset
1059
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 void LIRGenerator::do_Local(Local* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 // operand_for_instruction has the side effect of setting the result
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 // so there's no need to do it here.
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 operand_for_instruction(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1065
a61af66fc99e Initial load
duke
parents:
diff changeset
1066
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 void LIRGenerator::do_IfInstanceOf(IfInstanceOf* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 Unimplemented();
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1070
a61af66fc99e Initial load
duke
parents:
diff changeset
1071
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 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
1073 if (compilation()->env()->dtrace_method_probes()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 BasicTypeList signature;
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 signature.append(T_INT); // thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 signature.append(T_OBJECT); // methodOop
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 LIR_OprList* args = new LIR_OprList();
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 args->append(getThreadPointer());
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 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
1080 __ oop2reg(method()->constant_encoding(), meth);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 args->append(meth);
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 call_runtime(&signature, args, CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), voidType, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1084
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 if (x->type()->is_void()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 __ return_op(LIR_OprFact::illegalOpr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 LIR_Opr reg = result_register_for(x->type(), /*callee=*/true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 LIRItem result(x->result(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1090
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 result.load_item_force(reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 __ return_op(result.result());
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 set_no_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1096
a61af66fc99e Initial load
duke
parents:
diff changeset
1097
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 // Example: object.getClass ()
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 void LIRGenerator::do_getClass(Intrinsic* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 assert(x->number_of_arguments() == 1, "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
1101
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 LIRItem rcvr(x->argument_at(0), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 rcvr.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 LIR_Opr result = rlock_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1105
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 // need to perform the null check on the rcvr
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 CodeEmitInfo* info = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 if (x->needs_null_check()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 info = state_for(x, x->state()->copy_locks());
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 __ move(new LIR_Address(rcvr.result(), oopDesc::klass_offset_in_bytes(), T_OBJECT), result, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 __ move(new LIR_Address(result, Klass::java_mirror_offset_in_bytes() +
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 klassOopDesc::klass_part_offset_in_bytes(), T_OBJECT), result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1115
a61af66fc99e Initial load
duke
parents:
diff changeset
1116
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 // Example: Thread.currentThread()
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 void LIRGenerator::do_currentThread(Intrinsic* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 assert(x->number_of_arguments() == 0, "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 LIR_Opr reg = rlock_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 __ load(new LIR_Address(getThreadPointer(), in_bytes(JavaThread::threadObj_offset()), T_OBJECT), reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1123
a61af66fc99e Initial load
duke
parents:
diff changeset
1124
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 void LIRGenerator::do_RegisterFinalizer(Intrinsic* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 assert(x->number_of_arguments() == 1, "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 LIRItem receiver(x->argument_at(0), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1128
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 receiver.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 BasicTypeList signature;
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 signature.append(T_OBJECT); // receiver
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 LIR_OprList* args = new LIR_OprList();
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 args->append(receiver.result());
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 CodeEmitInfo* info = state_for(x, x->state());
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 call_runtime(&signature, args,
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 CAST_FROM_FN_PTR(address, Runtime1::entry_for(Runtime1::register_finalizer_id)),
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 voidType, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1138
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 set_no_result(x);
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 //------------------------local access--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1144
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 LIR_Opr LIRGenerator::operand_for_instruction(Instruction* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 if (x->operand()->is_illegal()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 Constant* c = x->as_Constant();
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 if (c != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 x->set_operand(LIR_OprFact::value_type(c->type()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 assert(x->as_Phi() || x->as_Local() != NULL, "only for Phi and Local");
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 // allocate a virtual register for this local or phi
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 x->set_operand(rlock(x));
a61af66fc99e Initial load
duke
parents:
diff changeset
1154 _instruction_for_operand.at_put_grow(x->operand()->vreg_number(), x, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 return x->operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1159
a61af66fc99e Initial load
duke
parents:
diff changeset
1160
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 Instruction* LIRGenerator::instruction_for_opr(LIR_Opr opr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 if (opr->is_virtual()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 return instruction_for_vreg(opr->vreg_number());
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1167
a61af66fc99e Initial load
duke
parents:
diff changeset
1168
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 Instruction* LIRGenerator::instruction_for_vreg(int reg_num) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 if (reg_num < _instruction_for_operand.length()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 return _instruction_for_operand.at(reg_num);
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1175
a61af66fc99e Initial load
duke
parents:
diff changeset
1176
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 void LIRGenerator::set_vreg_flag(int vreg_num, VregFlag f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 if (_vreg_flags.size_in_bits() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 BitMap2D temp(100, num_vreg_flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 temp.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 _vreg_flags = temp;
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 _vreg_flags.at_put_grow(vreg_num, f, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1185
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 bool LIRGenerator::is_vreg_flag_set(int vreg_num, VregFlag f) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 if (!_vreg_flags.is_valid_index(vreg_num, f)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 return _vreg_flags.at(vreg_num, f);
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1192
a61af66fc99e Initial load
duke
parents:
diff changeset
1193
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 // Block local constant handling. This code is useful for keeping
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 // unpinned constants and constants which aren't exposed in the IR in
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 // registers. Unpinned Constant instructions have their operands
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 // cleared when the block is finished so that other blocks can't end
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 // up referring to their registers.
a61af66fc99e Initial load
duke
parents:
diff changeset
1199
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 LIR_Opr LIRGenerator::load_constant(Constant* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 assert(!x->is_pinned(), "only for unpinned constants");
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 _unpinned_constants.append(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 return load_constant(LIR_OprFact::value_type(x->type())->as_constant_ptr());
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1205
a61af66fc99e Initial load
duke
parents:
diff changeset
1206
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 LIR_Opr LIRGenerator::load_constant(LIR_Const* c) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 BasicType t = c->type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 for (int i = 0; i < _constants.length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 LIR_Const* other = _constants.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 if (t == other->type()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 switch (t) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 case T_INT:
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 case T_FLOAT:
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 if (c->as_jint_bits() != other->as_jint_bits()) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 case T_LONG:
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 case T_DOUBLE:
486
a738a625039a 6757316: load_constant() produces a wrong long constant, with high a low words swapped
never
parents: 380
diff changeset
1219 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
1220 if (c->as_jint_lo_bits() != other->as_jint_lo_bits()) continue;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 case T_OBJECT:
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 if (c->as_jobject() != other->as_jobject()) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 return _reg_for_constants.at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1229
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 LIR_Opr result = new_register(t);
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 __ move((LIR_Opr)c, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 _constants.append(c);
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 _reg_for_constants.append(result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1236
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 // Various barriers
a61af66fc99e Initial load
duke
parents:
diff changeset
1238
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1239 void LIRGenerator::pre_barrier(LIR_Opr addr_opr, bool patch, CodeEmitInfo* info) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1240 // Do the pre-write barrier, if any.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1241 switch (_bs->kind()) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1242 #ifndef SERIALGC
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1243 case BarrierSet::G1SATBCT:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1244 case BarrierSet::G1SATBCTLogging:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1245 G1SATBCardTableModRef_pre_barrier(addr_opr, patch, info);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1246 break;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1247 #endif // SERIALGC
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1248 case BarrierSet::CardTableModRef:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1249 case BarrierSet::CardTableExtension:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1250 // No pre barriers
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1251 break;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1252 case BarrierSet::ModRef:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1253 case BarrierSet::Other:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1254 // No pre barriers
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1255 break;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1256 default :
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1257 ShouldNotReachHere();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1258
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1259 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1260 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1261
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 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
1263 switch (_bs->kind()) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1264 #ifndef SERIALGC
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1265 case BarrierSet::G1SATBCT:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1266 case BarrierSet::G1SATBCTLogging:
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1267 G1SATBCardTableModRef_post_barrier(addr, new_val);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1268 break;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1269 #endif // SERIALGC
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 case BarrierSet::CardTableModRef:
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 case BarrierSet::CardTableExtension:
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 CardTableModRef_post_barrier(addr, new_val);
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 case BarrierSet::ModRef:
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 case BarrierSet::Other:
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 // No post barriers
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 default :
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1282
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1283 ////////////////////////////////////////////////////////////////////////
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1284 #ifndef SERIALGC
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1285
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1286 void LIRGenerator::G1SATBCardTableModRef_pre_barrier(LIR_Opr addr_opr, bool patch, CodeEmitInfo* info) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1287 if (G1DisablePreBarrier) return;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1288
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1289 // First we test whether marking is in progress.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1290 BasicType flag_type;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1291 if (in_bytes(PtrQueue::byte_width_of_active()) == 4) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1292 flag_type = T_INT;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1293 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1294 guarantee(in_bytes(PtrQueue::byte_width_of_active()) == 1,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1295 "Assumption");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1296 flag_type = T_BYTE;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1297 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1298 LIR_Opr thrd = getThreadPointer();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1299 LIR_Address* mark_active_flag_addr =
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1300 new LIR_Address(thrd,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1301 in_bytes(JavaThread::satb_mark_queue_offset() +
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1302 PtrQueue::byte_offset_of_active()),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1303 flag_type);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1304 // Read the marking-in-progress flag.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1305 LIR_Opr flag_val = new_register(T_INT);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1306 __ load(mark_active_flag_addr, flag_val);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1307
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1308 LabelObj* start_store = new LabelObj();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1309
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1310 LIR_PatchCode pre_val_patch_code =
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1311 patch ? lir_patch_normal : lir_patch_none;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1312
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1313 LIR_Opr pre_val = new_register(T_OBJECT);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1314
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1315 __ cmp(lir_cond_notEqual, flag_val, LIR_OprFact::intConst(0));
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1316 if (!addr_opr->is_address()) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1317 assert(addr_opr->is_register(), "must be");
1572
87fc6aca31ab 6955349: C1: Make G1 barriers work with x64
iveresov
parents: 1564
diff changeset
1318 addr_opr = LIR_OprFact::address(new LIR_Address(addr_opr, T_OBJECT));
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1319 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1320 CodeStub* slow = new G1PreBarrierStub(addr_opr, pre_val, pre_val_patch_code,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1321 info);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1322 __ branch(lir_cond_notEqual, T_INT, slow);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1323 __ branch_destination(slow->continuation());
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1324 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1325
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1326 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
1327 if (G1DisablePostBarrier) return;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1328
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1329 // 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
1330 if (new_val->is_constant() &&
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1331 new_val->as_constant_ptr()->as_jobject() == NULL) return;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1332
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1333 if (!new_val->is_register()) {
1572
87fc6aca31ab 6955349: C1: Make G1 barriers work with x64
iveresov
parents: 1564
diff changeset
1334 LIR_Opr new_val_reg = new_register(T_OBJECT);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1335 if (new_val->is_constant()) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1336 __ move(new_val, new_val_reg);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1337 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1338 __ leal(new_val, new_val_reg);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1339 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1340 new_val = new_val_reg;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1341 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1342 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
1343
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1344 if (addr->is_address()) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1345 LIR_Address* address = addr->as_address_ptr();
1572
87fc6aca31ab 6955349: C1: Make G1 barriers work with x64
iveresov
parents: 1564
diff changeset
1346 LIR_Opr ptr = new_register(T_OBJECT);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1347 if (!address->index()->is_valid() && address->disp() == 0) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1348 __ move(address->base(), ptr);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1349 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1350 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
1351 __ leal(addr, ptr);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1352 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1353 addr = ptr;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1354 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1355 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
1356
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1357 LIR_Opr xor_res = new_pointer_register();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1358 LIR_Opr xor_shift_res = new_pointer_register();
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1359 if (TwoOperandLIRForm ) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1360 __ move(addr, xor_res);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1361 __ logical_xor(xor_res, new_val, xor_res);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1362 __ move(xor_res, xor_shift_res);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1363 __ unsigned_shift_right(xor_shift_res,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1364 LIR_OprFact::intConst(HeapRegion::LogOfHRGrainBytes),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1365 xor_shift_res,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1366 LIR_OprDesc::illegalOpr());
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1367 } else {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1368 __ logical_xor(addr, new_val, xor_res);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1369 __ unsigned_shift_right(xor_res,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1370 LIR_OprFact::intConst(HeapRegion::LogOfHRGrainBytes),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1371 xor_shift_res,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1372 LIR_OprDesc::illegalOpr());
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1373 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1374
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1375 if (!new_val->is_register()) {
1572
87fc6aca31ab 6955349: C1: Make G1 barriers work with x64
iveresov
parents: 1564
diff changeset
1376 LIR_Opr new_val_reg = new_register(T_OBJECT);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1377 __ leal(new_val, new_val_reg);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1378 new_val = new_val_reg;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1379 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1380 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
1381
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1382 __ 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
1383
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1384 CodeStub* slow = new G1PostBarrierStub(addr, new_val);
1572
87fc6aca31ab 6955349: C1: Make G1 barriers work with x64
iveresov
parents: 1564
diff changeset
1385 __ 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
1386 __ branch_destination(slow->continuation());
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1387 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1388
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1389 #endif // SERIALGC
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1390 ////////////////////////////////////////////////////////////////////////
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1391
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 void LIRGenerator::CardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1393
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1394 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
1395 LIR_Const* card_table_base = new LIR_Const(((CardTableModRefBS*)_bs)->byte_map_base);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 if (addr->is_address()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 LIR_Address* address = addr->as_address_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1398 LIR_Opr ptr = new_register(T_OBJECT);
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 if (!address->index()->is_valid() && address->disp() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1400 __ move(address->base(), ptr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1402 assert(address->disp() != max_jint, "lea doesn't support patched addresses!");
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 __ leal(addr, ptr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1404 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 addr = ptr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 assert(addr->is_register(), "must be a register at this point");
a61af66fc99e Initial load
duke
parents:
diff changeset
1408
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1409 #ifdef ARM
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1410 // TODO: ARM - move to platform-dependent code
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1411 LIR_Opr tmp = FrameMap::R14_opr;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1412 if (VM_Version::supports_movw()) {
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1413 __ move((LIR_Opr)card_table_base, tmp);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1414 } else {
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1415 __ 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
1416 }
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1417
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1418 CardTableModRefBS* ct = (CardTableModRefBS*)_bs;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1419 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
1420 if(((int)ct->byte_map_base & 0xff) == 0) {
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1421 __ move(tmp, card_addr);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1422 } else {
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1423 LIR_Opr tmp_zero = new_register(T_INT);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1424 __ move(LIR_OprFact::intConst(0), tmp_zero);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1425 __ move(tmp_zero, card_addr);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1426 }
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1427 #else // ARM
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 LIR_Opr tmp = new_pointer_register();
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 if (TwoOperandLIRForm) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 __ move(addr, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 __ unsigned_shift_right(tmp, CardTableModRefBS::card_shift, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 __ unsigned_shift_right(addr, CardTableModRefBS::card_shift, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 if (can_inline_as_constant(card_table_base)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 __ move(LIR_OprFact::intConst(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 new LIR_Address(tmp, card_table_base->as_jint(), T_BYTE));
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1439 __ move(LIR_OprFact::intConst(0),
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 new LIR_Address(tmp, load_constant(card_table_base),
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 T_BYTE));
a61af66fc99e Initial load
duke
parents:
diff changeset
1442 }
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1443 #endif // ARM
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1445
a61af66fc99e Initial load
duke
parents:
diff changeset
1446
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 //------------------------field access--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1448
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 // Comment copied form templateTable_i486.cpp
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 // ----------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 // Volatile variables demand their effects be made known to all CPU's in
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 // order. Store buffers on most chips allow reads & writes to reorder; the
a61af66fc99e Initial load
duke
parents:
diff changeset
1453 // JMM's ReadAfterWrite.java test fails in -Xint mode without some kind of
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 // memory barrier (i.e., it's not sufficient that the interpreter does not
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 // reorder volatile references, the hardware also must not reorder them).
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 // According to the new Java Memory Model (JMM):
a61af66fc99e Initial load
duke
parents:
diff changeset
1458 // (1) All volatiles are serialized wrt to each other.
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 // ALSO reads & writes act as aquire & release, so:
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 // (2) A read cannot let unrelated NON-volatile memory refs that happen after
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 // the read float up to before the read. It's OK for non-volatile memory refs
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 // that happen before the volatile read to float down below it.
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 // (3) Similar a volatile write cannot let unrelated NON-volatile memory refs
a61af66fc99e Initial load
duke
parents:
diff changeset
1464 // that happen BEFORE the write float down to after the write. It's OK for
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 // non-volatile memory refs that happen after the volatile write to float up
a61af66fc99e Initial load
duke
parents:
diff changeset
1466 // before it.
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1468 // We only put in barriers around volatile refs (they are expensive), not
a61af66fc99e Initial load
duke
parents:
diff changeset
1469 // _between_ memory refs (that would require us to track the flavor of the
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 // previous memory refs). Requirements (2) and (3) require some barriers
a61af66fc99e Initial load
duke
parents:
diff changeset
1471 // before volatile stores and after volatile loads. These nearly cover
a61af66fc99e Initial load
duke
parents:
diff changeset
1472 // requirement (1) but miss the volatile-store-volatile-load case. This final
a61af66fc99e Initial load
duke
parents:
diff changeset
1473 // case is placed after volatile-stores although it could just as well go
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 // before volatile-loads.
a61af66fc99e Initial load
duke
parents:
diff changeset
1475
a61af66fc99e Initial load
duke
parents:
diff changeset
1476
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 void LIRGenerator::do_StoreField(StoreField* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1478 bool needs_patching = x->needs_patching();
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 bool is_volatile = x->field()->is_volatile();
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 BasicType field_type = x->field_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1481 bool is_oop = (field_type == T_ARRAY || field_type == T_OBJECT);
a61af66fc99e Initial load
duke
parents:
diff changeset
1482
a61af66fc99e Initial load
duke
parents:
diff changeset
1483 CodeEmitInfo* info = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1484 if (needs_patching) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 assert(x->explicit_null_check() == NULL, "can't fold null check into patching field access");
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 info = state_for(x, x->state_before());
a61af66fc99e Initial load
duke
parents:
diff changeset
1487 } else if (x->needs_null_check()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 NullCheck* nc = x->explicit_null_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 if (nc == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 info = state_for(x, x->lock_stack());
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1492 info = state_for(nc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1495
a61af66fc99e Initial load
duke
parents:
diff changeset
1496
a61af66fc99e Initial load
duke
parents:
diff changeset
1497 LIRItem object(x->obj(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1498 LIRItem value(x->value(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1499
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 object.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1501
a61af66fc99e Initial load
duke
parents:
diff changeset
1502 if (is_volatile || needs_patching) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1503 // load item if field is volatile (fewer special cases for volatiles)
a61af66fc99e Initial load
duke
parents:
diff changeset
1504 // load item if field not initialized
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 // load item if field not constant
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 // because of code patching we cannot inline constants
a61af66fc99e Initial load
duke
parents:
diff changeset
1507 if (field_type == T_BYTE || field_type == T_BOOLEAN) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1508 value.load_byte_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 value.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1513 value.load_for_store(field_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1514 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1515
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 set_no_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1517
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 if (PrintNotLoaded && needs_patching) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1519 tty->print_cr(" ###class not loaded at store_%s bci %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
1520 x->is_static() ? "static" : "field", x->bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
1521 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1522
a61af66fc99e Initial load
duke
parents:
diff changeset
1523 if (x->needs_null_check() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 (needs_patching ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1525 MacroAssembler::needs_explicit_null_check(x->offset()))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1526 // emit an explicit null check because the offset is too large
a61af66fc99e Initial load
duke
parents:
diff changeset
1527 __ null_check(object.result(), new CodeEmitInfo(info));
a61af66fc99e Initial load
duke
parents:
diff changeset
1528 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1529
a61af66fc99e Initial load
duke
parents:
diff changeset
1530 LIR_Address* address;
a61af66fc99e Initial load
duke
parents:
diff changeset
1531 if (needs_patching) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1532 // we need to patch the offset in the instruction so don't allow
a61af66fc99e Initial load
duke
parents:
diff changeset
1533 // generate_address to try to be smart about emitting the -1.
a61af66fc99e Initial load
duke
parents:
diff changeset
1534 // Otherwise the patching code won't know how to find the
a61af66fc99e Initial load
duke
parents:
diff changeset
1535 // instruction to patch.
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1536 address = new LIR_Address(object.result(), PATCHED_ADDR, field_type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1537 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1538 address = generate_address(object.result(), x->offset(), field_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1540
a61af66fc99e Initial load
duke
parents:
diff changeset
1541 if (is_volatile && os::is_MP()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1542 __ membar_release();
a61af66fc99e Initial load
duke
parents:
diff changeset
1543 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1544
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1545 if (is_oop) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1546 // Do the pre-write barrier, if any.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1547 pre_barrier(LIR_OprFact::address(address),
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1548 needs_patching,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1549 (info ? new CodeEmitInfo(info) : NULL));
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1550 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 0
diff changeset
1551
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1552 if (is_volatile) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1553 assert(!needs_patching && x->is_loaded(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1554 "how do we know it's volatile if it's not loaded");
a61af66fc99e Initial load
duke
parents:
diff changeset
1555 volatile_field_store(value.result(), address, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1556 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1557 LIR_PatchCode patch_code = needs_patching ? lir_patch_normal : lir_patch_none;
a61af66fc99e Initial load
duke
parents:
diff changeset
1558 __ store(value.result(), address, info, patch_code);
a61af66fc99e Initial load
duke
parents:
diff changeset
1559 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1560
a61af66fc99e Initial load
duke
parents:
diff changeset
1561 if (is_oop) {
819
c6386080541b 6849574: VM crash using NonBlockingHashMap (high_scale_lib)
never
parents: 780
diff changeset
1562 // Store to object so mark the card of the header
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1563 post_barrier(object.result(), value.result());
a61af66fc99e Initial load
duke
parents:
diff changeset
1564 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1565
a61af66fc99e Initial load
duke
parents:
diff changeset
1566 if (is_volatile && os::is_MP()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1567 __ membar();
a61af66fc99e Initial load
duke
parents:
diff changeset
1568 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1569 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1570
a61af66fc99e Initial load
duke
parents:
diff changeset
1571
a61af66fc99e Initial load
duke
parents:
diff changeset
1572 void LIRGenerator::do_LoadField(LoadField* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1573 bool needs_patching = x->needs_patching();
a61af66fc99e Initial load
duke
parents:
diff changeset
1574 bool is_volatile = x->field()->is_volatile();
a61af66fc99e Initial load
duke
parents:
diff changeset
1575 BasicType field_type = x->field_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1576
a61af66fc99e Initial load
duke
parents:
diff changeset
1577 CodeEmitInfo* info = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1578 if (needs_patching) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1579 assert(x->explicit_null_check() == NULL, "can't fold null check into patching field access");
a61af66fc99e Initial load
duke
parents:
diff changeset
1580 info = state_for(x, x->state_before());
a61af66fc99e Initial load
duke
parents:
diff changeset
1581 } else if (x->needs_null_check()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1582 NullCheck* nc = x->explicit_null_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
1583 if (nc == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1584 info = state_for(x, x->lock_stack());
a61af66fc99e Initial load
duke
parents:
diff changeset
1585 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1586 info = state_for(nc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1587 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1588 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1589
a61af66fc99e Initial load
duke
parents:
diff changeset
1590 LIRItem object(x->obj(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1591
a61af66fc99e Initial load
duke
parents:
diff changeset
1592 object.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1593
a61af66fc99e Initial load
duke
parents:
diff changeset
1594 if (PrintNotLoaded && needs_patching) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1595 tty->print_cr(" ###class not loaded at load_%s bci %d",
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 x->is_static() ? "static" : "field", x->bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1598
a61af66fc99e Initial load
duke
parents:
diff changeset
1599 if (x->needs_null_check() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1600 (needs_patching ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1601 MacroAssembler::needs_explicit_null_check(x->offset()))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1602 // emit an explicit null check because the offset is too large
a61af66fc99e Initial load
duke
parents:
diff changeset
1603 __ null_check(object.result(), new CodeEmitInfo(info));
a61af66fc99e Initial load
duke
parents:
diff changeset
1604 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1605
a61af66fc99e Initial load
duke
parents:
diff changeset
1606 LIR_Opr reg = rlock_result(x, field_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1607 LIR_Address* address;
a61af66fc99e Initial load
duke
parents:
diff changeset
1608 if (needs_patching) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1609 // we need to patch the offset in the instruction so don't allow
a61af66fc99e Initial load
duke
parents:
diff changeset
1610 // generate_address to try to be smart about emitting the -1.
a61af66fc99e Initial load
duke
parents:
diff changeset
1611 // Otherwise the patching code won't know how to find the
a61af66fc99e Initial load
duke
parents:
diff changeset
1612 // instruction to patch.
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1613 address = new LIR_Address(object.result(), PATCHED_ADDR, field_type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1614 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1615 address = generate_address(object.result(), x->offset(), field_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1616 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1617
a61af66fc99e Initial load
duke
parents:
diff changeset
1618 if (is_volatile) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1619 assert(!needs_patching && x->is_loaded(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1620 "how do we know it's volatile if it's not loaded");
a61af66fc99e Initial load
duke
parents:
diff changeset
1621 volatile_field_load(address, reg, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1622 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1623 LIR_PatchCode patch_code = needs_patching ? lir_patch_normal : lir_patch_none;
a61af66fc99e Initial load
duke
parents:
diff changeset
1624 __ load(address, reg, info, patch_code);
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1626
a61af66fc99e Initial load
duke
parents:
diff changeset
1627 if (is_volatile && os::is_MP()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1628 __ membar_acquire();
a61af66fc99e Initial load
duke
parents:
diff changeset
1629 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1630 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1631
a61af66fc99e Initial load
duke
parents:
diff changeset
1632
a61af66fc99e Initial load
duke
parents:
diff changeset
1633 //------------------------java.nio.Buffer.checkIndex------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1634
a61af66fc99e Initial load
duke
parents:
diff changeset
1635 // int java.nio.Buffer.checkIndex(int)
a61af66fc99e Initial load
duke
parents:
diff changeset
1636 void LIRGenerator::do_NIOCheckIndex(Intrinsic* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1637 // NOTE: by the time we are in checkIndex() we are guaranteed that
a61af66fc99e Initial load
duke
parents:
diff changeset
1638 // the buffer is non-null (because checkIndex is package-private and
a61af66fc99e Initial load
duke
parents:
diff changeset
1639 // only called from within other methods in the buffer).
a61af66fc99e Initial load
duke
parents:
diff changeset
1640 assert(x->number_of_arguments() == 2, "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
1641 LIRItem buf (x->argument_at(0), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1642 LIRItem index(x->argument_at(1), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1643 buf.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1644 index.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1645
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 LIR_Opr result = rlock_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1647 if (GenerateRangeChecks) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1648 CodeEmitInfo* info = state_for(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1649 CodeStub* stub = new RangeCheckStub(info, index.result(), true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1650 if (index.result()->is_constant()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1651 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
1652 __ branch(lir_cond_belowEqual, T_INT, stub);
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1654 cmp_reg_mem(lir_cond_aboveEqual, index.result(), buf.result(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1655 java_nio_Buffer::limit_offset(), T_INT, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1656 __ branch(lir_cond_aboveEqual, T_INT, stub);
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1658 __ move(index.result(), result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1659 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1660 // Just load the index into the result register
a61af66fc99e Initial load
duke
parents:
diff changeset
1661 __ move(index.result(), result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1664
a61af66fc99e Initial load
duke
parents:
diff changeset
1665
a61af66fc99e Initial load
duke
parents:
diff changeset
1666 //------------------------array access--------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1667
a61af66fc99e Initial load
duke
parents:
diff changeset
1668
a61af66fc99e Initial load
duke
parents:
diff changeset
1669 void LIRGenerator::do_ArrayLength(ArrayLength* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1670 LIRItem array(x->array(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 array.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1672 LIR_Opr reg = rlock_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1673
a61af66fc99e Initial load
duke
parents:
diff changeset
1674 CodeEmitInfo* info = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1675 if (x->needs_null_check()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1676 NullCheck* nc = x->explicit_null_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
1677 if (nc == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1678 info = state_for(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1679 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1680 info = state_for(nc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1681 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1682 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1683 __ 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
1684 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1685
a61af66fc99e Initial load
duke
parents:
diff changeset
1686
a61af66fc99e Initial load
duke
parents:
diff changeset
1687 void LIRGenerator::do_LoadIndexed(LoadIndexed* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 bool use_length = x->length() != NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 LIRItem array(x->array(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1690 LIRItem index(x->index(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 LIRItem length(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1692 bool needs_range_check = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1693
a61af66fc99e Initial load
duke
parents:
diff changeset
1694 if (use_length) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1695 needs_range_check = x->compute_needs_range_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
1696 if (needs_range_check) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1697 length.set_instruction(x->length());
a61af66fc99e Initial load
duke
parents:
diff changeset
1698 length.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1699 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1701
a61af66fc99e Initial load
duke
parents:
diff changeset
1702 array.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1703 if (index.is_constant() && can_inline_as_constant(x->index())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1704 // let it be a constant
a61af66fc99e Initial load
duke
parents:
diff changeset
1705 index.dont_load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1706 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1707 index.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1708 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1709
a61af66fc99e Initial load
duke
parents:
diff changeset
1710 CodeEmitInfo* range_check_info = state_for(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1711 CodeEmitInfo* null_check_info = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1712 if (x->needs_null_check()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1713 NullCheck* nc = x->explicit_null_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
1714 if (nc != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1715 null_check_info = state_for(nc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1716 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1717 null_check_info = range_check_info;
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1719 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1720
a61af66fc99e Initial load
duke
parents:
diff changeset
1721 // emit array address setup early so it schedules better
a61af66fc99e Initial load
duke
parents:
diff changeset
1722 LIR_Address* array_addr = emit_array_address(array.result(), index.result(), x->elt_type(), false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1723
a61af66fc99e Initial load
duke
parents:
diff changeset
1724 if (GenerateRangeChecks && needs_range_check) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1725 if (use_length) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1726 // TODO: use a (modified) version of array_range_check that does not require a
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 // constant length to be loaded to a register
a61af66fc99e Initial load
duke
parents:
diff changeset
1728 __ cmp(lir_cond_belowEqual, length.result(), index.result());
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 __ branch(lir_cond_belowEqual, T_INT, new RangeCheckStub(range_check_info, index.result()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1730 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1731 array_range_check(array.result(), index.result(), null_check_info, range_check_info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1732 // The range check performs the null check, so clear it out for the load
a61af66fc99e Initial load
duke
parents:
diff changeset
1733 null_check_info = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1735 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1736
a61af66fc99e Initial load
duke
parents:
diff changeset
1737 __ move(array_addr, rlock_result(x, x->elt_type()), null_check_info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1739
a61af66fc99e Initial load
duke
parents:
diff changeset
1740
a61af66fc99e Initial load
duke
parents:
diff changeset
1741 void LIRGenerator::do_NullCheck(NullCheck* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1742 if (x->can_trap()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1743 LIRItem value(x->obj(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1744 value.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1745 CodeEmitInfo* info = state_for(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1746 __ null_check(value.result(), info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1747 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1748 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1749
a61af66fc99e Initial load
duke
parents:
diff changeset
1750
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 void LIRGenerator::do_Throw(Throw* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1752 LIRItem exception(x->exception(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1753 exception.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1754 set_no_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1755 LIR_Opr exception_opr = exception.result();
a61af66fc99e Initial load
duke
parents:
diff changeset
1756 CodeEmitInfo* info = state_for(x, x->state());
a61af66fc99e Initial load
duke
parents:
diff changeset
1757
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1759 if (PrintC1Statistics) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1760 increment_counter(Runtime1::throw_count_address());
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1762 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1763
a61af66fc99e Initial load
duke
parents:
diff changeset
1764 // check if the instruction has an xhandler in any of the nested scopes
a61af66fc99e Initial load
duke
parents:
diff changeset
1765 bool unwind = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1766 if (info->exception_handlers()->length() == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1767 // this throw is not inside an xhandler
a61af66fc99e Initial load
duke
parents:
diff changeset
1768 unwind = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1769 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1770 // get some idea of the throw type
a61af66fc99e Initial load
duke
parents:
diff changeset
1771 bool type_is_exact = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1772 ciType* throw_type = x->exception()->exact_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1773 if (throw_type == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1774 type_is_exact = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1775 throw_type = x->exception()->declared_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1776 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1777 if (throw_type != NULL && throw_type->is_instance_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1778 ciInstanceKlass* throw_klass = (ciInstanceKlass*)throw_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
1779 unwind = !x->exception_handlers()->could_catch(throw_klass, type_is_exact);
a61af66fc99e Initial load
duke
parents:
diff changeset
1780 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1781 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1782
a61af66fc99e Initial load
duke
parents:
diff changeset
1783 // do null check before moving exception oop into fixed register
a61af66fc99e Initial load
duke
parents:
diff changeset
1784 // to avoid a fixed interval with an oop during the null check.
a61af66fc99e Initial load
duke
parents:
diff changeset
1785 // Use a copy of the CodeEmitInfo because debug information is
a61af66fc99e Initial load
duke
parents:
diff changeset
1786 // different for null_check and throw.
a61af66fc99e Initial load
duke
parents:
diff changeset
1787 if (GenerateCompilerNullChecks &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1788 (x->exception()->as_NewInstance() == NULL && x->exception()->as_ExceptionObject() == NULL)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1789 // if the exception object wasn't created using new then it might be null.
a61af66fc99e Initial load
duke
parents:
diff changeset
1790 __ null_check(exception_opr, new CodeEmitInfo(info, true));
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1792
1378
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1304
diff changeset
1793 if (compilation()->env()->jvmti_can_post_on_exceptions()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1794 // we need to go through the exception lookup path to get JVMTI
a61af66fc99e Initial load
duke
parents:
diff changeset
1795 // notification done
a61af66fc99e Initial load
duke
parents:
diff changeset
1796 unwind = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1797 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1798
a61af66fc99e Initial load
duke
parents:
diff changeset
1799 // move exception oop into fixed register
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 __ move(exception_opr, exceptionOopOpr());
a61af66fc99e Initial load
duke
parents:
diff changeset
1801
a61af66fc99e Initial load
duke
parents:
diff changeset
1802 if (unwind) {
1378
9f5b60a14736 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 1304
diff changeset
1803 __ unwind_exception(exceptionOopOpr());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1804 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1805 __ throw_exception(exceptionPcOpr(), exceptionOopOpr(), info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1806 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1807 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1808
a61af66fc99e Initial load
duke
parents:
diff changeset
1809
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 void LIRGenerator::do_RoundFP(RoundFP* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1811 LIRItem input(x->input(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1812 input.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1813 LIR_Opr input_opr = input.result();
a61af66fc99e Initial load
duke
parents:
diff changeset
1814 assert(input_opr->is_register(), "why round if value is not in a register?");
a61af66fc99e Initial load
duke
parents:
diff changeset
1815 assert(input_opr->is_single_fpu() || input_opr->is_double_fpu(), "input should be floating-point value");
a61af66fc99e Initial load
duke
parents:
diff changeset
1816 if (input_opr->is_single_fpu()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1817 set_result(x, round_item(input_opr)); // This code path not currently taken
a61af66fc99e Initial load
duke
parents:
diff changeset
1818 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1819 LIR_Opr result = new_register(T_DOUBLE);
a61af66fc99e Initial load
duke
parents:
diff changeset
1820 set_vreg_flag(result, must_start_in_memory);
a61af66fc99e Initial load
duke
parents:
diff changeset
1821 __ roundfp(input_opr, LIR_OprFact::illegalOpr, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1822 set_result(x, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
1823 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1824 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1825
a61af66fc99e Initial load
duke
parents:
diff changeset
1826 void LIRGenerator::do_UnsafeGetRaw(UnsafeGetRaw* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1827 LIRItem base(x->base(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1828 LIRItem idx(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1829
a61af66fc99e Initial load
duke
parents:
diff changeset
1830 base.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1831 if (x->has_index()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1832 idx.set_instruction(x->index());
a61af66fc99e Initial load
duke
parents:
diff changeset
1833 idx.load_nonconstant();
a61af66fc99e Initial load
duke
parents:
diff changeset
1834 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1835
a61af66fc99e Initial load
duke
parents:
diff changeset
1836 LIR_Opr reg = rlock_result(x, x->basic_type());
a61af66fc99e Initial load
duke
parents:
diff changeset
1837
a61af66fc99e Initial load
duke
parents:
diff changeset
1838 int log2_scale = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1839 if (x->has_index()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1840 assert(x->index()->type()->tag() == intTag, "should not find non-int index");
a61af66fc99e Initial load
duke
parents:
diff changeset
1841 log2_scale = x->log2_scale();
a61af66fc99e Initial load
duke
parents:
diff changeset
1842 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1843
a61af66fc99e Initial load
duke
parents:
diff changeset
1844 assert(!x->has_index() || idx.value() == x->index(), "should match");
a61af66fc99e Initial load
duke
parents:
diff changeset
1845
a61af66fc99e Initial load
duke
parents:
diff changeset
1846 LIR_Opr base_op = base.result();
a61af66fc99e Initial load
duke
parents:
diff changeset
1847 #ifndef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
1848 if (x->base()->type()->tag() == longTag) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1849 base_op = new_register(T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 __ convert(Bytecodes::_l2i, base.result(), base_op);
a61af66fc99e Initial load
duke
parents:
diff changeset
1851 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1852 assert(x->base()->type()->tag() == intTag, "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
1853 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1854 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1855
a61af66fc99e Initial load
duke
parents:
diff changeset
1856 BasicType dst_type = x->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1857 LIR_Opr index_op = idx.result();
a61af66fc99e Initial load
duke
parents:
diff changeset
1858
a61af66fc99e Initial load
duke
parents:
diff changeset
1859 LIR_Address* addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1860 if (index_op->is_constant()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1861 assert(log2_scale == 0, "must not have a scale");
a61af66fc99e Initial load
duke
parents:
diff changeset
1862 addr = new LIR_Address(base_op, index_op->as_jint(), dst_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1863 } else {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 0
diff changeset
1864 #ifdef X86
1060
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
1865 #ifdef _LP64
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
1866 if (!index_op->is_illegal() && index_op->type() == T_INT) {
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
1867 LIR_Opr tmp = new_pointer_register();
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
1868 __ convert(Bytecodes::_i2l, index_op, tmp);
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
1869 index_op = tmp;
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
1870 }
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
1871 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1872 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
1873 #elif defined(ARM)
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1874 addr = generate_address(base_op, index_op, log2_scale, 0, dst_type);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1875 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
1876 if (index_op->is_illegal() || log2_scale == 0) {
1060
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
1877 #ifdef _LP64
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
1878 if (!index_op->is_illegal() && index_op->type() == T_INT) {
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
1879 LIR_Opr tmp = new_pointer_register();
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
1880 __ convert(Bytecodes::_i2l, index_op, tmp);
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
1881 index_op = tmp;
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
1882 }
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
1883 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1884 addr = new LIR_Address(base_op, index_op, dst_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1885 } else {
1060
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
1886 LIR_Opr tmp = new_pointer_register();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1887 __ shift_left(index_op, log2_scale, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1888 addr = new LIR_Address(base_op, tmp, dst_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1889 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1890 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1891 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1892
a61af66fc99e Initial load
duke
parents:
diff changeset
1893 if (x->may_be_unaligned() && (dst_type == T_LONG || dst_type == T_DOUBLE)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1894 __ unaligned_move(addr, reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
1895 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1896 __ move(addr, reg);
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
a61af66fc99e Initial load
duke
parents:
diff changeset
1901 void LIRGenerator::do_UnsafePutRaw(UnsafePutRaw* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1902 int log2_scale = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1903 BasicType type = x->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1904
a61af66fc99e Initial load
duke
parents:
diff changeset
1905 if (x->has_index()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1906 assert(x->index()->type()->tag() == intTag, "should not find non-int index");
a61af66fc99e Initial load
duke
parents:
diff changeset
1907 log2_scale = x->log2_scale();
a61af66fc99e Initial load
duke
parents:
diff changeset
1908 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1909
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 LIRItem base(x->base(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1911 LIRItem value(x->value(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1912 LIRItem idx(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1913
a61af66fc99e Initial load
duke
parents:
diff changeset
1914 base.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1915 if (x->has_index()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 idx.set_instruction(x->index());
a61af66fc99e Initial load
duke
parents:
diff changeset
1917 idx.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1918 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1919
a61af66fc99e Initial load
duke
parents:
diff changeset
1920 if (type == T_BYTE || type == T_BOOLEAN) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1921 value.load_byte_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1922 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1923 value.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1924 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1925
a61af66fc99e Initial load
duke
parents:
diff changeset
1926 set_no_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1927
a61af66fc99e Initial load
duke
parents:
diff changeset
1928 LIR_Opr base_op = base.result();
a61af66fc99e Initial load
duke
parents:
diff changeset
1929 #ifndef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
1930 if (x->base()->type()->tag() == longTag) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1931 base_op = new_register(T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
1932 __ convert(Bytecodes::_l2i, base.result(), base_op);
a61af66fc99e Initial load
duke
parents:
diff changeset
1933 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1934 assert(x->base()->type()->tag() == intTag, "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
1935 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1936 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1937
a61af66fc99e Initial load
duke
parents:
diff changeset
1938 LIR_Opr index_op = idx.result();
a61af66fc99e Initial load
duke
parents:
diff changeset
1939 if (log2_scale != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1940 // 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
1941 index_op = new_pointer_register();
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
1942 #ifdef _LP64
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
1943 if(idx.result()->type() == T_INT) {
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
1944 __ convert(Bytecodes::_i2l, idx.result(), index_op);
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
1945 } else {
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
1946 #endif
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
1947 // TODO: ARM also allows embedded shift in the address
1060
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
1948 __ move(idx.result(), index_op);
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
1949 #ifdef _LP64
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
1950 }
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
1951 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1952 __ shift_left(index_op, log2_scale, index_op);
a61af66fc99e Initial load
duke
parents:
diff changeset
1953 }
1060
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
1954 #ifdef _LP64
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
1955 else if(!index_op->is_illegal() && index_op->type() == T_INT) {
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
1956 LIR_Opr tmp = new_pointer_register();
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
1957 __ convert(Bytecodes::_i2l, index_op, tmp);
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
1958 index_op = tmp;
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
1959 }
323bd24c6520 6769124: various 64-bit fixes for c1
roland
parents: 989
diff changeset
1960 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1961
a61af66fc99e Initial load
duke
parents:
diff changeset
1962 LIR_Address* addr = new LIR_Address(base_op, index_op, x->basic_type());
a61af66fc99e Initial load
duke
parents:
diff changeset
1963 __ move(value.result(), addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1964 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1965
a61af66fc99e Initial load
duke
parents:
diff changeset
1966
a61af66fc99e Initial load
duke
parents:
diff changeset
1967 void LIRGenerator::do_UnsafeGetObject(UnsafeGetObject* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1968 BasicType type = x->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1969 LIRItem src(x->object(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1970 LIRItem off(x->offset(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1971
a61af66fc99e Initial load
duke
parents:
diff changeset
1972 off.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1973 src.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1974
a61af66fc99e Initial load
duke
parents:
diff changeset
1975 LIR_Opr reg = reg = rlock_result(x, x->basic_type());
a61af66fc99e Initial load
duke
parents:
diff changeset
1976
a61af66fc99e Initial load
duke
parents:
diff changeset
1977 if (x->is_volatile() && os::is_MP()) __ membar_acquire();
a61af66fc99e Initial load
duke
parents:
diff changeset
1978 get_Object_unsafe(reg, src.result(), off.result(), type, x->is_volatile());
a61af66fc99e Initial load
duke
parents:
diff changeset
1979 if (x->is_volatile() && os::is_MP()) __ membar();
a61af66fc99e Initial load
duke
parents:
diff changeset
1980 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1981
a61af66fc99e Initial load
duke
parents:
diff changeset
1982
a61af66fc99e Initial load
duke
parents:
diff changeset
1983 void LIRGenerator::do_UnsafePutObject(UnsafePutObject* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1984 BasicType type = x->basic_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1985 LIRItem src(x->object(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1986 LIRItem off(x->offset(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1987 LIRItem data(x->value(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
1988
a61af66fc99e Initial load
duke
parents:
diff changeset
1989 src.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1990 if (type == T_BOOLEAN || type == T_BYTE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1991 data.load_byte_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1992 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1993 data.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1994 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1995 off.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
1996
a61af66fc99e Initial load
duke
parents:
diff changeset
1997 set_no_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
1998
a61af66fc99e Initial load
duke
parents:
diff changeset
1999 if (x->is_volatile() && os::is_MP()) __ membar_release();
a61af66fc99e Initial load
duke
parents:
diff changeset
2000 put_Object_unsafe(src.result(), off.result(), data.result(), type, x->is_volatile());
a61af66fc99e Initial load
duke
parents:
diff changeset
2001 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2002
a61af66fc99e Initial load
duke
parents:
diff changeset
2003
a61af66fc99e Initial load
duke
parents:
diff changeset
2004 void LIRGenerator::do_UnsafePrefetch(UnsafePrefetch* x, bool is_store) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2005 LIRItem src(x->object(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2006 LIRItem off(x->offset(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2007
a61af66fc99e Initial load
duke
parents:
diff changeset
2008 src.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2009 if (off.is_constant() && can_inline_as_constant(x->offset())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2010 // let it be a constant
a61af66fc99e Initial load
duke
parents:
diff changeset
2011 off.dont_load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2012 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2013 off.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2014 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2015
a61af66fc99e Initial load
duke
parents:
diff changeset
2016 set_no_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2017
a61af66fc99e Initial load
duke
parents:
diff changeset
2018 LIR_Address* addr = generate_address(src.result(), off.result(), 0, 0, T_BYTE);
a61af66fc99e Initial load
duke
parents:
diff changeset
2019 __ prefetch(addr, is_store);
a61af66fc99e Initial load
duke
parents:
diff changeset
2020 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2021
a61af66fc99e Initial load
duke
parents:
diff changeset
2022
a61af66fc99e Initial load
duke
parents:
diff changeset
2023 void LIRGenerator::do_UnsafePrefetchRead(UnsafePrefetchRead* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2024 do_UnsafePrefetch(x, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2025 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2026
a61af66fc99e Initial load
duke
parents:
diff changeset
2027
a61af66fc99e Initial load
duke
parents:
diff changeset
2028 void LIRGenerator::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2029 do_UnsafePrefetch(x, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
2030 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2031
a61af66fc99e Initial load
duke
parents:
diff changeset
2032
a61af66fc99e Initial load
duke
parents:
diff changeset
2033 void LIRGenerator::do_SwitchRanges(SwitchRangeArray* x, LIR_Opr value, BlockBegin* default_sux) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2034 int lng = x->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
2035
a61af66fc99e Initial load
duke
parents:
diff changeset
2036 for (int i = 0; i < lng; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2037 SwitchRange* one_range = x->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2038 int low_key = one_range->low_key();
a61af66fc99e Initial load
duke
parents:
diff changeset
2039 int high_key = one_range->high_key();
a61af66fc99e Initial load
duke
parents:
diff changeset
2040 BlockBegin* dest = one_range->sux();
a61af66fc99e Initial load
duke
parents:
diff changeset
2041 if (low_key == high_key) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2042 __ cmp(lir_cond_equal, value, low_key);
a61af66fc99e Initial load
duke
parents:
diff changeset
2043 __ branch(lir_cond_equal, T_INT, dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
2044 } else if (high_key - low_key == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2045 __ cmp(lir_cond_equal, value, low_key);
a61af66fc99e Initial load
duke
parents:
diff changeset
2046 __ branch(lir_cond_equal, T_INT, dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
2047 __ cmp(lir_cond_equal, value, high_key);
a61af66fc99e Initial load
duke
parents:
diff changeset
2048 __ branch(lir_cond_equal, T_INT, dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
2049 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2050 LabelObj* L = new LabelObj();
a61af66fc99e Initial load
duke
parents:
diff changeset
2051 __ cmp(lir_cond_less, value, low_key);
a61af66fc99e Initial load
duke
parents:
diff changeset
2052 __ branch(lir_cond_less, L->label());
a61af66fc99e Initial load
duke
parents:
diff changeset
2053 __ cmp(lir_cond_lessEqual, value, high_key);
a61af66fc99e Initial load
duke
parents:
diff changeset
2054 __ branch(lir_cond_lessEqual, T_INT, dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
2055 __ branch_destination(L->label());
a61af66fc99e Initial load
duke
parents:
diff changeset
2056 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2057 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2058 __ jump(default_sux);
a61af66fc99e Initial load
duke
parents:
diff changeset
2059 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2060
a61af66fc99e Initial load
duke
parents:
diff changeset
2061
a61af66fc99e Initial load
duke
parents:
diff changeset
2062 SwitchRangeArray* LIRGenerator::create_lookup_ranges(TableSwitch* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2063 SwitchRangeList* res = new SwitchRangeList();
a61af66fc99e Initial load
duke
parents:
diff changeset
2064 int len = x->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
2065 if (len > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2066 BlockBegin* sux = x->sux_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2067 int key = x->lo_key();
a61af66fc99e Initial load
duke
parents:
diff changeset
2068 BlockBegin* default_sux = x->default_sux();
a61af66fc99e Initial load
duke
parents:
diff changeset
2069 SwitchRange* range = new SwitchRange(key, sux);
a61af66fc99e Initial load
duke
parents:
diff changeset
2070 for (int i = 0; i < len; i++, key++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2071 BlockBegin* new_sux = x->sux_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2072 if (sux == new_sux) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2073 // still in same range
a61af66fc99e Initial load
duke
parents:
diff changeset
2074 range->set_high_key(key);
a61af66fc99e Initial load
duke
parents:
diff changeset
2075 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2076 // skip tests which explicitly dispatch to the default
a61af66fc99e Initial load
duke
parents:
diff changeset
2077 if (sux != default_sux) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2078 res->append(range);
a61af66fc99e Initial load
duke
parents:
diff changeset
2079 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2080 range = new SwitchRange(key, new_sux);
a61af66fc99e Initial load
duke
parents:
diff changeset
2081 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2082 sux = new_sux;
a61af66fc99e Initial load
duke
parents:
diff changeset
2083 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2084 if (res->length() == 0 || res->last() != range) res->append(range);
a61af66fc99e Initial load
duke
parents:
diff changeset
2085 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2086 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
2087 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2088
a61af66fc99e Initial load
duke
parents:
diff changeset
2089
a61af66fc99e Initial load
duke
parents:
diff changeset
2090 // we expect the keys to be sorted by increasing value
a61af66fc99e Initial load
duke
parents:
diff changeset
2091 SwitchRangeArray* LIRGenerator::create_lookup_ranges(LookupSwitch* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2092 SwitchRangeList* res = new SwitchRangeList();
a61af66fc99e Initial load
duke
parents:
diff changeset
2093 int len = x->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
2094 if (len > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2095 BlockBegin* default_sux = x->default_sux();
a61af66fc99e Initial load
duke
parents:
diff changeset
2096 int key = x->key_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2097 BlockBegin* sux = x->sux_at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2098 SwitchRange* range = new SwitchRange(key, sux);
a61af66fc99e Initial load
duke
parents:
diff changeset
2099 for (int i = 1; i < len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2100 int new_key = x->key_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2101 BlockBegin* new_sux = x->sux_at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2102 if (key+1 == new_key && sux == new_sux) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2103 // still in same range
a61af66fc99e Initial load
duke
parents:
diff changeset
2104 range->set_high_key(new_key);
a61af66fc99e Initial load
duke
parents:
diff changeset
2105 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2106 // skip tests which explicitly dispatch to the default
a61af66fc99e Initial load
duke
parents:
diff changeset
2107 if (range->sux() != default_sux) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2108 res->append(range);
a61af66fc99e Initial load
duke
parents:
diff changeset
2109 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2110 range = new SwitchRange(new_key, new_sux);
a61af66fc99e Initial load
duke
parents:
diff changeset
2111 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2112 key = new_key;
a61af66fc99e Initial load
duke
parents:
diff changeset
2113 sux = new_sux;
a61af66fc99e Initial load
duke
parents:
diff changeset
2114 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2115 if (res->length() == 0 || res->last() != range) res->append(range);
a61af66fc99e Initial load
duke
parents:
diff changeset
2116 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2117 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
2118 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2119
a61af66fc99e Initial load
duke
parents:
diff changeset
2120
a61af66fc99e Initial load
duke
parents:
diff changeset
2121 void LIRGenerator::do_TableSwitch(TableSwitch* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2122 LIRItem tag(x->tag(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2123 tag.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2124 set_no_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2125
a61af66fc99e Initial load
duke
parents:
diff changeset
2126 if (x->is_safepoint()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2127 __ safepoint(safepoint_poll_register(), state_for(x, x->state_before()));
a61af66fc99e Initial load
duke
parents:
diff changeset
2128 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2129
a61af66fc99e Initial load
duke
parents:
diff changeset
2130 // move values into phi locations
a61af66fc99e Initial load
duke
parents:
diff changeset
2131 move_to_phi(x->state());
a61af66fc99e Initial load
duke
parents:
diff changeset
2132
a61af66fc99e Initial load
duke
parents:
diff changeset
2133 int lo_key = x->lo_key();
a61af66fc99e Initial load
duke
parents:
diff changeset
2134 int hi_key = x->hi_key();
a61af66fc99e Initial load
duke
parents:
diff changeset
2135 int len = x->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
2136 CodeEmitInfo* info = state_for(x, x->state());
a61af66fc99e Initial load
duke
parents:
diff changeset
2137 LIR_Opr value = tag.result();
a61af66fc99e Initial load
duke
parents:
diff changeset
2138 if (UseTableRanges) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2139 do_SwitchRanges(create_lookup_ranges(x), value, x->default_sux());
a61af66fc99e Initial load
duke
parents:
diff changeset
2140 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2141 for (int i = 0; i < len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2142 __ cmp(lir_cond_equal, value, i + lo_key);
a61af66fc99e Initial load
duke
parents:
diff changeset
2143 __ branch(lir_cond_equal, T_INT, x->sux_at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
2144 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2145 __ jump(x->default_sux());
a61af66fc99e Initial load
duke
parents:
diff changeset
2146 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2147 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2148
a61af66fc99e Initial load
duke
parents:
diff changeset
2149
a61af66fc99e Initial load
duke
parents:
diff changeset
2150 void LIRGenerator::do_LookupSwitch(LookupSwitch* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2151 LIRItem tag(x->tag(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2152 tag.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2153 set_no_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2154
a61af66fc99e Initial load
duke
parents:
diff changeset
2155 if (x->is_safepoint()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2156 __ safepoint(safepoint_poll_register(), state_for(x, x->state_before()));
a61af66fc99e Initial load
duke
parents:
diff changeset
2157 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2158
a61af66fc99e Initial load
duke
parents:
diff changeset
2159 // move values into phi locations
a61af66fc99e Initial load
duke
parents:
diff changeset
2160 move_to_phi(x->state());
a61af66fc99e Initial load
duke
parents:
diff changeset
2161
a61af66fc99e Initial load
duke
parents:
diff changeset
2162 LIR_Opr value = tag.result();
a61af66fc99e Initial load
duke
parents:
diff changeset
2163 if (UseTableRanges) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2164 do_SwitchRanges(create_lookup_ranges(x), value, x->default_sux());
a61af66fc99e Initial load
duke
parents:
diff changeset
2165 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2166 int len = x->length();
a61af66fc99e Initial load
duke
parents:
diff changeset
2167 for (int i = 0; i < len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2168 __ cmp(lir_cond_equal, value, x->key_at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
2169 __ branch(lir_cond_equal, T_INT, x->sux_at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
2170 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2171 __ jump(x->default_sux());
a61af66fc99e Initial load
duke
parents:
diff changeset
2172 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2173 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2174
a61af66fc99e Initial load
duke
parents:
diff changeset
2175
a61af66fc99e Initial load
duke
parents:
diff changeset
2176 void LIRGenerator::do_Goto(Goto* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2177 set_no_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2178
a61af66fc99e Initial load
duke
parents:
diff changeset
2179 if (block()->next()->as_OsrEntry()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2180 // need to free up storage used for OSR entry point
a61af66fc99e Initial load
duke
parents:
diff changeset
2181 LIR_Opr osrBuffer = block()->next()->operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
2182 BasicTypeList signature;
a61af66fc99e Initial load
duke
parents:
diff changeset
2183 signature.append(T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
2184 CallingConvention* cc = frame_map()->c_calling_convention(&signature);
a61af66fc99e Initial load
duke
parents:
diff changeset
2185 __ move(osrBuffer, cc->args()->at(0));
a61af66fc99e Initial load
duke
parents:
diff changeset
2186 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::OSR_migration_end),
a61af66fc99e Initial load
duke
parents:
diff changeset
2187 getThreadTemp(), LIR_OprFact::illegalOpr, cc->args());
a61af66fc99e Initial load
duke
parents:
diff changeset
2188 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2189
a61af66fc99e Initial load
duke
parents:
diff changeset
2190 if (x->is_safepoint()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2191 ValueStack* state = x->state_before() ? x->state_before() : x->state();
a61af66fc99e Initial load
duke
parents:
diff changeset
2192
a61af66fc99e Initial load
duke
parents:
diff changeset
2193 // increment backedge counter if needed
a61af66fc99e Initial load
duke
parents:
diff changeset
2194 increment_backedge_counter(state_for(x, state));
a61af66fc99e Initial load
duke
parents:
diff changeset
2195
a61af66fc99e Initial load
duke
parents:
diff changeset
2196 CodeEmitInfo* safepoint_info = state_for(x, state);
a61af66fc99e Initial load
duke
parents:
diff changeset
2197 __ safepoint(safepoint_poll_register(), safepoint_info);
a61af66fc99e Initial load
duke
parents:
diff changeset
2198 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2199
a61af66fc99e Initial load
duke
parents:
diff changeset
2200 // emit phi-instruction move after safepoint since this simplifies
a61af66fc99e Initial load
duke
parents:
diff changeset
2201 // describing the state as the safepoint.
a61af66fc99e Initial load
duke
parents:
diff changeset
2202 move_to_phi(x->state());
a61af66fc99e Initial load
duke
parents:
diff changeset
2203
a61af66fc99e Initial load
duke
parents:
diff changeset
2204 __ jump(x->default_sux());
a61af66fc99e Initial load
duke
parents:
diff changeset
2205 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2206
a61af66fc99e Initial load
duke
parents:
diff changeset
2207
a61af66fc99e Initial load
duke
parents:
diff changeset
2208 void LIRGenerator::do_Base(Base* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2209 __ std_entry(LIR_OprFact::illegalOpr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2210 // Emit moves from physical registers / stack slots to virtual registers
a61af66fc99e Initial load
duke
parents:
diff changeset
2211 CallingConvention* args = compilation()->frame_map()->incoming_arguments();
a61af66fc99e Initial load
duke
parents:
diff changeset
2212 IRScope* irScope = compilation()->hir()->top_scope();
a61af66fc99e Initial load
duke
parents:
diff changeset
2213 int java_index = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2214 for (int i = 0; i < args->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2215 LIR_Opr src = args->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2216 assert(!src->is_illegal(), "check");
a61af66fc99e Initial load
duke
parents:
diff changeset
2217 BasicType t = src->type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2218
a61af66fc99e Initial load
duke
parents:
diff changeset
2219 // Types which are smaller than int are passed as int, so
a61af66fc99e Initial load
duke
parents:
diff changeset
2220 // correct the type which passed.
a61af66fc99e Initial load
duke
parents:
diff changeset
2221 switch (t) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2222 case T_BYTE:
a61af66fc99e Initial load
duke
parents:
diff changeset
2223 case T_BOOLEAN:
a61af66fc99e Initial load
duke
parents:
diff changeset
2224 case T_SHORT:
a61af66fc99e Initial load
duke
parents:
diff changeset
2225 case T_CHAR:
a61af66fc99e Initial load
duke
parents:
diff changeset
2226 t = T_INT;
a61af66fc99e Initial load
duke
parents:
diff changeset
2227 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2228 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2229
a61af66fc99e Initial load
duke
parents:
diff changeset
2230 LIR_Opr dest = new_register(t);
a61af66fc99e Initial load
duke
parents:
diff changeset
2231 __ move(src, dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
2232
a61af66fc99e Initial load
duke
parents:
diff changeset
2233 // Assign new location to Local instruction for this local
a61af66fc99e Initial load
duke
parents:
diff changeset
2234 Local* local = x->state()->local_at(java_index)->as_Local();
a61af66fc99e Initial load
duke
parents:
diff changeset
2235 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
2236 #ifndef __SOFTFP__
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
2237 // The java calling convention passes double as long and float as int.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2238 assert(as_ValueType(t)->tag() == local->type()->tag(), "check");
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1584
diff changeset
2239 #endif // __SOFTFP__
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2240 local->set_operand(dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
2241 _instruction_for_operand.at_put_grow(dest->vreg_number(), local, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2242 java_index += type2size[t];
a61af66fc99e Initial load
duke
parents:
diff changeset
2243 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2244
780
c96bf21b756f 6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents: 579
diff changeset
2245 if (compilation()->env()->dtrace_method_probes()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2246 BasicTypeList signature;
a61af66fc99e Initial load
duke
parents:
diff changeset
2247 signature.append(T_INT); // thread
a61af66fc99e Initial load
duke
parents:
diff changeset
2248 signature.append(T_OBJECT); // methodOop
a61af66fc99e Initial load
duke
parents:
diff changeset
2249 LIR_OprList* args = new LIR_OprList();
a61af66fc99e Initial load
duke
parents:
diff changeset
2250 args->append(getThreadPointer());
a61af66fc99e Initial load
duke
parents:
diff changeset
2251 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
2252 __ oop2reg(method()->constant_encoding(), meth);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2253 args->append(meth);
a61af66fc99e Initial load
duke
parents:
diff changeset
2254 call_runtime(&signature, args, CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry), voidType, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2255 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2256
a61af66fc99e Initial load
duke
parents:
diff changeset
2257 if (method()->is_synchronized()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2258 LIR_Opr obj;
a61af66fc99e Initial load
duke
parents:
diff changeset
2259 if (method()->is_static()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2260 obj = new_register(T_OBJECT);
989
148e5441d916 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 819
diff changeset
2261 __ oop2reg(method()->holder()->java_mirror()->constant_encoding(), obj);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2262 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2263 Local* receiver = x->state()->local_at(0)->as_Local();
a61af66fc99e Initial load
duke
parents:
diff changeset
2264 assert(receiver != NULL, "must already exist");
a61af66fc99e Initial load
duke
parents:
diff changeset
2265 obj = receiver->operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
2266 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2267 assert(obj->is_valid(), "must be valid");
a61af66fc99e Initial load
duke
parents:
diff changeset
2268
a61af66fc99e Initial load
duke
parents:
diff changeset
2269 if (method()->is_synchronized() && GenerateSynchronizationCode) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2270 LIR_Opr lock = new_register(T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
2271 __ load_stack_address_monitor(0, lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
2272
a61af66fc99e Initial load
duke
parents:
diff changeset
2273 CodeEmitInfo* info = new CodeEmitInfo(SynchronizationEntryBCI, scope()->start()->state(), NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2274 CodeStub* slow_path = new MonitorEnterStub(obj, lock, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
2275
a61af66fc99e Initial load
duke
parents:
diff changeset
2276 // receiver is guaranteed non-NULL so don't need CodeEmitInfo
a61af66fc99e Initial load
duke
parents:
diff changeset
2277 __ lock_object(syncTempOpr(), obj, lock, new_register(T_OBJECT), slow_path, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2278 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2279 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2280
a61af66fc99e Initial load
duke
parents:
diff changeset
2281 // increment invocation counters if needed
a61af66fc99e Initial load
duke
parents:
diff changeset
2282 increment_invocation_counter(new CodeEmitInfo(0, scope()->start()->state(), NULL));
a61af66fc99e Initial load
duke
parents:
diff changeset
2283
a61af66fc99e Initial load
duke
parents:
diff changeset
2284 // all blocks with a successor must end with an unconditional jump
a61af66fc99e Initial load
duke
parents:
diff changeset
2285 // to the successor even if they are consecutive
a61af66fc99e Initial load
duke
parents:
diff changeset
2286 __ jump(x->default_sux());
a61af66fc99e Initial load
duke
parents:
diff changeset
2287 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2288
a61af66fc99e Initial load
duke
parents:
diff changeset
2289
a61af66fc99e Initial load
duke
parents:
diff changeset
2290 void LIRGenerator::do_OsrEntry(OsrEntry* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2291 // construct our frame and model the production of incoming pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
2292 // to the OSR buffer.
a61af66fc99e Initial load
duke
parents:
diff changeset
2293 __ osr_entry(LIR_Assembler::osrBufferPointer());
a61af66fc99e Initial load
duke
parents:
diff changeset
2294 LIR_Opr result = rlock_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2295 __ move(LIR_Assembler::osrBufferPointer(), result);
a61af66fc99e Initial load
duke
parents:
diff changeset
2296 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2297
a61af66fc99e Initial load
duke
parents:
diff changeset
2298
a61af66fc99e Initial load
duke
parents:
diff changeset
2299 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
2300 int i = (x->has_receiver() || x->is_invokedynamic()) ? 1 : 0;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2301 for (; i < args->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2302 LIRItem* param = args->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2303 LIR_Opr loc = arg_list->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2304 if (loc->is_register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2305 param->load_item_force(loc);
a61af66fc99e Initial load
duke
parents:
diff changeset
2306 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2307 LIR_Address* addr = loc->as_address_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2308 param->load_for_store(addr->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
2309 if (addr->type() == T_LONG || addr->type() == T_DOUBLE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2310 __ unaligned_move(param->result(), addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2311 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2312 __ move(param->result(), addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2313 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2314 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2315 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2316
a61af66fc99e Initial load
duke
parents:
diff changeset
2317 if (x->has_receiver()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2318 LIRItem* receiver = args->at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2319 LIR_Opr loc = arg_list->at(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
2320 if (loc->is_register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2321 receiver->load_item_force(loc);
a61af66fc99e Initial load
duke
parents:
diff changeset
2322 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2323 assert(loc->is_address(), "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
2324 receiver->load_for_store(T_OBJECT);
a61af66fc99e Initial load
duke
parents:
diff changeset
2325 __ move(receiver->result(), loc);
a61af66fc99e Initial load
duke
parents:
diff changeset
2326 }
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
a61af66fc99e Initial load
duke
parents:
diff changeset
2331 // Visits all arguments, returns appropriate items without loading them
a61af66fc99e Initial load
duke
parents:
diff changeset
2332 LIRItemList* LIRGenerator::invoke_visit_arguments(Invoke* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2333 LIRItemList* argument_items = new LIRItemList();
a61af66fc99e Initial load
duke
parents:
diff changeset
2334 if (x->has_receiver()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2335 LIRItem* receiver = new LIRItem(x->receiver(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2336 argument_items->append(receiver);
a61af66fc99e Initial load
duke
parents:
diff changeset
2337 }
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2338 if (x->is_invokedynamic()) {
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2339 // Insert a dummy for the synthetic MethodHandle argument.
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2340 argument_items->append(NULL);
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2341 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2342 int idx = x->has_receiver() ? 1 : 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2343 for (int i = 0; i < x->number_of_arguments(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2344 LIRItem* param = new LIRItem(x->argument_at(i), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2345 argument_items->append(param);
a61af66fc99e Initial load
duke
parents:
diff changeset
2346 idx += (param->type()->is_double_word() ? 2 : 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2347 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2348 return argument_items;
a61af66fc99e Initial load
duke
parents:
diff changeset
2349 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2350
a61af66fc99e Initial load
duke
parents:
diff changeset
2351
a61af66fc99e Initial load
duke
parents:
diff changeset
2352 // The invoke with receiver has following phases:
a61af66fc99e Initial load
duke
parents:
diff changeset
2353 // a) traverse and load/lock receiver;
a61af66fc99e Initial load
duke
parents:
diff changeset
2354 // b) traverse all arguments -> item-array (invoke_visit_argument)
a61af66fc99e Initial load
duke
parents:
diff changeset
2355 // c) push receiver on stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2356 // d) load each of the items and push on stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2357 // e) unlock receiver
a61af66fc99e Initial load
duke
parents:
diff changeset
2358 // f) move receiver into receiver-register %o0
a61af66fc99e Initial load
duke
parents:
diff changeset
2359 // g) lock result registers and emit call operation
a61af66fc99e Initial load
duke
parents:
diff changeset
2360 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2361 // Before issuing a call, we must spill-save all values on stack
a61af66fc99e Initial load
duke
parents:
diff changeset
2362 // that are in caller-save register. "spill-save" moves thos registers
a61af66fc99e Initial load
duke
parents:
diff changeset
2363 // either in a free callee-save register or spills them if no free
a61af66fc99e Initial load
duke
parents:
diff changeset
2364 // callee save register is available.
a61af66fc99e Initial load
duke
parents:
diff changeset
2365 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2366 // The problem is where to invoke spill-save.
a61af66fc99e Initial load
duke
parents:
diff changeset
2367 // - if invoked between e) and f), we may lock callee save
a61af66fc99e Initial load
duke
parents:
diff changeset
2368 // register in "spill-save" that destroys the receiver register
a61af66fc99e Initial load
duke
parents:
diff changeset
2369 // before f) is executed
a61af66fc99e Initial load
duke
parents:
diff changeset
2370 // - if we rearange the f) to be earlier, by loading %o0, it
a61af66fc99e Initial load
duke
parents:
diff changeset
2371 // may destroy a value on the stack that is currently in %o0
a61af66fc99e Initial load
duke
parents:
diff changeset
2372 // and is waiting to be spilled
a61af66fc99e Initial load
duke
parents:
diff changeset
2373 // - if we keep the receiver locked while doing spill-save,
a61af66fc99e Initial load
duke
parents:
diff changeset
2374 // we cannot spill it as it is spill-locked
a61af66fc99e Initial load
duke
parents:
diff changeset
2375 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2376 void LIRGenerator::do_Invoke(Invoke* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2377 CallingConvention* cc = frame_map()->java_calling_convention(x->signature(), true);
a61af66fc99e Initial load
duke
parents:
diff changeset
2378
a61af66fc99e Initial load
duke
parents:
diff changeset
2379 LIR_OprList* arg_list = cc->args();
a61af66fc99e Initial load
duke
parents:
diff changeset
2380 LIRItemList* args = invoke_visit_arguments(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2381 LIR_Opr receiver = LIR_OprFact::illegalOpr;
a61af66fc99e Initial load
duke
parents:
diff changeset
2382
a61af66fc99e Initial load
duke
parents:
diff changeset
2383 // setup result register
a61af66fc99e Initial load
duke
parents:
diff changeset
2384 LIR_Opr result_register = LIR_OprFact::illegalOpr;
a61af66fc99e Initial load
duke
parents:
diff changeset
2385 if (x->type() != voidType) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2386 result_register = result_register_for(x->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
2387 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2388
a61af66fc99e Initial load
duke
parents:
diff changeset
2389 CodeEmitInfo* info = state_for(x, x->state());
a61af66fc99e Initial load
duke
parents:
diff changeset
2390
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2391 // invokedynamics can deoptimize.
1304
76c1d7d13ec5 6932091: JSR 292 x86 code cleanup
twisti
parents: 1295
diff changeset
2392 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
2393
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2394 invoke_load_arguments(x, args, arg_list);
a61af66fc99e Initial load
duke
parents:
diff changeset
2395
a61af66fc99e Initial load
duke
parents:
diff changeset
2396 if (x->has_receiver()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2397 args->at(0)->load_item_force(LIR_Assembler::receiverOpr());
a61af66fc99e Initial load
duke
parents:
diff changeset
2398 receiver = args->at(0)->result();
a61af66fc99e Initial load
duke
parents:
diff changeset
2399 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2400
a61af66fc99e Initial load
duke
parents:
diff changeset
2401 // emit invoke code
a61af66fc99e Initial load
duke
parents:
diff changeset
2402 bool optimized = x->target_is_loaded() && x->target_is_final();
a61af66fc99e Initial load
duke
parents:
diff changeset
2403 assert(receiver->is_illegal() || receiver->is_equal(LIR_Assembler::receiverOpr()), "must match");
a61af66fc99e Initial load
duke
parents:
diff changeset
2404
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2405 // JSR 292
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2406 // Preserve the SP over MethodHandle call sites.
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2407 ciMethod* target = x->target();
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2408 if (target->is_method_handle_invoke()) {
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2409 info->set_is_method_handle_invoke(true);
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2410 __ 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
2411 }
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2412
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2413 switch (x->code()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2414 case Bytecodes::_invokestatic:
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2415 __ call_static(target, result_register,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2416 SharedRuntime::get_resolve_static_call_stub(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2417 arg_list, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
2418 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2419 case Bytecodes::_invokespecial:
a61af66fc99e Initial load
duke
parents:
diff changeset
2420 case Bytecodes::_invokevirtual:
a61af66fc99e Initial load
duke
parents:
diff changeset
2421 case Bytecodes::_invokeinterface:
a61af66fc99e Initial load
duke
parents:
diff changeset
2422 // for final target we still produce an inline cache, in order
a61af66fc99e Initial load
duke
parents:
diff changeset
2423 // to be able to call mixed mode
a61af66fc99e Initial load
duke
parents:
diff changeset
2424 if (x->code() == Bytecodes::_invokespecial || optimized) {
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2425 __ call_opt_virtual(target, receiver, result_register,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2426 SharedRuntime::get_resolve_opt_virtual_call_stub(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2427 arg_list, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
2428 } else if (x->vtable_index() < 0) {
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2429 __ call_icvirtual(target, receiver, result_register,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2430 SharedRuntime::get_resolve_virtual_call_stub(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2431 arg_list, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
2432 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2433 int entry_offset = instanceKlass::vtable_start_offset() + x->vtable_index() * vtableEntry::size();
a61af66fc99e Initial load
duke
parents:
diff changeset
2434 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
2435 __ call_virtual(target, receiver, result_register, vtable_offset, arg_list, info);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2436 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2437 break;
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2438 case Bytecodes::_invokedynamic: {
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2439 ciBytecodeStream bcs(x->scope()->method());
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2440 bcs.force_bci(x->bci());
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2441 assert(bcs.cur_bc() == Bytecodes::_invokedynamic, "wrong stream");
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2442 ciCPCache* cpcache = bcs.get_cpcache();
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2443
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2444 // Get CallSite offset from constant pool cache pointer.
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2445 int index = bcs.get_method_index();
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2446 size_t call_site_offset = cpcache->get_f1_offset(index);
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2447
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2448 // 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
2449 // the interpreter, the CallSite object in the constant pool
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2450 // cache is still null and we need to deoptimize.
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2451 if (cpcache->is_f1_null_at(index)) {
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2452 // Cannot re-use same xhandlers for multiple CodeEmitInfos, so
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2453 // clone all handlers. This is handled transparently in other
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2454 // places by the CodeEmitInfo cloning logic but is handled
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2455 // specially here because a stub isn't being used.
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2456 x->set_exception_handlers(new XHandlers(x->exception_handlers()));
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2457
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2458 DeoptimizeStub* deopt_stub = new DeoptimizeStub(deopt_info);
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2459 __ jump(deopt_stub);
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2460 }
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2461
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2462 // Use the receiver register for the synthetic MethodHandle
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2463 // argument.
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2464 receiver = LIR_Assembler::receiverOpr();
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2465 LIR_Opr tmp = new_register(objectType);
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2466
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2467 // Load CallSite object from constant pool cache.
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2468 __ oop2reg(cpcache->constant_encoding(), tmp);
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2469 __ load(new LIR_Address(tmp, call_site_offset, T_OBJECT), tmp);
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2470
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2471 // Load target MethodHandle from CallSite object.
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2472 __ load(new LIR_Address(tmp, java_dyn_CallSite::target_offset_in_bytes(), T_OBJECT), receiver);
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2473
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2474 __ call_dynamic(target, receiver, result_register,
1295
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2475 SharedRuntime::get_resolve_opt_virtual_call_stub(),
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2476 arg_list, info);
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2477 break;
3cf667df43ef 6919934: JSR 292 needs to support x86 C1
twisti
parents: 1213
diff changeset
2478 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2479 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
2480 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
2481 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2482 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2483
1564
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2484 // JSR 292
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2485 // Restore the SP after MethodHandle call sites.
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2486 if (target->is_method_handle_invoke()) {
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2487 __ 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
2488 }
61b2245abf36 6930772: JSR 292 needs to support SPARC C1
twisti
parents: 1378
diff changeset
2489
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2490 if (x->type()->is_float() || x->type()->is_double()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2491 // Force rounding of results from non-strictfp when in strictfp
a61af66fc99e Initial load
duke
parents:
diff changeset
2492 // scope (or when we don't know the strictness of the callee, to
a61af66fc99e Initial load
duke
parents:
diff changeset
2493 // be safe.)
a61af66fc99e Initial load
duke
parents:
diff changeset
2494 if (method()->is_strict()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2495 if (!x->target_is_loaded() || !x->target_is_strictfp()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2496 result_register = round_item(result_register);
a61af66fc99e Initial load
duke
parents:
diff changeset
2497 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2498 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2499 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2500
a61af66fc99e Initial load
duke
parents:
diff changeset
2501 if (result_register->is_valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2502 LIR_Opr result = rlock_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2503 __ move(result_register, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
2504 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2505 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2506
a61af66fc99e Initial load
duke
parents:
diff changeset
2507
a61af66fc99e Initial load
duke
parents:
diff changeset
2508 void LIRGenerator::do_FPIntrinsics(Intrinsic* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2509 assert(x->number_of_arguments() == 1, "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
2510 LIRItem value (x->argument_at(0), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2511 LIR_Opr reg = rlock_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2512 value.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2513 LIR_Opr tmp = force_to_spill(value.result(), as_BasicType(x->type()));
a61af66fc99e Initial load
duke
parents:
diff changeset
2514 __ move(tmp, reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2515 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2516
a61af66fc99e Initial load
duke
parents:
diff changeset
2517
a61af66fc99e Initial load
duke
parents:
diff changeset
2518
a61af66fc99e Initial load
duke
parents:
diff changeset
2519 // Code for : x->x() {x->cond()} x->y() ? x->tval() : x->fval()
a61af66fc99e Initial load
duke
parents:
diff changeset
2520 void LIRGenerator::do_IfOp(IfOp* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2521 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
2522 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2523 ValueTag xtag = x->x()->type()->tag();
a61af66fc99e Initial load
duke
parents:
diff changeset
2524 ValueTag ttag = x->tval()->type()->tag();
a61af66fc99e Initial load
duke
parents:
diff changeset
2525 assert(xtag == intTag || xtag == objectTag, "cannot handle others");
a61af66fc99e Initial load
duke
parents:
diff changeset
2526 assert(ttag == addressTag || ttag == intTag || ttag == objectTag || ttag == longTag, "cannot handle others");
a61af66fc99e Initial load
duke
parents:
diff changeset
2527 assert(ttag == x->fval()->type()->tag(), "cannot handle others");
a61af66fc99e Initial load
duke
parents:
diff changeset
2528 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2529 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2530
a61af66fc99e Initial load
duke
parents:
diff changeset
2531 LIRItem left(x->x(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2532 LIRItem right(x->y(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2533 left.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2534 if (can_inline_as_constant(right.value())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2535 right.dont_load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2536 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2537 right.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2538 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2539
a61af66fc99e Initial load
duke
parents:
diff changeset
2540 LIRItem t_val(x->tval(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2541 LIRItem f_val(x->fval(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2542 t_val.dont_load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2543 f_val.dont_load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2544 LIR_Opr reg = rlock_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2545
a61af66fc99e Initial load
duke
parents:
diff changeset
2546 __ cmp(lir_cond(x->cond()), left.result(), right.result());
a61af66fc99e Initial load
duke
parents:
diff changeset
2547 __ cmove(lir_cond(x->cond()), t_val.result(), f_val.result(), reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
2548 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2549
a61af66fc99e Initial load
duke
parents:
diff changeset
2550
a61af66fc99e Initial load
duke
parents:
diff changeset
2551 void LIRGenerator::do_Intrinsic(Intrinsic* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2552 switch (x->id()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2553 case vmIntrinsics::_intBitsToFloat :
a61af66fc99e Initial load
duke
parents:
diff changeset
2554 case vmIntrinsics::_doubleToRawLongBits :
a61af66fc99e Initial load
duke
parents:
diff changeset
2555 case vmIntrinsics::_longBitsToDouble :
a61af66fc99e Initial load
duke
parents:
diff changeset
2556 case vmIntrinsics::_floatToRawIntBits : {
a61af66fc99e Initial load
duke
parents:
diff changeset
2557 do_FPIntrinsics(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2558 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2559 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2560
a61af66fc99e Initial load
duke
parents:
diff changeset
2561 case vmIntrinsics::_currentTimeMillis: {
a61af66fc99e Initial load
duke
parents:
diff changeset
2562 assert(x->number_of_arguments() == 0, "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
2563 LIR_Opr reg = result_register_for(x->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
2564 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, os::javaTimeMillis), getThreadTemp(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2565 reg, new LIR_OprList());
a61af66fc99e Initial load
duke
parents:
diff changeset
2566 LIR_Opr result = rlock_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2567 __ move(reg, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
2568 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2569 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2570
a61af66fc99e Initial load
duke
parents:
diff changeset
2571 case vmIntrinsics::_nanoTime: {
a61af66fc99e Initial load
duke
parents:
diff changeset
2572 assert(x->number_of_arguments() == 0, "wrong type");
a61af66fc99e Initial load
duke
parents:
diff changeset
2573 LIR_Opr reg = result_register_for(x->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
2574 __ call_runtime_leaf(CAST_FROM_FN_PTR(address, os::javaTimeNanos), getThreadTemp(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2575 reg, new LIR_OprList());
a61af66fc99e Initial load
duke
parents:
diff changeset
2576 LIR_Opr result = rlock_result(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2577 __ move(reg, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
2578 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2579 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2580
a61af66fc99e Initial load
duke
parents:
diff changeset
2581 case vmIntrinsics::_Object_init: do_RegisterFinalizer(x); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2582 case vmIntrinsics::_getClass: do_getClass(x); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2583 case vmIntrinsics::_currentThread: do_currentThread(x); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2584
a61af66fc99e Initial load
duke
parents:
diff changeset
2585 case vmIntrinsics::_dlog: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2586 case vmIntrinsics::_dlog10: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2587 case vmIntrinsics::_dabs: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2588 case vmIntrinsics::_dsqrt: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2589 case vmIntrinsics::_dtan: // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2590 case vmIntrinsics::_dsin : // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
2591 case vmIntrinsics::_dcos : do_MathIntrinsic(x); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2592 case vmIntrinsics::_arraycopy: do_ArrayCopy(x); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2593
a61af66fc99e Initial load
duke
parents:
diff changeset
2594 // java.nio.Buffer.checkIndex
a61af66fc99e Initial load
duke
parents:
diff changeset
2595 case vmIntrinsics::_checkIndex: do_NIOCheckIndex(x); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2596
a61af66fc99e Initial load
duke
parents:
diff changeset
2597 case vmIntrinsics::_compareAndSwapObject:
a61af66fc99e Initial load
duke
parents:
diff changeset
2598 do_CompareAndSwap(x, objectType);
a61af66fc99e Initial load
duke
parents:
diff changeset
2599 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2600 case vmIntrinsics::_compareAndSwapInt:
a61af66fc99e Initial load
duke
parents:
diff changeset
2601 do_CompareAndSwap(x, intType);
a61af66fc99e Initial load
duke
parents:
diff changeset
2602 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2603 case vmIntrinsics::_compareAndSwapLong:
a61af66fc99e Initial load
duke
parents:
diff changeset
2604 do_CompareAndSwap(x, longType);
a61af66fc99e Initial load
duke
parents:
diff changeset
2605 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2606
a61af66fc99e Initial load
duke
parents:
diff changeset
2607 // sun.misc.AtomicLongCSImpl.attemptUpdate
a61af66fc99e Initial load
duke
parents:
diff changeset
2608 case vmIntrinsics::_attemptUpdate:
a61af66fc99e Initial load
duke
parents:
diff changeset
2609 do_AttemptUpdate(x);
a61af66fc99e Initial load
duke
parents:
diff changeset
2610 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2611
a61af66fc99e Initial load
duke
parents:
diff changeset
2612 default: ShouldNotReachHere(); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2613 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2614 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2615
a61af66fc99e Initial load
duke
parents:
diff changeset
2616
a61af66fc99e Initial load
duke
parents:
diff changeset
2617 void LIRGenerator::do_ProfileCall(ProfileCall* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2618 // Need recv in a temporary register so it interferes with the other temporaries
a61af66fc99e Initial load
duke
parents:
diff changeset
2619 LIR_Opr recv = LIR_OprFact::illegalOpr;
a61af66fc99e Initial load
duke
parents:
diff changeset
2620 LIR_Opr mdo = new_register(T_OBJECT);
a61af66fc99e Initial load
duke
parents:
diff changeset
2621 LIR_Opr tmp = new_register(T_INT);
a61af66fc99e Initial load
duke
parents:
diff changeset
2622 if (x->recv() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2623 LIRItem value(x->recv(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2624 value.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2625 recv = new_register(T_OBJECT);
a61af66fc99e Initial load
duke
parents:
diff changeset
2626 __ move(value.result(), recv);
a61af66fc99e Initial load
duke
parents:
diff changeset
2627 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2628 __ profile_call(x->method(), x->bci_of_invoke(), mdo, recv, tmp, x->known_holder());
a61af66fc99e Initial load
duke
parents:
diff changeset
2629 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2630
a61af66fc99e Initial load
duke
parents:
diff changeset
2631
a61af66fc99e Initial load
duke
parents:
diff changeset
2632 void LIRGenerator::do_ProfileCounter(ProfileCounter* x) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2633 LIRItem mdo(x->mdo(), this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2634 mdo.load_item();
a61af66fc99e Initial load
duke
parents:
diff changeset
2635
a61af66fc99e Initial load
duke
parents:
diff changeset
2636 increment_counter(new LIR_Address(mdo.result(), x->offset(), T_INT), x->increment());
a61af66fc99e Initial load
duke
parents:
diff changeset
2637 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2638
a61af66fc99e Initial load
duke
parents:
diff changeset
2639
a61af66fc99e Initial load
duke
parents:
diff changeset
2640 LIR_Opr LIRGenerator::call_runtime(Value arg1, address entry, ValueType* result_type, CodeEmitInfo* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2641 LIRItemList args(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2642 LIRItem value(arg1, this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2643 args.append(&value);
a61af66fc99e Initial load
duke
parents:
diff changeset
2644 BasicTypeList signature;
a61af66fc99e Initial load
duke
parents:
diff changeset
2645 signature.append(as_BasicType(arg1->type()));
a61af66fc99e Initial load
duke
parents:
diff changeset
2646
a61af66fc99e Initial load
duke
parents:
diff changeset
2647 return call_runtime(&signature, &args, entry, result_type, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
2648 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2649
a61af66fc99e Initial load
duke
parents:
diff changeset
2650
a61af66fc99e Initial load
duke
parents:
diff changeset
2651 LIR_Opr LIRGenerator::call_runtime(Value arg1, Value arg2, address entry, ValueType* result_type, CodeEmitInfo* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2652 LIRItemList args(2);
a61af66fc99e Initial load
duke
parents:
diff changeset
2653 LIRItem value1(arg1, this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2654 LIRItem value2(arg2, this);
a61af66fc99e Initial load
duke
parents:
diff changeset
2655 args.append(&value1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2656 args.append(&value2);
a61af66fc99e Initial load
duke
parents:
diff changeset
2657 BasicTypeList signature;
a61af66fc99e Initial load
duke
parents:
diff changeset
2658 signature.append(as_BasicType(arg1->type()));
a61af66fc99e Initial load
duke
parents:
diff changeset
2659 signature.append(as_BasicType(arg2->type()));
a61af66fc99e Initial load
duke
parents:
diff changeset
2660
a61af66fc99e Initial load
duke
parents:
diff changeset
2661 return call_runtime(&signature, &args, entry, result_type, info);
a61af66fc99e Initial load
duke
parents:
diff changeset
2662 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2663
a61af66fc99e Initial load
duke
parents:
diff changeset
2664
a61af66fc99e Initial load
duke
parents:
diff changeset
2665 LIR_Opr LIRGenerator::call_runtime(BasicTypeArray* signature, LIR_OprList* args,
a61af66fc99e Initial load
duke
parents:
diff changeset
2666 address entry, ValueType* result_type, CodeEmitInfo* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2667 // get a result register
a61af66fc99e Initial load
duke
parents:
diff changeset
2668 LIR_Opr phys_reg = LIR_OprFact::illegalOpr;
a61af66fc99e Initial load
duke
parents:
diff changeset
2669 LIR_Opr result = LIR_OprFact::illegalOpr;
a61af66fc99e Initial load
duke
parents:
diff changeset
2670 if (result_type->tag() != voidTag) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2671 result = new_register(result_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2672 phys_reg = result_register_for(result_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2673 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2674
a61af66fc99e Initial load
duke
parents:
diff changeset
2675 // move the arguments into the correct location
a61af66fc99e Initial load
duke
parents:
diff changeset
2676 CallingConvention* cc = frame_map()->c_calling_convention(signature);
a61af66fc99e Initial load
duke
parents:
diff changeset
2677 assert(cc->length() == args->length(), "argument mismatch");
a61af66fc99e Initial load
duke
parents:
diff changeset
2678 for (int i = 0; i < args->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2679 LIR_Opr arg = args->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2680 LIR_Opr loc = cc->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2681 if (loc->is_register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2682 __ move(arg, loc);
a61af66fc99e Initial load
duke
parents:
diff changeset
2683 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2684 LIR_Address* addr = loc->as_address_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2685 // if (!can_store_as_constant(arg)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2686 // LIR_Opr tmp = new_register(arg->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
2687 // __ move(arg, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2688 // arg = tmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
2689 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
2690 if (addr->type() == T_LONG || addr->type() == T_DOUBLE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2691 __ unaligned_move(arg, addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2692 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2693 __ move(arg, addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2694 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2695 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2696 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2697
a61af66fc99e Initial load
duke
parents:
diff changeset
2698 if (info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2699 __ call_runtime(entry, getThreadTemp(), phys_reg, cc->args(), info);
a61af66fc99e Initial load
duke
parents:
diff changeset
2700 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2701 __ call_runtime_leaf(entry, getThreadTemp(), phys_reg, cc->args());
a61af66fc99e Initial load
duke
parents:
diff changeset
2702 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2703 if (result->is_valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2704 __ move(phys_reg, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
2705 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2706 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
2707 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2708
a61af66fc99e Initial load
duke
parents:
diff changeset
2709
a61af66fc99e Initial load
duke
parents:
diff changeset
2710 LIR_Opr LIRGenerator::call_runtime(BasicTypeArray* signature, LIRItemList* args,
a61af66fc99e Initial load
duke
parents:
diff changeset
2711 address entry, ValueType* result_type, CodeEmitInfo* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2712 // get a result register
a61af66fc99e Initial load
duke
parents:
diff changeset
2713 LIR_Opr phys_reg = LIR_OprFact::illegalOpr;
a61af66fc99e Initial load
duke
parents:
diff changeset
2714 LIR_Opr result = LIR_OprFact::illegalOpr;
a61af66fc99e Initial load
duke
parents:
diff changeset
2715 if (result_type->tag() != voidTag) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2716 result = new_register(result_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2717 phys_reg = result_register_for(result_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
2718 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2719
a61af66fc99e Initial load
duke
parents:
diff changeset
2720 // move the arguments into the correct location
a61af66fc99e Initial load
duke
parents:
diff changeset
2721 CallingConvention* cc = frame_map()->c_calling_convention(signature);
a61af66fc99e Initial load
duke
parents:
diff changeset
2722
a61af66fc99e Initial load
duke
parents:
diff changeset
2723 assert(cc->length() == args->length(), "argument mismatch");
a61af66fc99e Initial load
duke
parents:
diff changeset
2724 for (int i = 0; i < args->length(); i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2725 LIRItem* arg = args->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2726 LIR_Opr loc = cc->at(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2727 if (loc->is_register()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2728 arg->load_item_force(loc);
a61af66fc99e Initial load
duke
parents:
diff changeset
2729 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2730 LIR_Address* addr = loc->as_address_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2731 arg->load_for_store(addr->type());
a61af66fc99e Initial load
duke
parents:
diff changeset
2732 if (addr->type() == T_LONG || addr->type() == T_DOUBLE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2733 __ unaligned_move(arg->result(), addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2734 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2735 __ move(arg->result(), addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2736 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2737 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2738 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2739
a61af66fc99e Initial load
duke
parents:
diff changeset
2740 if (info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2741 __ call_runtime(entry, getThreadTemp(), phys_reg, cc->args(), info);
a61af66fc99e Initial load
duke
parents:
diff changeset
2742 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2743 __ call_runtime_leaf(entry, getThreadTemp(), phys_reg, cc->args());
a61af66fc99e Initial load
duke
parents:
diff changeset
2744 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2745 if (result->is_valid()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2746 __ move(phys_reg, result);
a61af66fc99e Initial load
duke
parents:
diff changeset
2747 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2748 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
2749 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2750
a61af66fc99e Initial load
duke
parents:
diff changeset
2751
a61af66fc99e Initial load
duke
parents:
diff changeset
2752
a61af66fc99e Initial load
duke
parents:
diff changeset
2753 void LIRGenerator::increment_invocation_counter(CodeEmitInfo* info, bool backedge) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2754 #ifdef TIERED
a61af66fc99e Initial load
duke
parents:
diff changeset
2755 if (_compilation->env()->comp_level() == CompLevel_fast_compile &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2756 (method()->code_size() >= Tier1BytecodeLimit || backedge)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2757 int limit = InvocationCounter::Tier1InvocationLimit;
a61af66fc99e Initial load
duke
parents:
diff changeset
2758 int offset = in_bytes(methodOopDesc::invocation_counter_offset() +
a61af66fc99e Initial load
duke
parents:
diff changeset
2759 InvocationCounter::counter_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
2760 if (backedge) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2761 limit = InvocationCounter::Tier1BackEdgeLimit;
a61af66fc99e Initial load
duke
parents:
diff changeset
2762 offset = in_bytes(methodOopDesc::backedge_counter_offset() +
a61af66fc99e Initial load
duke
parents:
diff changeset
2763 InvocationCounter::counter_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
2764 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2765
a61af66fc99e Initial load
duke
parents:
diff changeset
2766 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
2767 __ oop2reg(method()->constant_encoding(), meth);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2768 LIR_Opr result = increment_and_return_counter(meth, offset, InvocationCounter::count_increment);
a61af66fc99e Initial load
duke
parents:
diff changeset
2769 __ cmp(lir_cond_aboveEqual, result, LIR_OprFact::intConst(limit));
a61af66fc99e Initial load
duke
parents:
diff changeset
2770 CodeStub* overflow = new CounterOverflowStub(info, info->bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
2771 __ branch(lir_cond_aboveEqual, T_INT, overflow);
a61af66fc99e Initial load
duke
parents:
diff changeset
2772 __ branch_destination(overflow->continuation());
a61af66fc99e Initial load
duke
parents:
diff changeset
2773 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2774 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2775 }