Mercurial > hg > graal-compiler
annotate src/share/vm/shark/sharkStack.cpp @ 10185:d50cc62e94ff
8012715: G1: GraphKit accesses PtrQueue::_index as int but is size_t
Summary: In graphKit INT operations were generated to access PtrQueue::_index which has type size_t. This is 64 bit on 64-bit machines. No problems occur on little endian machines as long as the index fits into 32 bit, but on big endian machines the upper part is read, which is zero. This leads to unnecessary branches to the slow path in the runtime.
Reviewed-by: twisti, johnc
Contributed-by: Martin Doerr <martin.doerr@sap.com>
author | johnc |
---|---|
date | Wed, 24 Apr 2013 14:48:43 -0700 |
parents | 2cd5e15048e6 |
children |
rev | line source |
---|---|
1692 | 1 /* |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1972
diff
changeset
|
2 * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. |
1692 | 3 * Copyright 2008, 2009, 2010 Red Hat, Inc. |
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
5 * | |
6 * This code is free software; you can redistribute it and/or modify it | |
7 * under the terms of the GNU General Public License version 2 only, as | |
8 * published by the Free Software Foundation. | |
9 * | |
10 * This code is distributed in the hope that it will be useful, but WITHOUT | |
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
13 * version 2 for more details (a copy is included in the LICENSE file that | |
14 * accompanied this code). | |
15 * | |
16 * You should have received a copy of the GNU General Public License version | |
17 * 2 along with this work; if not, write to the Free Software Foundation, | |
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
19 * | |
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
21 * or visit www.oracle.com if you need additional information or have any | |
22 * questions. | |
23 * | |
24 */ | |
25 | |
1972 | 26 #include "precompiled.hpp" |
27 #include "shark/llvmHeaders.hpp" | |
28 #include "shark/sharkFunction.hpp" | |
29 #include "shark/sharkNativeWrapper.hpp" | |
30 #include "shark/sharkStack.hpp" | |
31 #include "shark/sharkType.hpp" | |
1692 | 32 |
33 using namespace llvm; | |
34 | |
35 void SharkStack::initialize(Value* method) { | |
36 bool setup_sp_and_method = (method != NULL); | |
37 | |
38 int locals_words = max_locals(); | |
39 int extra_locals = locals_words - arg_size(); | |
40 int header_words = SharkFrame::header_words; | |
41 int monitor_words = max_monitors()*frame::interpreter_frame_monitor_size(); | |
42 int stack_words = max_stack(); | |
43 int frame_words = header_words + monitor_words + stack_words; | |
44 | |
45 _extended_frame_size = frame_words + locals_words; | |
46 | |
47 // Update the stack pointer | |
48 Value *stack_pointer = builder()->CreateSub( | |
49 CreateLoadStackPointer(), | |
50 LLVMValue::intptr_constant((frame_words + extra_locals) * wordSize)); | |
51 CreateStackOverflowCheck(stack_pointer); | |
52 if (setup_sp_and_method) | |
53 CreateStoreStackPointer(stack_pointer); | |
54 | |
55 // Create the frame | |
56 _frame = builder()->CreateIntToPtr( | |
57 stack_pointer, | |
58 PointerType::getUnqual( | |
59 ArrayType::get(SharkType::intptr_type(), extended_frame_size())), | |
60 "frame"); | |
61 int offset = 0; | |
62 | |
63 // Expression stack | |
64 _stack_slots_offset = offset; | |
65 offset += stack_words; | |
66 | |
67 // Monitors | |
68 _monitors_slots_offset = offset; | |
69 offset += monitor_words; | |
70 | |
71 // Temporary oop slot | |
72 _oop_tmp_slot_offset = offset++; | |
73 | |
74 // Method pointer | |
75 _method_slot_offset = offset++; | |
76 if (setup_sp_and_method) { | |
77 builder()->CreateStore( | |
7195 | 78 method, slot_addr(method_slot_offset(), SharkType::Method_type())); |
1692 | 79 } |
80 | |
81 // Unextended SP | |
82 builder()->CreateStore(stack_pointer, slot_addr(offset++)); | |
83 | |
84 // PC | |
85 _pc_slot_offset = offset++; | |
86 | |
87 // Frame header | |
88 builder()->CreateStore( | |
89 LLVMValue::intptr_constant(ZeroFrame::SHARK_FRAME), slot_addr(offset++)); | |
90 Value *fp = slot_addr(offset++); | |
91 | |
92 // Local variables | |
93 _locals_slots_offset = offset; | |
94 offset += locals_words; | |
95 | |
96 // Push the frame | |
97 assert(offset == extended_frame_size(), "should do"); | |
98 builder()->CreateStore(CreateLoadFramePointer(), fp); | |
99 CreateStoreFramePointer( | |
100 builder()->CreatePtrToInt(fp, SharkType::intptr_type())); | |
101 } | |
102 | |
103 // This function should match ZeroStack::overflow_check | |
104 void SharkStack::CreateStackOverflowCheck(Value* sp) { | |
105 BasicBlock *zero_ok = CreateBlock("zero_stack_ok"); | |
106 BasicBlock *overflow = CreateBlock("stack_overflow"); | |
107 BasicBlock *abi_ok = CreateBlock("abi_stack_ok"); | |
108 | |
109 // Check the Zero stack | |
110 builder()->CreateCondBr( | |
111 builder()->CreateICmpULT(sp, stack_base()), | |
112 overflow, zero_ok); | |
113 | |
114 // Check the ABI stack | |
115 builder()->SetInsertPoint(zero_ok); | |
116 Value *stack_top = builder()->CreateSub( | |
117 builder()->CreateValueOfStructEntry( | |
118 thread(), | |
119 Thread::stack_base_offset(), | |
120 SharkType::intptr_type(), | |
121 "abi_base"), | |
122 builder()->CreateValueOfStructEntry( | |
123 thread(), | |
124 Thread::stack_size_offset(), | |
125 SharkType::intptr_type(), | |
126 "abi_size")); | |
127 Value *free_stack = builder()->CreateSub( | |
128 builder()->CreatePtrToInt( | |
129 builder()->CreateGetFrameAddress(), | |
130 SharkType::intptr_type(), | |
131 "abi_sp"), | |
132 stack_top); | |
133 builder()->CreateCondBr( | |
134 builder()->CreateICmpULT( | |
135 free_stack, | |
136 LLVMValue::intptr_constant(StackShadowPages * os::vm_page_size())), | |
137 overflow, abi_ok); | |
138 | |
139 // Handle overflows | |
140 builder()->SetInsertPoint(overflow); | |
141 builder()->CreateCall(builder()->throw_StackOverflowError(), thread()); | |
142 builder()->CreateRet(LLVMValue::jint_constant(0)); | |
143 | |
144 builder()->SetInsertPoint(abi_ok); | |
145 } | |
146 | |
147 Value* SharkStack::CreatePopFrame(int result_slots) { | |
148 assert(result_slots >= 0 && result_slots <= 2, "should be"); | |
149 int locals_to_pop = max_locals() - result_slots; | |
150 | |
151 Value *fp = CreateLoadFramePointer(); | |
152 Value *sp = builder()->CreateAdd( | |
153 fp, | |
154 LLVMValue::intptr_constant((1 + locals_to_pop) * wordSize)); | |
155 | |
156 CreateStoreStackPointer(sp); | |
157 CreateStoreFramePointer( | |
158 builder()->CreateLoad( | |
159 builder()->CreateIntToPtr( | |
160 fp, PointerType::getUnqual(SharkType::intptr_type())))); | |
161 | |
162 return sp; | |
163 } | |
164 | |
165 Value* SharkStack::slot_addr(int offset, | |
7195 | 166 Type* type, |
1692 | 167 const char* name) const { |
168 bool needs_cast = type && type != SharkType::intptr_type(); | |
169 | |
170 Value* result = builder()->CreateStructGEP( | |
171 _frame, offset, needs_cast ? "" : name); | |
172 | |
173 if (needs_cast) { | |
174 result = builder()->CreateBitCast( | |
175 result, PointerType::getUnqual(type), name); | |
176 } | |
177 return result; | |
178 } | |
179 | |
180 // The bits that differentiate stacks with normal and native frames on top | |
181 | |
182 SharkStack* SharkStack::CreateBuildAndPushFrame(SharkFunction* function, | |
183 Value* method) { | |
184 return new SharkStackWithNormalFrame(function, method); | |
185 } | |
186 SharkStack* SharkStack::CreateBuildAndPushFrame(SharkNativeWrapper* wrapper, | |
187 Value* method) { | |
188 return new SharkStackWithNativeFrame(wrapper, method); | |
189 } | |
190 | |
191 SharkStackWithNormalFrame::SharkStackWithNormalFrame(SharkFunction* function, | |
192 Value* method) | |
193 : SharkStack(function), _function(function) { | |
194 // For normal frames, the stack pointer and the method slot will | |
195 // be set during each decache, so it is not necessary to do them | |
196 // at the time the frame is created. However, we set them for | |
197 // non-PRODUCT builds to make crash dumps easier to understand. | |
198 initialize(PRODUCT_ONLY(NULL) NOT_PRODUCT(method)); | |
199 } | |
200 SharkStackWithNativeFrame::SharkStackWithNativeFrame(SharkNativeWrapper* wrp, | |
201 Value* method) | |
202 : SharkStack(wrp), _wrapper(wrp) { | |
203 initialize(method); | |
204 } | |
205 | |
206 int SharkStackWithNormalFrame::arg_size() const { | |
207 return function()->arg_size(); | |
208 } | |
209 int SharkStackWithNativeFrame::arg_size() const { | |
210 return wrapper()->arg_size(); | |
211 } | |
212 | |
213 int SharkStackWithNormalFrame::max_locals() const { | |
214 return function()->max_locals(); | |
215 } | |
216 int SharkStackWithNativeFrame::max_locals() const { | |
217 return wrapper()->arg_size(); | |
218 } | |
219 | |
220 int SharkStackWithNormalFrame::max_stack() const { | |
221 return function()->max_stack(); | |
222 } | |
223 int SharkStackWithNativeFrame::max_stack() const { | |
224 return 0; | |
225 } | |
226 | |
227 int SharkStackWithNormalFrame::max_monitors() const { | |
228 return function()->max_monitors(); | |
229 } | |
230 int SharkStackWithNativeFrame::max_monitors() const { | |
231 return wrapper()->is_synchronized() ? 1 : 0; | |
232 } | |
233 | |
234 BasicBlock* SharkStackWithNormalFrame::CreateBlock(const char* name) const { | |
235 return function()->CreateBlock(name); | |
236 } | |
237 BasicBlock* SharkStackWithNativeFrame::CreateBlock(const char* name) const { | |
238 return wrapper()->CreateBlock(name); | |
239 } | |
240 | |
241 address SharkStackWithNormalFrame::interpreter_entry_point() const { | |
242 return (address) CppInterpreter::normal_entry; | |
243 } | |
244 address SharkStackWithNativeFrame::interpreter_entry_point() const { | |
245 return (address) CppInterpreter::native_entry; | |
246 } | |
247 | |
248 #ifndef PRODUCT | |
249 void SharkStack::CreateAssertLastJavaSPIsNull() const { | |
250 #ifdef ASSERT | |
251 BasicBlock *fail = CreateBlock("assert_failed"); | |
252 BasicBlock *pass = CreateBlock("assert_ok"); | |
253 | |
254 builder()->CreateCondBr( | |
255 builder()->CreateICmpEQ( | |
256 builder()->CreateLoad(last_Java_sp_addr()), | |
257 LLVMValue::intptr_constant(0)), | |
258 pass, fail); | |
259 | |
260 builder()->SetInsertPoint(fail); | |
261 builder()->CreateShouldNotReachHere(__FILE__, __LINE__); | |
262 builder()->CreateUnreachable(); | |
263 | |
264 builder()->SetInsertPoint(pass); | |
265 #endif // ASSERT | |
266 } | |
267 #endif // !PRODUCT |