Mercurial > hg > truffle
annotate src/share/vm/shark/sharkBuilder.cpp @ 11646:8f8f6afeb97a
New caching mechanism in TruffleCache for better compilation performance. Clean up of partial evaluator phases.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Sun, 15 Sep 2013 16:27:07 +0200 |
parents | e0c9a1d29eb4 |
children | de6a9e811145 |
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 "ci/ciMethod.hpp" | |
28 #include "memory/resourceArea.hpp" | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
1972
diff
changeset
|
29 #include "oops/method.hpp" |
1972 | 30 #include "runtime/os.hpp" |
31 #include "runtime/synchronizer.hpp" | |
32 #include "runtime/thread.hpp" | |
33 #include "shark/llvmHeaders.hpp" | |
34 #include "shark/llvmValue.hpp" | |
35 #include "shark/sharkBuilder.hpp" | |
36 #include "shark/sharkContext.hpp" | |
37 #include "shark/sharkRuntime.hpp" | |
38 #include "utilities/debug.hpp" | |
1692 | 39 |
40 using namespace llvm; | |
41 | |
42 SharkBuilder::SharkBuilder(SharkCodeBuffer* code_buffer) | |
43 : IRBuilder<>(SharkContext::current()), | |
44 _code_buffer(code_buffer) { | |
45 } | |
46 | |
47 // Helpers for accessing structures | |
48 Value* SharkBuilder::CreateAddressOfStructEntry(Value* base, | |
49 ByteSize offset, | |
7195 | 50 Type* type, |
1692 | 51 const char* name) { |
52 return CreateBitCast(CreateStructGEP(base, in_bytes(offset)), type, name); | |
53 } | |
54 | |
55 LoadInst* SharkBuilder::CreateValueOfStructEntry(Value* base, | |
56 ByteSize offset, | |
7195 | 57 Type* type, |
1692 | 58 const char* name) { |
59 return CreateLoad( | |
60 CreateAddressOfStructEntry( | |
61 base, offset, PointerType::getUnqual(type)), | |
62 name); | |
63 } | |
64 | |
65 // Helpers for accessing arrays | |
66 | |
67 LoadInst* SharkBuilder::CreateArrayLength(Value* arrayoop) { | |
68 return CreateValueOfStructEntry( | |
69 arrayoop, in_ByteSize(arrayOopDesc::length_offset_in_bytes()), | |
70 SharkType::jint_type(), "length"); | |
71 } | |
72 | |
73 Value* SharkBuilder::CreateArrayAddress(Value* arrayoop, | |
7195 | 74 Type* element_type, |
1692 | 75 int element_bytes, |
76 ByteSize base_offset, | |
77 Value* index, | |
78 const char* name) { | |
79 Value* offset = CreateIntCast(index, SharkType::intptr_type(), false); | |
80 if (element_bytes != 1) | |
81 offset = CreateShl( | |
82 offset, | |
83 LLVMValue::intptr_constant(exact_log2(element_bytes))); | |
84 offset = CreateAdd( | |
85 LLVMValue::intptr_constant(in_bytes(base_offset)), offset); | |
86 | |
87 return CreateIntToPtr( | |
88 CreateAdd(CreatePtrToInt(arrayoop, SharkType::intptr_type()), offset), | |
89 PointerType::getUnqual(element_type), | |
90 name); | |
91 } | |
92 | |
93 Value* SharkBuilder::CreateArrayAddress(Value* arrayoop, | |
94 BasicType basic_type, | |
95 ByteSize base_offset, | |
96 Value* index, | |
97 const char* name) { | |
98 return CreateArrayAddress( | |
99 arrayoop, | |
100 SharkType::to_arrayType(basic_type), | |
101 type2aelembytes(basic_type), | |
102 base_offset, index, name); | |
103 } | |
104 | |
105 Value* SharkBuilder::CreateArrayAddress(Value* arrayoop, | |
106 BasicType basic_type, | |
107 Value* index, | |
108 const char* name) { | |
109 return CreateArrayAddress( | |
110 arrayoop, basic_type, | |
111 in_ByteSize(arrayOopDesc::base_offset_in_bytes(basic_type)), | |
112 index, name); | |
113 } | |
114 | |
115 // Helpers for creating intrinsics and external functions. | |
116 | |
7195 | 117 Type* SharkBuilder::make_type(char type, bool void_ok) { |
1692 | 118 switch (type) { |
119 // Primitive types | |
120 case 'c': | |
121 return SharkType::jbyte_type(); | |
122 case 'i': | |
123 return SharkType::jint_type(); | |
124 case 'l': | |
125 return SharkType::jlong_type(); | |
126 case 'x': | |
127 return SharkType::intptr_type(); | |
128 case 'f': | |
129 return SharkType::jfloat_type(); | |
130 case 'd': | |
131 return SharkType::jdouble_type(); | |
132 | |
133 // Pointers to primitive types | |
134 case 'C': | |
135 case 'I': | |
136 case 'L': | |
137 case 'X': | |
138 case 'F': | |
139 case 'D': | |
140 return PointerType::getUnqual(make_type(tolower(type), false)); | |
141 | |
142 // VM objects | |
143 case 'T': | |
144 return SharkType::thread_type(); | |
145 case 'M': | |
146 return PointerType::getUnqual(SharkType::monitor_type()); | |
147 case 'O': | |
148 return SharkType::oop_type(); | |
7195 | 149 case 'K': |
150 return SharkType::klass_type(); | |
1692 | 151 |
152 // Miscellaneous | |
153 case 'v': | |
154 assert(void_ok, "should be"); | |
155 return SharkType::void_type(); | |
156 case '1': | |
157 return SharkType::bit_type(); | |
158 | |
159 default: | |
160 ShouldNotReachHere(); | |
161 } | |
162 } | |
163 | |
7195 | 164 FunctionType* SharkBuilder::make_ftype(const char* params, |
1692 | 165 const char* ret) { |
7195 | 166 std::vector<Type*> param_types; |
1692 | 167 for (const char* c = params; *c; c++) |
168 param_types.push_back(make_type(*c, false)); | |
169 | |
170 assert(strlen(ret) == 1, "should be"); | |
7195 | 171 Type *return_type = make_type(*ret, true); |
1692 | 172 |
173 return FunctionType::get(return_type, param_types, false); | |
174 } | |
175 | |
176 // Create an object representing an intrinsic or external function by | |
177 // referencing the symbol by name. This is the LLVM-style approach, | |
178 // but it cannot be used on functions within libjvm.so its symbols | |
179 // are not exported. Note that you cannot make this work simply by | |
180 // exporting the symbols, as some symbols have the same names as | |
181 // symbols in the standard libraries (eg, atan2, fabs) and would | |
182 // obscure them were they visible. | |
183 Value* SharkBuilder::make_function(const char* name, | |
184 const char* params, | |
185 const char* ret) { | |
186 return SharkContext::current().get_external(name, make_ftype(params, ret)); | |
187 } | |
188 | |
189 // Create an object representing an external function by inlining a | |
190 // function pointer in the code. This is not the LLVM way, but it's | |
191 // the only way to access functions in libjvm.so and functions like | |
192 // __kernel_dmb on ARM which is accessed via an absolute address. | |
193 Value* SharkBuilder::make_function(address func, | |
194 const char* params, | |
195 const char* ret) { | |
196 return CreateIntToPtr( | |
197 LLVMValue::intptr_constant((intptr_t) func), | |
198 PointerType::getUnqual(make_ftype(params, ret))); | |
199 } | |
200 | |
201 // VM calls | |
202 | |
203 Value* SharkBuilder::find_exception_handler() { | |
204 return make_function( | |
205 (address) SharkRuntime::find_exception_handler, "TIi", "i"); | |
206 } | |
207 | |
208 Value* SharkBuilder::monitorenter() { | |
209 return make_function((address) SharkRuntime::monitorenter, "TM", "v"); | |
210 } | |
211 | |
212 Value* SharkBuilder::monitorexit() { | |
213 return make_function((address) SharkRuntime::monitorexit, "TM", "v"); | |
214 } | |
215 | |
216 Value* SharkBuilder::new_instance() { | |
217 return make_function((address) SharkRuntime::new_instance, "Ti", "v"); | |
218 } | |
219 | |
220 Value* SharkBuilder::newarray() { | |
221 return make_function((address) SharkRuntime::newarray, "Tii", "v"); | |
222 } | |
223 | |
224 Value* SharkBuilder::anewarray() { | |
225 return make_function((address) SharkRuntime::anewarray, "Tii", "v"); | |
226 } | |
227 | |
228 Value* SharkBuilder::multianewarray() { | |
229 return make_function((address) SharkRuntime::multianewarray, "TiiI", "v"); | |
230 } | |
231 | |
232 Value* SharkBuilder::register_finalizer() { | |
233 return make_function((address) SharkRuntime::register_finalizer, "TO", "v"); | |
234 } | |
235 | |
236 Value* SharkBuilder::safepoint() { | |
237 return make_function((address) SafepointSynchronize::block, "T", "v"); | |
238 } | |
239 | |
240 Value* SharkBuilder::throw_ArithmeticException() { | |
241 return make_function( | |
242 (address) SharkRuntime::throw_ArithmeticException, "TCi", "v"); | |
243 } | |
244 | |
245 Value* SharkBuilder::throw_ArrayIndexOutOfBoundsException() { | |
246 return make_function( | |
247 (address) SharkRuntime::throw_ArrayIndexOutOfBoundsException, "TCii", "v"); | |
248 } | |
249 | |
250 Value* SharkBuilder::throw_ClassCastException() { | |
251 return make_function( | |
252 (address) SharkRuntime::throw_ClassCastException, "TCi", "v"); | |
253 } | |
254 | |
255 Value* SharkBuilder::throw_NullPointerException() { | |
256 return make_function( | |
257 (address) SharkRuntime::throw_NullPointerException, "TCi", "v"); | |
258 } | |
259 | |
260 // High-level non-VM calls | |
261 | |
262 Value* SharkBuilder::f2i() { | |
263 return make_function((address) SharedRuntime::f2i, "f", "i"); | |
264 } | |
265 | |
266 Value* SharkBuilder::f2l() { | |
267 return make_function((address) SharedRuntime::f2l, "f", "l"); | |
268 } | |
269 | |
270 Value* SharkBuilder::d2i() { | |
271 return make_function((address) SharedRuntime::d2i, "d", "i"); | |
272 } | |
273 | |
274 Value* SharkBuilder::d2l() { | |
275 return make_function((address) SharedRuntime::d2l, "d", "l"); | |
276 } | |
277 | |
278 Value* SharkBuilder::is_subtype_of() { | |
7195 | 279 return make_function((address) SharkRuntime::is_subtype_of, "KK", "c"); |
1692 | 280 } |
281 | |
282 Value* SharkBuilder::current_time_millis() { | |
283 return make_function((address) os::javaTimeMillis, "", "l"); | |
284 } | |
285 | |
286 Value* SharkBuilder::sin() { | |
287 return make_function("llvm.sin.f64", "d", "d"); | |
288 } | |
289 | |
290 Value* SharkBuilder::cos() { | |
291 return make_function("llvm.cos.f64", "d", "d"); | |
292 } | |
293 | |
294 Value* SharkBuilder::tan() { | |
295 return make_function((address) ::tan, "d", "d"); | |
296 } | |
297 | |
298 Value* SharkBuilder::atan2() { | |
299 return make_function((address) ::atan2, "dd", "d"); | |
300 } | |
301 | |
302 Value* SharkBuilder::sqrt() { | |
303 return make_function("llvm.sqrt.f64", "d", "d"); | |
304 } | |
305 | |
306 Value* SharkBuilder::log() { | |
307 return make_function("llvm.log.f64", "d", "d"); | |
308 } | |
309 | |
310 Value* SharkBuilder::log10() { | |
311 return make_function("llvm.log10.f64", "d", "d"); | |
312 } | |
313 | |
314 Value* SharkBuilder::pow() { | |
315 return make_function("llvm.pow.f64", "dd", "d"); | |
316 } | |
317 | |
318 Value* SharkBuilder::exp() { | |
319 return make_function("llvm.exp.f64", "d", "d"); | |
320 } | |
321 | |
322 Value* SharkBuilder::fabs() { | |
323 return make_function((address) ::fabs, "d", "d"); | |
324 } | |
325 | |
326 Value* SharkBuilder::unsafe_field_offset_to_byte_offset() { | |
327 extern jlong Unsafe_field_offset_to_byte_offset(jlong field_offset); | |
328 return make_function((address) Unsafe_field_offset_to_byte_offset, "l", "l"); | |
329 } | |
330 | |
331 Value* SharkBuilder::osr_migration_end() { | |
332 return make_function((address) SharedRuntime::OSR_migration_end, "C", "v"); | |
333 } | |
334 | |
335 // Semi-VM calls | |
336 | |
337 Value* SharkBuilder::throw_StackOverflowError() { | |
338 return make_function((address) ZeroStack::handle_overflow, "T", "v"); | |
339 } | |
340 | |
341 Value* SharkBuilder::uncommon_trap() { | |
342 return make_function((address) SharkRuntime::uncommon_trap, "Ti", "i"); | |
343 } | |
344 | |
345 Value* SharkBuilder::deoptimized_entry_point() { | |
346 return make_function((address) CppInterpreter::main_loop, "iT", "v"); | |
347 } | |
348 | |
349 // Native-Java transition | |
350 | |
351 Value* SharkBuilder::check_special_condition_for_native_trans() { | |
352 return make_function( | |
353 (address) JavaThread::check_special_condition_for_native_trans, | |
354 "T", "v"); | |
355 } | |
356 | |
357 Value* SharkBuilder::frame_address() { | |
358 return make_function("llvm.frameaddress", "i", "C"); | |
359 } | |
360 | |
361 Value* SharkBuilder::memset() { | |
362 // LLVM 2.8 added a fifth isVolatile field for memset | |
363 // introduced with LLVM r100304 | |
7195 | 364 return make_function("llvm.memset.p0i8.i32", "Cciii", "v"); |
1692 | 365 } |
366 | |
367 Value* SharkBuilder::unimplemented() { | |
368 return make_function((address) report_unimplemented, "Ci", "v"); | |
369 } | |
370 | |
371 Value* SharkBuilder::should_not_reach_here() { | |
372 return make_function((address) report_should_not_reach_here, "Ci", "v"); | |
373 } | |
374 | |
375 Value* SharkBuilder::dump() { | |
376 return make_function((address) SharkRuntime::dump, "Cx", "v"); | |
377 } | |
378 | |
379 // Public interface to low-level non-VM calls | |
380 | |
381 CallInst* SharkBuilder::CreateGetFrameAddress() { | |
382 return CreateCall(frame_address(), LLVMValue::jint_constant(0)); | |
383 } | |
384 | |
385 CallInst* SharkBuilder::CreateMemset(Value* dst, | |
386 Value* value, | |
387 Value* len, | |
388 Value* align) { | |
389 return CreateCall5(memset(), dst, value, len, align, | |
390 LLVMValue::jint_constant(0)); | |
391 } | |
392 | |
393 CallInst* SharkBuilder::CreateUnimplemented(const char* file, int line) { | |
394 return CreateCall2( | |
395 unimplemented(), | |
396 CreateIntToPtr( | |
397 LLVMValue::intptr_constant((intptr_t) file), | |
398 PointerType::getUnqual(SharkType::jbyte_type())), | |
399 LLVMValue::jint_constant(line)); | |
400 } | |
401 | |
402 CallInst* SharkBuilder::CreateShouldNotReachHere(const char* file, int line) { | |
403 return CreateCall2( | |
404 should_not_reach_here(), | |
405 CreateIntToPtr( | |
406 LLVMValue::intptr_constant((intptr_t) file), | |
407 PointerType::getUnqual(SharkType::jbyte_type())), | |
408 LLVMValue::jint_constant(line)); | |
409 } | |
410 | |
411 #ifndef PRODUCT | |
412 CallInst* SharkBuilder::CreateDump(Value* value) { | |
413 const char *name; | |
414 if (value->hasName()) | |
415 // XXX this leaks, but it's only debug code | |
416 name = strdup(value->getName().str().c_str()); | |
417 else | |
418 name = "unnamed_value"; | |
419 | |
420 if (isa<PointerType>(value->getType())) | |
421 value = CreatePtrToInt(value, SharkType::intptr_type()); | |
422 else if (value->getType()-> | |
423 isIntegerTy() | |
424 ) | |
425 value = CreateIntCast(value, SharkType::intptr_type(), false); | |
426 else | |
427 Unimplemented(); | |
428 | |
429 return CreateCall2( | |
430 dump(), | |
431 CreateIntToPtr( | |
432 LLVMValue::intptr_constant((intptr_t) name), | |
433 PointerType::getUnqual(SharkType::jbyte_type())), | |
434 value); | |
435 } | |
436 #endif // PRODUCT | |
437 | |
438 // HotSpot memory barriers | |
439 | |
440 void SharkBuilder::CreateUpdateBarrierSet(BarrierSet* bs, Value* field) { | |
441 if (bs->kind() != BarrierSet::CardTableModRef) | |
442 Unimplemented(); | |
443 | |
444 CreateStore( | |
445 LLVMValue::jbyte_constant(CardTableModRefBS::dirty_card), | |
446 CreateIntToPtr( | |
447 CreateAdd( | |
448 LLVMValue::intptr_constant( | |
449 (intptr_t) ((CardTableModRefBS *) bs)->byte_map_base), | |
450 CreateLShr( | |
451 CreatePtrToInt(field, SharkType::intptr_type()), | |
452 LLVMValue::intptr_constant(CardTableModRefBS::card_shift))), | |
453 PointerType::getUnqual(SharkType::jbyte_type()))); | |
454 } | |
455 | |
456 // Helpers for accessing the code buffer | |
457 | |
458 Value* SharkBuilder::code_buffer_address(int offset) { | |
459 return CreateAdd( | |
460 code_buffer()->base_pc(), | |
461 LLVMValue::intptr_constant(offset)); | |
462 } | |
463 | |
464 Value* SharkBuilder::CreateInlineOop(jobject object, const char* name) { | |
465 return CreateLoad( | |
466 CreateIntToPtr( | |
467 code_buffer_address(code_buffer()->inline_oop(object)), | |
468 PointerType::getUnqual(SharkType::oop_type())), | |
469 name); | |
470 } | |
471 | |
7195 | 472 Value* SharkBuilder::CreateInlineMetadata(Metadata* metadata, llvm::PointerType* type, const char* name) { |
473 assert(metadata != NULL, "inlined metadata must not be NULL"); | |
11034 | 474 assert(metadata->is_metaspace_object(), "sanity check"); |
7195 | 475 return CreateLoad( |
476 CreateIntToPtr( | |
477 code_buffer_address(code_buffer()->inline_Metadata(metadata)), | |
478 PointerType::getUnqual(type)), | |
479 name); | |
480 } | |
481 | |
1692 | 482 Value* SharkBuilder::CreateInlineData(void* data, |
483 size_t size, | |
7195 | 484 Type* type, |
1692 | 485 const char* name) { |
486 return CreateIntToPtr( | |
487 code_buffer_address(code_buffer()->inline_data(data, size)), | |
488 type, | |
489 name); | |
490 } | |
491 | |
492 // Helpers for creating basic blocks. | |
493 | |
494 BasicBlock* SharkBuilder::GetBlockInsertionPoint() const { | |
495 BasicBlock *cur = GetInsertBlock(); | |
496 | |
497 // BasicBlock::Create takes an insertBefore argument, so | |
498 // we need to find the block _after_ the current block | |
499 Function::iterator iter = cur->getParent()->begin(); | |
500 Function::iterator end = cur->getParent()->end(); | |
501 while (iter != end) { | |
502 iter++; | |
503 if (&*iter == cur) { | |
504 iter++; | |
505 break; | |
506 } | |
507 } | |
508 | |
509 if (iter == end) | |
510 return NULL; | |
511 else | |
512 return iter; | |
513 } | |
514 | |
515 BasicBlock* SharkBuilder::CreateBlock(BasicBlock* ip, const char* name) const { | |
516 return BasicBlock::Create( | |
517 SharkContext::current(), name, GetInsertBlock()->getParent(), ip); | |
518 } | |
7195 | 519 |
520 LoadInst* SharkBuilder::CreateAtomicLoad(Value* ptr, unsigned align, AtomicOrdering ordering, SynchronizationScope synchScope, bool isVolatile, const char* name) { | |
521 return Insert(new LoadInst(ptr, name, isVolatile, align, ordering, synchScope), name); | |
522 } | |
523 | |
524 StoreInst* SharkBuilder::CreateAtomicStore(Value* val, Value* ptr, unsigned align, AtomicOrdering ordering, SynchronizationScope synchScope, bool isVolatile, const char* name) { | |
525 return Insert(new StoreInst(val, ptr, isVolatile, align, ordering, synchScope), name); | |
526 } |