src/share/vm/shark/sharkBuilder.cpp

Sat, 01 Sep 2012 13:25:18 -0400

author
coleenp
date
Sat, 01 Sep 2012 13:25:18 -0400
changeset 4037
da91efe96a93
parent 2314
f95d63e2154a
child 4314
2cd5e15048e6
permissions
-rw-r--r--

6964458: Reimplement class meta-data storage to use native memory
Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes
Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland
Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>

     1 /*
     2  * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
     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  */
    26 #include "precompiled.hpp"
    27 #include "ci/ciMethod.hpp"
    28 #include "memory/resourceArea.hpp"
    29 #include "oops/method.hpp"
    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"
    40 using namespace llvm;
    42 SharkBuilder::SharkBuilder(SharkCodeBuffer* code_buffer)
    43   : IRBuilder<>(SharkContext::current()),
    44     _code_buffer(code_buffer) {
    45 }
    47 // Helpers for accessing structures
    48 Value* SharkBuilder::CreateAddressOfStructEntry(Value*      base,
    49                                                 ByteSize    offset,
    50                                                 const Type* type,
    51                                                 const char* name) {
    52   return CreateBitCast(CreateStructGEP(base, in_bytes(offset)), type, name);
    53 }
    55 LoadInst* SharkBuilder::CreateValueOfStructEntry(Value*      base,
    56                                                  ByteSize    offset,
    57                                                  const Type* type,
    58                                                  const char* name) {
    59   return CreateLoad(
    60     CreateAddressOfStructEntry(
    61       base, offset, PointerType::getUnqual(type)),
    62     name);
    63 }
    65 // Helpers for accessing arrays
    67 LoadInst* SharkBuilder::CreateArrayLength(Value* arrayoop) {
    68   return CreateValueOfStructEntry(
    69     arrayoop, in_ByteSize(arrayOopDesc::length_offset_in_bytes()),
    70     SharkType::jint_type(), "length");
    71 }
    73 Value* SharkBuilder::CreateArrayAddress(Value*      arrayoop,
    74                                         const Type* element_type,
    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);
    87   return CreateIntToPtr(
    88     CreateAdd(CreatePtrToInt(arrayoop, SharkType::intptr_type()), offset),
    89     PointerType::getUnqual(element_type),
    90     name);
    91 }
    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 }
   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 }
   115 // Helpers for creating intrinsics and external functions.
   117 const Type* SharkBuilder::make_type(char type, bool void_ok) {
   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();
   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));
   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();
   150     // Miscellaneous
   151   case 'v':
   152     assert(void_ok, "should be");
   153     return SharkType::void_type();
   154   case '1':
   155     return SharkType::bit_type();
   157   default:
   158     ShouldNotReachHere();
   159   }
   160 }
   162 const FunctionType* SharkBuilder::make_ftype(const char* params,
   163                                              const char* ret) {
   164   std::vector<const Type*> param_types;
   165   for (const char* c = params; *c; c++)
   166     param_types.push_back(make_type(*c, false));
   168   assert(strlen(ret) == 1, "should be");
   169   const Type *return_type = make_type(*ret, true);
   171   return FunctionType::get(return_type, param_types, false);
   172 }
   174 // Create an object representing an intrinsic or external function by
   175 // referencing the symbol by name.  This is the LLVM-style approach,
   176 // but it cannot be used on functions within libjvm.so its symbols
   177 // are not exported.  Note that you cannot make this work simply by
   178 // exporting the symbols, as some symbols have the same names as
   179 // symbols in the standard libraries (eg, atan2, fabs) and would
   180 // obscure them were they visible.
   181 Value* SharkBuilder::make_function(const char* name,
   182                                    const char* params,
   183                                    const char* ret) {
   184   return SharkContext::current().get_external(name, make_ftype(params, ret));
   185 }
   187 // Create an object representing an external function by inlining a
   188 // function pointer in the code.  This is not the LLVM way, but it's
   189 // the only way to access functions in libjvm.so and functions like
   190 // __kernel_dmb on ARM which is accessed via an absolute address.
   191 Value* SharkBuilder::make_function(address     func,
   192                                    const char* params,
   193                                    const char* ret) {
   194   return CreateIntToPtr(
   195     LLVMValue::intptr_constant((intptr_t) func),
   196     PointerType::getUnqual(make_ftype(params, ret)));
   197 }
   199 // VM calls
   201 Value* SharkBuilder::find_exception_handler() {
   202   return make_function(
   203     (address) SharkRuntime::find_exception_handler, "TIi", "i");
   204 }
   206 Value* SharkBuilder::monitorenter() {
   207   return make_function((address) SharkRuntime::monitorenter, "TM", "v");
   208 }
   210 Value* SharkBuilder::monitorexit() {
   211   return make_function((address) SharkRuntime::monitorexit, "TM", "v");
   212 }
   214 Value* SharkBuilder::new_instance() {
   215   return make_function((address) SharkRuntime::new_instance, "Ti", "v");
   216 }
   218 Value* SharkBuilder::newarray() {
   219   return make_function((address) SharkRuntime::newarray, "Tii", "v");
   220 }
   222 Value* SharkBuilder::anewarray() {
   223   return make_function((address) SharkRuntime::anewarray, "Tii", "v");
   224 }
   226 Value* SharkBuilder::multianewarray() {
   227   return make_function((address) SharkRuntime::multianewarray, "TiiI", "v");
   228 }
   230 Value* SharkBuilder::register_finalizer() {
   231   return make_function((address) SharkRuntime::register_finalizer, "TO", "v");
   232 }
   234 Value* SharkBuilder::safepoint() {
   235   return make_function((address) SafepointSynchronize::block, "T", "v");
   236 }
   238 Value* SharkBuilder::throw_ArithmeticException() {
   239   return make_function(
   240     (address) SharkRuntime::throw_ArithmeticException, "TCi", "v");
   241 }
   243 Value* SharkBuilder::throw_ArrayIndexOutOfBoundsException() {
   244   return make_function(
   245     (address) SharkRuntime::throw_ArrayIndexOutOfBoundsException, "TCii", "v");
   246 }
   248 Value* SharkBuilder::throw_ClassCastException() {
   249   return make_function(
   250     (address) SharkRuntime::throw_ClassCastException, "TCi", "v");
   251 }
   253 Value* SharkBuilder::throw_NullPointerException() {
   254   return make_function(
   255     (address) SharkRuntime::throw_NullPointerException, "TCi", "v");
   256 }
   258 // High-level non-VM calls
   260 Value* SharkBuilder::f2i() {
   261   return make_function((address) SharedRuntime::f2i, "f", "i");
   262 }
   264 Value* SharkBuilder::f2l() {
   265   return make_function((address) SharedRuntime::f2l, "f", "l");
   266 }
   268 Value* SharkBuilder::d2i() {
   269   return make_function((address) SharedRuntime::d2i, "d", "i");
   270 }
   272 Value* SharkBuilder::d2l() {
   273   return make_function((address) SharedRuntime::d2l, "d", "l");
   274 }
   276 Value* SharkBuilder::is_subtype_of() {
   277   return make_function((address) SharkRuntime::is_subtype_of, "OO", "c");
   278 }
   280 Value* SharkBuilder::current_time_millis() {
   281   return make_function((address) os::javaTimeMillis, "", "l");
   282 }
   284 Value* SharkBuilder::sin() {
   285   return make_function("llvm.sin.f64", "d", "d");
   286 }
   288 Value* SharkBuilder::cos() {
   289   return make_function("llvm.cos.f64", "d", "d");
   290 }
   292 Value* SharkBuilder::tan() {
   293   return make_function((address) ::tan, "d", "d");
   294 }
   296 Value* SharkBuilder::atan2() {
   297   return make_function((address) ::atan2, "dd", "d");
   298 }
   300 Value* SharkBuilder::sqrt() {
   301   return make_function("llvm.sqrt.f64", "d", "d");
   302 }
   304 Value* SharkBuilder::log() {
   305   return make_function("llvm.log.f64", "d", "d");
   306 }
   308 Value* SharkBuilder::log10() {
   309   return make_function("llvm.log10.f64", "d", "d");
   310 }
   312 Value* SharkBuilder::pow() {
   313   return make_function("llvm.pow.f64", "dd", "d");
   314 }
   316 Value* SharkBuilder::exp() {
   317   return make_function("llvm.exp.f64", "d", "d");
   318 }
   320 Value* SharkBuilder::fabs() {
   321   return make_function((address) ::fabs, "d", "d");
   322 }
   324 Value* SharkBuilder::unsafe_field_offset_to_byte_offset() {
   325   extern jlong Unsafe_field_offset_to_byte_offset(jlong field_offset);
   326   return make_function((address) Unsafe_field_offset_to_byte_offset, "l", "l");
   327 }
   329 Value* SharkBuilder::osr_migration_end() {
   330   return make_function((address) SharedRuntime::OSR_migration_end, "C", "v");
   331 }
   333 // Semi-VM calls
   335 Value* SharkBuilder::throw_StackOverflowError() {
   336   return make_function((address) ZeroStack::handle_overflow, "T", "v");
   337 }
   339 Value* SharkBuilder::uncommon_trap() {
   340   return make_function((address) SharkRuntime::uncommon_trap, "Ti", "i");
   341 }
   343 Value* SharkBuilder::deoptimized_entry_point() {
   344   return make_function((address) CppInterpreter::main_loop, "iT", "v");
   345 }
   347 // Native-Java transition
   349 Value* SharkBuilder::check_special_condition_for_native_trans() {
   350   return make_function(
   351     (address) JavaThread::check_special_condition_for_native_trans,
   352     "T", "v");
   353 }
   355 // Low-level non-VM calls
   357 // The ARM-specific code here is to work around unimplemented
   358 // atomic exchange and memory barrier intrinsics in LLVM.
   359 //
   360 // Delegating to external functions for these would normally
   361 // incur a speed penalty, but Linux on ARM is a special case
   362 // in that atomic operations on that platform are handled by
   363 // external functions anyway.  It would be *preferable* for
   364 // the calls to be hidden away in LLVM, but it's not hurting
   365 // performance so having the calls here is acceptable.
   366 //
   367 // If you are building Shark on a platform without atomic
   368 // exchange and/or memory barrier intrinsics then it is only
   369 // acceptable to mimic this approach if your platform cannot
   370 // perform these operations without delegating to a function.
   372 #ifdef ARM
   373 static jint zero_cmpxchg_int(volatile jint *ptr, jint oldval, jint newval) {
   374   return Atomic::cmpxchg(newval, ptr, oldval);
   375 }
   376 #endif // ARM
   378 Value* SharkBuilder::cmpxchg_int() {
   379   return make_function(
   380 #ifdef ARM
   381     (address) zero_cmpxchg_int,
   382 #else
   383     "llvm.atomic.cmp.swap.i32.p0i32",
   384 #endif // ARM
   385     "Iii", "i");
   386 }
   388 #ifdef ARM
   389 static intptr_t zero_cmpxchg_ptr(volatile intptr_t* ptr,
   390                                  intptr_t           oldval,
   391                                  intptr_t           newval) {
   392   return Atomic::cmpxchg_ptr(newval, ptr, oldval);
   393 }
   394 #endif // ARM
   396 Value* SharkBuilder::cmpxchg_ptr() {
   397   return make_function(
   398 #ifdef ARM
   399     (address) zero_cmpxchg_ptr,
   400 #else
   401     "llvm.atomic.cmp.swap.i" LP64_ONLY("64") NOT_LP64("32") ".p0i" LP64_ONLY("64") NOT_LP64("32"),
   402 #endif // ARM
   403     "Xxx", "x");
   404 }
   406 Value* SharkBuilder::frame_address() {
   407   return make_function("llvm.frameaddress", "i", "C");
   408 }
   410 Value* SharkBuilder::memory_barrier() {
   411   return make_function(
   412 #ifdef ARM
   413     (address) 0xffff0fa0, // __kernel_dmb
   414 #else
   415     "llvm.memory.barrier",
   416 #endif // ARM
   417     "11111", "v");
   418 }
   420 Value* SharkBuilder::memset() {
   421 #if SHARK_LLVM_VERSION >= 28
   422   // LLVM 2.8 added a fifth isVolatile field for memset
   423   // introduced with LLVM r100304
   424   return make_function("llvm.memset.i32", "Cciii", "v");
   425 #else
   426   return make_function("llvm.memset.i32", "Ccii", "v");
   427 #endif
   428 }
   430 Value* SharkBuilder::unimplemented() {
   431   return make_function((address) report_unimplemented, "Ci", "v");
   432 }
   434 Value* SharkBuilder::should_not_reach_here() {
   435   return make_function((address) report_should_not_reach_here, "Ci", "v");
   436 }
   438 Value* SharkBuilder::dump() {
   439   return make_function((address) SharkRuntime::dump, "Cx", "v");
   440 }
   442 // Public interface to low-level non-VM calls
   444 CallInst* SharkBuilder::CreateCmpxchgInt(Value* exchange_value,
   445                                          Value* dst,
   446                                          Value* compare_value) {
   447   return CreateCall3(cmpxchg_int(), dst, compare_value, exchange_value);
   448 }
   450 CallInst* SharkBuilder::CreateCmpxchgPtr(Value* exchange_value,
   451                                          Value* dst,
   452                                          Value* compare_value) {
   453   return CreateCall3(cmpxchg_ptr(), dst, compare_value, exchange_value);
   454 }
   456 CallInst* SharkBuilder::CreateGetFrameAddress() {
   457   return CreateCall(frame_address(), LLVMValue::jint_constant(0));
   458 }
   460 CallInst *SharkBuilder::CreateMemoryBarrier(int flags) {
   461   Value *args[] = {
   462     LLVMValue::bit_constant((flags & BARRIER_LOADLOAD) ? 1 : 0),
   463     LLVMValue::bit_constant((flags & BARRIER_LOADSTORE) ? 1 : 0),
   464     LLVMValue::bit_constant((flags & BARRIER_STORELOAD) ? 1 : 0),
   465     LLVMValue::bit_constant((flags & BARRIER_STORESTORE) ? 1 : 0),
   466     LLVMValue::bit_constant(1)};
   468   return CreateCall(memory_barrier(), args, args + 5);
   469 }
   471 CallInst* SharkBuilder::CreateMemset(Value* dst,
   472                                      Value* value,
   473                                      Value* len,
   474                                      Value* align) {
   475 #if SHARK_LLVM_VERSION >= 28
   476   return CreateCall5(memset(), dst, value, len, align,
   477                      LLVMValue::jint_constant(0));
   478 #else
   479   return CreateCall4(memset(), dst, value, len, align);
   480 #endif
   481 }
   483 CallInst* SharkBuilder::CreateUnimplemented(const char* file, int line) {
   484   return CreateCall2(
   485     unimplemented(),
   486     CreateIntToPtr(
   487       LLVMValue::intptr_constant((intptr_t) file),
   488       PointerType::getUnqual(SharkType::jbyte_type())),
   489     LLVMValue::jint_constant(line));
   490 }
   492 CallInst* SharkBuilder::CreateShouldNotReachHere(const char* file, int line) {
   493   return CreateCall2(
   494     should_not_reach_here(),
   495     CreateIntToPtr(
   496       LLVMValue::intptr_constant((intptr_t) file),
   497       PointerType::getUnqual(SharkType::jbyte_type())),
   498     LLVMValue::jint_constant(line));
   499 }
   501 #ifndef PRODUCT
   502 CallInst* SharkBuilder::CreateDump(Value* value) {
   503   const char *name;
   504   if (value->hasName())
   505     // XXX this leaks, but it's only debug code
   506     name = strdup(value->getName().str().c_str());
   507   else
   508     name = "unnamed_value";
   510   if (isa<PointerType>(value->getType()))
   511     value = CreatePtrToInt(value, SharkType::intptr_type());
   512   else if (value->getType()->
   513 #if SHARK_LLVM_VERSION >= 27
   514            isIntegerTy()
   515 #else
   516            isInteger()
   517 #endif
   518            )
   519     value = CreateIntCast(value, SharkType::intptr_type(), false);
   520   else
   521     Unimplemented();
   523   return CreateCall2(
   524     dump(),
   525     CreateIntToPtr(
   526       LLVMValue::intptr_constant((intptr_t) name),
   527       PointerType::getUnqual(SharkType::jbyte_type())),
   528     value);
   529 }
   530 #endif // PRODUCT
   532 // HotSpot memory barriers
   534 void SharkBuilder::CreateUpdateBarrierSet(BarrierSet* bs, Value* field) {
   535   if (bs->kind() != BarrierSet::CardTableModRef)
   536     Unimplemented();
   538   CreateStore(
   539     LLVMValue::jbyte_constant(CardTableModRefBS::dirty_card),
   540     CreateIntToPtr(
   541       CreateAdd(
   542         LLVMValue::intptr_constant(
   543           (intptr_t) ((CardTableModRefBS *) bs)->byte_map_base),
   544         CreateLShr(
   545           CreatePtrToInt(field, SharkType::intptr_type()),
   546           LLVMValue::intptr_constant(CardTableModRefBS::card_shift))),
   547       PointerType::getUnqual(SharkType::jbyte_type())));
   548 }
   550 // Helpers for accessing the code buffer
   552 Value* SharkBuilder::code_buffer_address(int offset) {
   553   return CreateAdd(
   554     code_buffer()->base_pc(),
   555     LLVMValue::intptr_constant(offset));
   556 }
   558 Value* SharkBuilder::CreateInlineOop(jobject object, const char* name) {
   559   return CreateLoad(
   560     CreateIntToPtr(
   561       code_buffer_address(code_buffer()->inline_oop(object)),
   562       PointerType::getUnqual(SharkType::oop_type())),
   563     name);
   564 }
   566 Value* SharkBuilder::CreateInlineData(void*       data,
   567                                       size_t      size,
   568                                       const Type* type,
   569                                       const char* name) {
   570   return CreateIntToPtr(
   571     code_buffer_address(code_buffer()->inline_data(data, size)),
   572     type,
   573     name);
   574 }
   576 // Helpers for creating basic blocks.
   578 BasicBlock* SharkBuilder::GetBlockInsertionPoint() const {
   579   BasicBlock *cur = GetInsertBlock();
   581   // BasicBlock::Create takes an insertBefore argument, so
   582   // we need to find the block _after_ the current block
   583   Function::iterator iter = cur->getParent()->begin();
   584   Function::iterator end  = cur->getParent()->end();
   585   while (iter != end) {
   586     iter++;
   587     if (&*iter == cur) {
   588       iter++;
   589       break;
   590     }
   591   }
   593   if (iter == end)
   594     return NULL;
   595   else
   596     return iter;
   597 }
   599 BasicBlock* SharkBuilder::CreateBlock(BasicBlock* ip, const char* name) const {
   600   return BasicBlock::Create(
   601     SharkContext::current(), name, GetInsertBlock()->getParent(), ip);
   602 }

mercurial