/*
* Copyright 2008, 2009, 2010 Red Hat, Inc.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#include "precompiled.hpp"
#include "ci/ciMethod.hpp"
#include "memory/resourceArea.hpp"
#include "oops/methodOop.hpp"
#include "runtime/synchronizer.hpp"
#include "runtime/thread.hpp"
#include "shark/llvmHeaders.hpp"
#include "shark/llvmValue.hpp"
#include "shark/sharkBuilder.hpp"
#include "shark/sharkContext.hpp"
#include "shark/sharkRuntime.hpp"
using namespace llvm;
}
// Helpers for accessing structures
const char* name) {
}
const char* name) {
return CreateLoad(
name);
}
// Helpers for accessing arrays
return CreateValueOfStructEntry(
}
const Type* element_type,
int element_bytes,
const char* name) {
if (element_bytes != 1)
return CreateIntToPtr(
name);
}
const char* name) {
return CreateArrayAddress(
}
const char* name) {
return CreateArrayAddress(
}
// Helpers for creating intrinsics and external functions.
switch (type) {
// Primitive types
case 'c':
return SharkType::jbyte_type();
case 'i':
case 'l':
return SharkType::jlong_type();
case 'x':
return SharkType::intptr_type();
case 'f':
return SharkType::jfloat_type();
case 'd':
return SharkType::jdouble_type();
// Pointers to primitive types
case 'C':
case 'I':
case 'L':
case 'X':
case 'F':
case 'D':
// VM objects
case 'T':
return SharkType::thread_type();
case 'M':
case 'O':
// Miscellaneous
case 'v':
case '1':
default:
}
}
const char* ret) {
for (const char* c = params; *c; c++)
}
// Create an object representing an intrinsic or external function by
// referencing the symbol by name. This is the LLVM-style approach,
// but it cannot be used on functions within libjvm.so its symbols
// are not exported. Note that you cannot make this work simply by
// exporting the symbols, as some symbols have the same names as
// symbols in the standard libraries (eg, atan2, fabs) and would
// obscure them were they visible.
const char* params,
const char* ret) {
}
// Create an object representing an external function by inlining a
// function pointer in the code. This is not the LLVM way, but it's
// the only way to access functions in libjvm.so and functions like
// __kernel_dmb on ARM which is accessed via an absolute address.
const char* params,
const char* ret) {
return CreateIntToPtr(
}
// VM calls
return make_function(
}
}
}
}
}
}
}
}
}
return make_function(
}
return make_function(
}
return make_function(
}
return make_function(
}
// High-level non-VM calls
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
// Semi-VM calls
}
}
}
// Native-Java transition
return make_function(
"T", "v");
}
// Low-level non-VM calls
// The ARM-specific code here is to work around unimplemented
// atomic exchange and memory barrier intrinsics in LLVM.
//
// Delegating to external functions for these would normally
// incur a speed penalty, but Linux on ARM is a special case
// in that atomic operations on that platform are handled by
// external functions anyway. It would be *preferable* for
// the calls to be hidden away in LLVM, but it's not hurting
// performance so having the calls here is acceptable.
//
// If you are building Shark on a platform without atomic
// acceptable to mimic this approach if your platform cannot
// perform these operations without delegating to a function.
#ifdef ARM
}
#endif // ARM
return make_function(
#ifdef ARM
#else
"llvm.atomic.cmp.swap.i32.p0i32",
#endif // ARM
"Iii", "i");
}
#ifdef ARM
}
#endif // ARM
return make_function(
#ifdef ARM
#else
#endif // ARM
"Xxx", "x");
}
}
return make_function(
#ifdef ARM
#else
"llvm.memory.barrier",
#endif // ARM
"11111", "v");
}
#if SHARK_LLVM_VERSION >= 28
// LLVM 2.8 added a fifth isVolatile field for memset
// introduced with LLVM r100304
#else
#endif
}
}
}
}
// Public interface to low-level non-VM calls
Value* compare_value) {
}
Value* compare_value) {
}
}
}
#if SHARK_LLVM_VERSION >= 28
LLVMValue::jint_constant(0));
#else
#endif
}
return CreateCall2(
}
return CreateCall2(
}
#ifndef PRODUCT
const char *name;
// XXX this leaks, but it's only debug code
else
name = "unnamed_value";
#if SHARK_LLVM_VERSION >= 27
#else
#endif
)
else
return CreateCall2(
dump(),
value);
}
#endif // PRODUCT
// HotSpot memory barriers
}
// Helpers for accessing the code buffer
return CreateAdd(
code_buffer()->base_pc(),
}
return CreateLoad(
name);
}
const char* name) {
return CreateIntToPtr(
type,
name);
}
// Helpers for creating basic blocks.
// BasicBlock::Create takes an insertBefore argument, so
// we need to find the block _after_ the current block
iter++;
iter++;
break;
}
}
return NULL;
else
return iter;
}
return BasicBlock::Create(
}