# HG changeset patch # User Gary Benson # Date 1236776607 14400 # Node ID 1eeb14582f5a679354df249e23e10b2f61b423e8 # Parent b7948732adf296d3bcec78f5327b1199f812e30d 2009-03-11 Gary Benson * ports/hotspot/src/share/vm/shark/sharkIntrinsics.hpp: New file. * ports/hotspot/src/share/vm/shark/sharkIntrinsics.cpp: Likewise. * ports/hotspot/src/share/vm/shark/shark_globals.hpp (SharkPerformanceWarnings): New flag. * ports/hotspot/src/share/vm/shark/sharkBuilder.hpp (SharkBuilder::_llvm_cmpxchg_int_fn): New field. (SharkBuilder::_llvm_sin_fn): Likewise. (SharkBuilder::_llvm_cos_fn): Likewise. (SharkBuilder::_llvm_sqrt_fn): Likewise. (SharkBuilder::_llvm_log_fn): Likewise. (SharkBuilder::_llvm_log10_fn): Likewise. (SharkBuilder::_llvm_pow_fn): Likewise. (SharkBuilder::_llvm_exp_fn): Likewise. (SharkBuilder::set_llvm_cmpxchg_int_fn): New method. (SharkBuilder::set_llvm_sin_fn): Likewise. (SharkBuilder::set_llvm_cos_fn): Likewise. (SharkBuilder::set_llvm_sqrt_fn): Likewise. (SharkBuilder::set_llvm_log_fn): Likewise. (SharkBuilder::set_llvm_log10_fn): Likewise. (SharkBuilder::set_llvm_pow_fn): Likewise. (SharkBuilder::set_llvm_exp_fn): Likewise. (SharkBuilder::llvm_cmpxchg_int_fn): Likewise. (SharkBuilder::llvm_sin_fn): Likewise. (SharkBuilder::llvm_cos_fn): Likewise. (SharkBuilder::llvm_sqrt_fn): Likewise. (SharkBuilder::llvm_log_fn): Likewise. (SharkBuilder::llvm_log10_fn): Likewise. (SharkBuilder::llvm_pow_fn): Likewise. (SharkBuilder::llvm_exp_fn): Likewise. (SharkBuilder::CreateCmpxchgInt): Likewise. * ports/hotspot/src/share/vm/shark/sharkBuilder.cpp (SharkBuilder::init_external_functions): Initialize new fields. (SharkBuilder::CreateCmpxchgInt): New method. * ports/hotspot/src/share/vm/shark/sharkRuntime.hpp (SharkRuntime::_current_time_millis): New field. (SharkRuntime::_fabs): Likewise. (SharkRuntime::_tan): Likewise. (SharkRuntime::_atan2): Likewise. (SharkRuntime::_unsafe_field_offset_to_byte_offset): Likewise. (SharkRuntime::current_time_millis): New method. (SharkRuntime::fabs): Likewise. (SharkRuntime::tan): Likewise. (SharkRuntime::atan2): Likewise. (SharkRuntime::unsafe_field_offset_to_byte_offset): Likewise. * ports/hotspot/src/share/vm/shark/sharkRuntime.cpp (SharkRuntime::_current_time_millis): New field. (SharkRuntime::_fabs): Likewise. (SharkRuntime::_tan): Likewise. (SharkRuntime::_atan2): Likewise. (SharkRuntime::_unsafe_field_offset_to_byte_offset): Likewise. (SharkRuntime::initialize): Initialize the above. * ports/hotspot/src/share/vm/shark/sharkBlock.hpp (SharkBlock::SharkBlock): New thread argument. (SharkBlock::_thread): New field. (SharkBlock::thread): New method. * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp (SharkTopLevelBlock::SharkTopLevelBlock): Pass thread to super. (SharkTopLevelBlock::thread): Removed method. * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp (SharkTopLevelBlock::do_call): Pass thread to inliner. * ports/hotspot/src/share/vm/shark/sharkFunction.cpp (SharkFunction::initialize): Do the arguments before creating blocks. * ports/hotspot/src/share/vm/shark/sharkInliner.hpp (SharkInliner::attempt_inline): New thread argument. * ports/hotspot/src/share/vm/shark/sharkInliner.cpp (SharkInlineBlock::SharkInlineBlock): Pass thread to super. (SharkInlinerHelper::SharkInlinerHelper): New thread argument. (SharkInlinerHelper::_thread): New field. (SharkInlinerHelper::thread): New method. (SharkInlinerHelper::do_inline): Pass thread to block constructor. (SharkInliner::attempt_inline): Attempt to inline intrinsics. * ports/hotspot/src/share/vm/includeDB_shark: Updated. diff -r b7948732adf2 -r 1eeb14582f5a ChangeLog --- a/ChangeLog Mon Mar 09 12:36:47 2009 -0400 +++ b/ChangeLog Wed Mar 11 09:03:27 2009 -0400 @@ -1,3 +1,86 @@ +2009-03-11 Gary Benson + + * ports/hotspot/src/share/vm/shark/sharkIntrinsics.hpp: New file. + * ports/hotspot/src/share/vm/shark/sharkIntrinsics.cpp: Likewise. + + * ports/hotspot/src/share/vm/shark/shark_globals.hpp + (SharkPerformanceWarnings): New flag. + + * ports/hotspot/src/share/vm/shark/sharkBuilder.hpp + (SharkBuilder::_llvm_cmpxchg_int_fn): New field. + (SharkBuilder::_llvm_sin_fn): Likewise. + (SharkBuilder::_llvm_cos_fn): Likewise. + (SharkBuilder::_llvm_sqrt_fn): Likewise. + (SharkBuilder::_llvm_log_fn): Likewise. + (SharkBuilder::_llvm_log10_fn): Likewise. + (SharkBuilder::_llvm_pow_fn): Likewise. + (SharkBuilder::_llvm_exp_fn): Likewise. + (SharkBuilder::set_llvm_cmpxchg_int_fn): New method. + (SharkBuilder::set_llvm_sin_fn): Likewise. + (SharkBuilder::set_llvm_cos_fn): Likewise. + (SharkBuilder::set_llvm_sqrt_fn): Likewise. + (SharkBuilder::set_llvm_log_fn): Likewise. + (SharkBuilder::set_llvm_log10_fn): Likewise. + (SharkBuilder::set_llvm_pow_fn): Likewise. + (SharkBuilder::set_llvm_exp_fn): Likewise. + (SharkBuilder::llvm_cmpxchg_int_fn): Likewise. + (SharkBuilder::llvm_sin_fn): Likewise. + (SharkBuilder::llvm_cos_fn): Likewise. + (SharkBuilder::llvm_sqrt_fn): Likewise. + (SharkBuilder::llvm_log_fn): Likewise. + (SharkBuilder::llvm_log10_fn): Likewise. + (SharkBuilder::llvm_pow_fn): Likewise. + (SharkBuilder::llvm_exp_fn): Likewise. + (SharkBuilder::CreateCmpxchgInt): Likewise. + * ports/hotspot/src/share/vm/shark/sharkBuilder.cpp + (SharkBuilder::init_external_functions): Initialize new fields. + (SharkBuilder::CreateCmpxchgInt): New method. + + * ports/hotspot/src/share/vm/shark/sharkRuntime.hpp + (SharkRuntime::_current_time_millis): New field. + (SharkRuntime::_fabs): Likewise. + (SharkRuntime::_tan): Likewise. + (SharkRuntime::_atan2): Likewise. + (SharkRuntime::_unsafe_field_offset_to_byte_offset): Likewise. + (SharkRuntime::current_time_millis): New method. + (SharkRuntime::fabs): Likewise. + (SharkRuntime::tan): Likewise. + (SharkRuntime::atan2): Likewise. + (SharkRuntime::unsafe_field_offset_to_byte_offset): Likewise. + * ports/hotspot/src/share/vm/shark/sharkRuntime.cpp + (SharkRuntime::_current_time_millis): New field. + (SharkRuntime::_fabs): Likewise. + (SharkRuntime::_tan): Likewise. + (SharkRuntime::_atan2): Likewise. + (SharkRuntime::_unsafe_field_offset_to_byte_offset): Likewise. + (SharkRuntime::initialize): Initialize the above. + + * ports/hotspot/src/share/vm/shark/sharkBlock.hpp + (SharkBlock::SharkBlock): New thread argument. + (SharkBlock::_thread): New field. + (SharkBlock::thread): New method. + + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp + (SharkTopLevelBlock::SharkTopLevelBlock): Pass thread to super. + (SharkTopLevelBlock::thread): Removed method. + * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp + (SharkTopLevelBlock::do_call): Pass thread to inliner. + + * ports/hotspot/src/share/vm/shark/sharkFunction.cpp + (SharkFunction::initialize): Do the arguments before creating blocks. + + * ports/hotspot/src/share/vm/shark/sharkInliner.hpp + (SharkInliner::attempt_inline): New thread argument. + * ports/hotspot/src/share/vm/shark/sharkInliner.cpp + (SharkInlineBlock::SharkInlineBlock): Pass thread to super. + (SharkInlinerHelper::SharkInlinerHelper): New thread argument. + (SharkInlinerHelper::_thread): New field. + (SharkInlinerHelper::thread): New method. + (SharkInlinerHelper::do_inline): Pass thread to block constructor. + (SharkInliner::attempt_inline): Attempt to inline intrinsics. + + * ports/hotspot/src/share/vm/includeDB_shark: Updated. + 2009-03-09 Tomas Hurka * Makefile.am: Updated visualvm to version 1.1.1. diff -r b7948732adf2 -r 1eeb14582f5a ports/hotspot/src/share/vm/includeDB_shark --- a/ports/hotspot/src/share/vm/includeDB_shark Mon Mar 09 12:36:47 2009 -0400 +++ b/ports/hotspot/src/share/vm/includeDB_shark Wed Mar 11 09:03:27 2009 -0400 @@ -191,13 +191,28 @@ sharkInliner.cpp ciStreams.hpp sharkInliner.cpp shark_globals.hpp sharkInliner.cpp sharkInliner.hpp +sharkInliner.cpp sharkIntrinsics.hpp sharkInliner.cpp sharkState.inline.hpp sharkInliner.cpp sharkValue.inline.hpp sharkInliner.hpp allocation.hpp sharkInliner.hpp ciMethod.hpp +sharkInliner.hpp llvmHeaders.hpp sharkInliner.hpp sharkState.inline.hpp +sharkIntrinsics.cpp ciMethod.hpp +sharkIntrinsics.cpp llvmHeaders.hpp +sharkIntrinsics.cpp shark_globals.hpp +sharkIntrinsics.cpp sharkIntrinsics.hpp +sharkIntrinsics.cpp sharkRuntime.hpp +sharkIntrinsics.cpp sharkState.inline.hpp +sharkIntrinsics.cpp sharkValue.inline.hpp + +sharkIntrinsics.hpp allocation.hpp +sharkIntrinsics.hpp ciMethod.hpp +sharkIntrinsics.hpp llvmHeaders.hpp +sharkIntrinsics.hpp sharkState.hpp + sharkMemoryManager.hpp llvmHeaders.hpp sharkMemoryManager.hpp sharkEntry.hpp diff -r b7948732adf2 -r 1eeb14582f5a ports/hotspot/src/share/vm/shark/sharkBlock.hpp --- a/ports/hotspot/src/share/vm/shark/sharkBlock.hpp Mon Mar 09 12:36:47 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkBlock.hpp Wed Mar 11 09:03:27 2009 -0400 @@ -27,14 +27,22 @@ class SharkBlock : public ResourceObj { public: - SharkBlock(SharkBuilder* builder, ciMethod* target, ciBytecodeStream* iter) - : _builder(builder),_target(target),_iter(iter),_current_state(NULL) {} + SharkBlock(SharkBuilder* builder, + ciMethod* target, + ciBytecodeStream* iter, + llvm::Value* thread) + : _builder(builder), + _target(target), + _iter(iter), + _current_state(NULL), + _thread(thread) {} private: SharkBuilder* _builder; ciMethod* _target; ciBytecodeStream* _iter; SharkState* _current_state; + llvm::Value* _thread; public: SharkBuilder* builder() const @@ -49,6 +57,10 @@ { return _iter; } + llvm::Value* thread() const + { + return _thread; + } // Target properties public: diff -r b7948732adf2 -r 1eeb14582f5a ports/hotspot/src/share/vm/shark/sharkBuilder.cpp --- a/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp Mon Mar 09 12:36:47 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkBuilder.cpp Wed Mar 11 09:03:27 2009 -0400 @@ -76,6 +76,14 @@ set_llvm_memset_fn(module()->getOrInsertFunction("llvm.memset.i32", type)); params.clear(); + params.push_back(PointerType::getUnqual(SharkType::jint_type())); + params.push_back(SharkType::jint_type()); + params.push_back(SharkType::jint_type()); + type = FunctionType::get(SharkType::jint_type(), params, false); + set_llvm_cmpxchg_int_fn( + module()->getOrInsertFunction("llvm.atomic.cmp.swap.i32", type)); + + params.clear(); params.push_back(PointerType::getUnqual(SharkType::intptr_type())); params.push_back(SharkType::intptr_type()); params.push_back(SharkType::intptr_type()); @@ -90,6 +98,22 @@ type = FunctionType::get(Type::VoidTy, params, false); set_llvm_memory_barrier_fn( module()->getOrInsertFunction("llvm.memory.barrier", type)); + + params.clear(); + params.push_back(SharkType::jdouble_type()); + type = FunctionType::get(SharkType::jdouble_type(), params, false); + set_llvm_sin_fn (module()->getOrInsertFunction("llvm.sin.f64", type)); + set_llvm_cos_fn (module()->getOrInsertFunction("llvm.cos.f64", type)); + set_llvm_sqrt_fn (module()->getOrInsertFunction("llvm.sqrt.f64", type)); + set_llvm_log_fn (module()->getOrInsertFunction("llvm.log.f64", type)); + set_llvm_log10_fn(module()->getOrInsertFunction("llvm.log10.f64", type)); + set_llvm_exp_fn (module()->getOrInsertFunction("llvm.exp.f64", type)); + + params.clear(); + params.push_back(SharkType::jdouble_type()); + params.push_back(SharkType::jdouble_type()); + type = FunctionType::get(SharkType::jdouble_type(), params, false); + set_llvm_pow_fn(module()->getOrInsertFunction("llvm.pow.f64", type)); } Function *SharkBuilder::CreateFunction(const char *name) @@ -130,6 +154,14 @@ return CreateCall2(SharkRuntime::dump(), name, value); } +CallInst* SharkBuilder::CreateCmpxchgInt(Value* exchange_value, + Value* dst, + Value* compare_value) +{ + return CreateCall3( + llvm_cmpxchg_int_fn(), dst, compare_value, exchange_value); +} + CallInst* SharkBuilder::CreateCmpxchgPtr(Value* exchange_value, Value* dst, Value* compare_value) diff -r b7948732adf2 -r 1eeb14582f5a ports/hotspot/src/share/vm/shark/sharkBuilder.hpp --- a/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp Mon Mar 09 12:36:47 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkBuilder.hpp Wed Mar 11 09:03:27 2009 -0400 @@ -197,10 +197,22 @@ // External functions (and intrinsics) private: + llvm::Constant* _llvm_cmpxchg_int_fn; llvm::Constant* _llvm_cmpxchg_ptr_fn; llvm::Constant* _llvm_memory_barrier_fn; llvm::Constant* _llvm_memset_fn; + llvm::Constant* _llvm_sin_fn; + llvm::Constant* _llvm_cos_fn; + llvm::Constant* _llvm_sqrt_fn; + llvm::Constant* _llvm_log_fn; + llvm::Constant* _llvm_log10_fn; + llvm::Constant* _llvm_pow_fn; + llvm::Constant* _llvm_exp_fn; + void set_llvm_cmpxchg_int_fn(llvm::Constant* llvm_cmpxchg_int_fn) + { + _llvm_cmpxchg_int_fn = llvm_cmpxchg_int_fn; + } void set_llvm_cmpxchg_ptr_fn(llvm::Constant* llvm_cmpxchg_ptr_fn) { _llvm_cmpxchg_ptr_fn = llvm_cmpxchg_ptr_fn; @@ -213,10 +225,42 @@ { _llvm_memset_fn = llvm_memset_fn; } + void set_llvm_sin_fn(llvm::Constant* llvm_sin_fn) + { + _llvm_sin_fn = llvm_sin_fn; + } + void set_llvm_cos_fn(llvm::Constant* llvm_cos_fn) + { + _llvm_cos_fn = llvm_cos_fn; + } + void set_llvm_sqrt_fn(llvm::Constant* llvm_sqrt_fn) + { + _llvm_sqrt_fn = llvm_sqrt_fn; + } + void set_llvm_log_fn(llvm::Constant* llvm_log_fn) + { + _llvm_log_fn = llvm_log_fn; + } + void set_llvm_log10_fn(llvm::Constant* llvm_log10_fn) + { + _llvm_log10_fn = llvm_log10_fn; + } + void set_llvm_pow_fn(llvm::Constant* llvm_pow_fn) + { + _llvm_pow_fn = llvm_pow_fn; + } + void set_llvm_exp_fn(llvm::Constant* llvm_exp_fn) + { + _llvm_exp_fn = llvm_exp_fn; + } void init_external_functions(); protected: + llvm::Constant* llvm_cmpxchg_int_fn() const + { + return _llvm_cmpxchg_int_fn; + } llvm::Constant* llvm_cmpxchg_ptr_fn() const { return _llvm_cmpxchg_ptr_fn; @@ -231,11 +275,44 @@ } public: + llvm::Constant* llvm_sin_fn() const + { + return _llvm_sin_fn; + } + llvm::Constant* llvm_cos_fn() const + { + return _llvm_cos_fn; + } + llvm::Constant* llvm_sqrt_fn() const + { + return _llvm_sqrt_fn; + } + llvm::Constant* llvm_log_fn() const + { + return _llvm_log_fn; + } + llvm::Constant* llvm_log10_fn() const + { + return _llvm_log10_fn; + } + llvm::Constant* llvm_pow_fn() const + { + return _llvm_pow_fn; + } + llvm::Constant* llvm_exp_fn() const + { + return _llvm_exp_fn; + } + + public: llvm::CallInst* CreateDump(llvm::Value* value); llvm::CallInst* CreateMemset(llvm::Value* dst, llvm::Value* value, llvm::Value* len, llvm::Value* align); + llvm::CallInst* CreateCmpxchgInt(llvm::Value* exchange_value, + llvm::Value* dst, + llvm::Value* compare_value); llvm::CallInst* CreateCmpxchgPtr(llvm::Value* exchange_value, llvm::Value* dst, llvm::Value* compare_value); diff -r b7948732adf2 -r 1eeb14582f5a ports/hotspot/src/share/vm/shark/sharkFunction.cpp --- a/ports/hotspot/src/share/vm/shark/sharkFunction.cpp Mon Mar 09 12:36:47 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkFunction.cpp Wed Mar 11 09:03:27 2009 -0400 @@ -100,6 +100,15 @@ entry->set_llvm_function(function()); compiler()->memory_manager()->set_entry_for_function(function(), entry); + // Get our arguments + Function::arg_iterator ai = function()->arg_begin(); + Argument *method = ai++; + method->setName("method"); + _base_pc = ai++; + _base_pc->setName("base_pc"); + _thread = ai++; + _thread->setName("thread"); + // Create the list of blocks set_block_insertion_point(NULL); _blocks = NEW_RESOURCE_ARRAY(SharkTopLevelBlock*, flow()->block_count()); @@ -132,15 +141,6 @@ _monitor_count, block(i)->ciblock()->monitor_count()); } - // Get our arguments - Function::arg_iterator ai = function()->arg_begin(); - Argument *method = ai++; - method->setName("method"); - _base_pc = ai++; - _base_pc->setName("base_pc"); - _thread = ai++; - _thread->setName("thread"); - // Create the method preamble set_block_insertion_point(&function()->front()); builder()->SetInsertPoint(CreateBlock()); diff -r b7948732adf2 -r 1eeb14582f5a ports/hotspot/src/share/vm/shark/sharkInliner.cpp --- a/ports/hotspot/src/share/vm/shark/sharkInliner.cpp Mon Mar 09 12:36:47 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkInliner.cpp Wed Mar 11 09:03:27 2009 -0400 @@ -32,8 +32,9 @@ public: SharkInlineBlock(ciMethod* target, SharkState* state, - ciBytecodeStream* iter) - : SharkBlock(state->builder(), target, iter), + ciBytecodeStream* iter, + Value* thread) + : SharkBlock(state->builder(), target, iter, thread), _outer_state(state), _entry_state(new SharkState(this)) { @@ -79,13 +80,17 @@ class SharkInlinerHelper : public StackObj { public: - SharkInlinerHelper(ciMethod* target, SharkState* entry_state) - : _target(target), _entry_state(entry_state), _iter(target) {} + SharkInlinerHelper(ciMethod* target, SharkState* entry_state, Value* thread) + : _target(target), + _entry_state(entry_state), + _iter(target), + _thread(thread) {} private: ciBytecodeStream _iter; SharkState* _entry_state; ciMethod* _target; + Value* _thread; public: ciBytecodeStream* iter() @@ -100,6 +105,10 @@ { return _target; } + Value* thread() const + { + return _thread; + } public: Bytecodes::Code bc() @@ -198,7 +207,8 @@ public: void do_inline() { - (new SharkInlineBlock(target(), entry_state(), iter()))->emit_IR(); + (new SharkInlineBlock( + target(), entry_state(), iter(), thread()))->emit_IR(); } }; @@ -756,10 +766,17 @@ return true; } -bool SharkInliner::attempt_inline(ciMethod *target, SharkState *state) +bool SharkInliner::attempt_inline(ciMethod* target, + SharkState* state, + Value* thread) { + if (SharkIntrinsics::is_intrinsic(target)) { + SharkIntrinsics::inline_intrinsic(target, state, thread); + return true; + } + if (may_be_inlinable(target)) { - SharkInlinerHelper inliner(target, state); + SharkInlinerHelper inliner(target, state, thread); if (inliner.is_inlinable()) { inliner.do_inline(); return true; diff -r b7948732adf2 -r 1eeb14582f5a ports/hotspot/src/share/vm/shark/sharkInliner.hpp --- a/ports/hotspot/src/share/vm/shark/sharkInliner.hpp Mon Mar 09 12:36:47 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkInliner.hpp Wed Mar 11 09:03:27 2009 -0400 @@ -25,7 +25,9 @@ class SharkInliner : public AllStatic { public: - static bool attempt_inline(ciMethod* target, SharkState* state); + static bool attempt_inline(ciMethod* target, + SharkState* state, + llvm::Value* thread); private: static bool may_be_inlinable(ciMethod* target); diff -r b7948732adf2 -r 1eeb14582f5a ports/hotspot/src/share/vm/shark/sharkIntrinsics.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/share/vm/shark/sharkIntrinsics.cpp Wed Mar 11 09:03:27 2009 -0400 @@ -0,0 +1,284 @@ +/* + * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +#include "incls/_precompiled.incl" +#include "incls/_sharkIntrinsics.cpp.incl" + +using namespace llvm; + +bool SharkIntrinsics::is_intrinsic(ciMethod *target) +{ + switch (target->intrinsic_id()) { + case vmIntrinsics::_none: + return false; + + // java.lang.Math + case vmIntrinsics::_min: + case vmIntrinsics::_max: + case vmIntrinsics::_dabs: + case vmIntrinsics::_dsin: + case vmIntrinsics::_dcos: + case vmIntrinsics::_dtan: + case vmIntrinsics::_datan2: + case vmIntrinsics::_dsqrt: + case vmIntrinsics::_dlog: + case vmIntrinsics::_dlog10: + case vmIntrinsics::_dpow: + case vmIntrinsics::_dexp: + return true; + + // java.lang.Object + case vmIntrinsics::_getClass: + return true; + + // java.lang.System + case vmIntrinsics::_currentTimeMillis: + return true; + + // java.lang.Thread + case vmIntrinsics::_currentThread: + return true; + + // sun.misc.Unsafe + case vmIntrinsics::_compareAndSwapInt: + return true; + + default: + if (SharkPerformanceWarnings) { + warning( + "unhandled intrinsic vmIntrinsic::%s", + vmIntrinsics::name_at(target->intrinsic_id())); + } + } + return false; +} + +void SharkIntrinsics::inline_intrinsic(ciMethod* target, + SharkState* state, + Value* thread) +{ + switch (target->intrinsic_id()) { + // java.lang.Math + case vmIntrinsics::_min: + do_Math_minmax(state, llvm::ICmpInst::ICMP_SLE); + break; + case vmIntrinsics::_max: + do_Math_minmax(state, llvm::ICmpInst::ICMP_SGE); + break; + case vmIntrinsics::_dabs: + do_Math_1to1(state, SharkRuntime::fabs()); + break; + case vmIntrinsics::_dsin: + do_Math_1to1(state, state->builder()->llvm_sin_fn()); + break; + case vmIntrinsics::_dcos: + do_Math_1to1(state, state->builder()->llvm_cos_fn()); + break; + case vmIntrinsics::_dtan: + do_Math_1to1(state, SharkRuntime::tan()); + break; + case vmIntrinsics::_datan2: + do_Math_2to1(state, SharkRuntime::atan2()); + break; + case vmIntrinsics::_dsqrt: + do_Math_1to1(state, state->builder()->llvm_sqrt_fn()); + break; + case vmIntrinsics::_dlog: + do_Math_1to1(state, state->builder()->llvm_log_fn()); + break; + case vmIntrinsics::_dlog10: + do_Math_1to1(state, state->builder()->llvm_log10_fn()); + break; + case vmIntrinsics::_dpow: + do_Math_2to1(state, state->builder()->llvm_pow_fn()); + break; + case vmIntrinsics::_dexp: + do_Math_1to1(state, state->builder()->llvm_exp_fn()); + break; + + // java.lang.Object + case vmIntrinsics::_getClass: + do_Object_getClass(state); + break; + + // java.lang.System + case vmIntrinsics::_currentTimeMillis: + do_System_currentTimeMillis(state); + break; + + // java.lang.Thread + case vmIntrinsics::_currentThread: + do_Thread_currentThread(state, thread); + break; + + // sun.misc.Unsafe + case vmIntrinsics::_compareAndSwapInt: + do_Unsafe_compareAndSwapInt(state); + break; + + default: + ShouldNotReachHere(); + } +} + +void SharkIntrinsics::do_Math_minmax(SharkState *state, ICmpInst::Predicate p) +{ + SharkBuilder *builder = state->builder(); + + // Pop the arguments + SharkValue *sb = state->pop(); + SharkValue *sa = state->pop(); + Value *a = sa->jint_value(); + Value *b = sb->jint_value(); + + // Perform the test + BasicBlock *ip = builder->GetBlockInsertionPoint(); + BasicBlock *return_a = builder->CreateBlock(ip, "return_a"); + BasicBlock *return_b = builder->CreateBlock(ip, "return_b"); + BasicBlock *done = builder->CreateBlock(ip, "done"); + + builder->CreateCondBr(builder->CreateICmp(p, a, b), return_a, return_b); + + builder->SetInsertPoint(return_a); + builder->CreateBr(done); + + builder->SetInsertPoint(return_b); + builder->CreateBr(done); + + builder->SetInsertPoint(done); + PHINode *phi = builder->CreatePHI(a->getType(), "result"); + phi->addIncoming(a, return_a); + phi->addIncoming(b, return_b); + + // Push the result + SharkValue *result = SharkValue::create_jint(phi); + if (sa->zero_checked() && sb->zero_checked()) + result->set_zero_checked(true); + state->push(result); +} + +void SharkIntrinsics::do_Math_1to1(SharkState *state, Constant *function) +{ + SharkValue *empty = state->pop(); + assert(empty == NULL, "should be"); + state->push( + SharkValue::create_jdouble( + state->builder()->CreateCall(function, state->pop()->jdouble_value()))); + state->push(NULL); +} + +void SharkIntrinsics::do_Math_2to1(SharkState *state, Constant *function) +{ + SharkValue *empty = state->pop(); + assert(empty == NULL, "should be"); + Value *y = state->pop()->jdouble_value(); + empty = state->pop(); + assert(empty == NULL, "should be"); + Value *x = state->pop()->jdouble_value(); + + state->push( + SharkValue::create_jdouble(state->builder()->CreateCall2(function, x, y))); + state->push(NULL); +} + +void SharkIntrinsics::do_Object_getClass(SharkState *state) +{ + SharkBuilder *builder = state->builder(); + + Value *klass = builder->CreateValueOfStructEntry( + state->pop()->jobject_value(), + in_ByteSize(oopDesc::klass_offset_in_bytes()), + SharkType::jobject_type(), + "klass"); + + Value *klass_part = builder->CreateAddressOfStructEntry( + klass, + in_ByteSize(klassOopDesc::klass_part_offset_in_bytes()), + SharkType::klass_type(), + "klass_part"); + + SharkValue *result = SharkValue::create_jobject( + builder->CreateValueOfStructEntry( + klass_part, + in_ByteSize(Klass::java_mirror_offset_in_bytes()), + SharkType::oop_type(), + "java_mirror")); + + result->set_zero_checked(true); + state->push(result); +} + +void SharkIntrinsics::do_System_currentTimeMillis(SharkState *state) +{ + state->push( + SharkValue::create_jlong( + state->builder()->CreateCall(SharkRuntime::current_time_millis()))); + state->push(NULL); +} + +void SharkIntrinsics::do_Thread_currentThread(SharkState *state, Value *thread) +{ + SharkValue *result = SharkValue::create_jobject( + state->builder()->CreateValueOfStructEntry( + thread, JavaThread::threadObj_offset(), + SharkType::jobject_type(), + "threadObj")); + result->set_zero_checked(true); + state->push(result); +} + +void SharkIntrinsics::do_Unsafe_compareAndSwapInt(SharkState *state) +{ + SharkBuilder *builder = state->builder(); + + // Pop the arguments + Value *x = state->pop()->jint_value(); + Value *e = state->pop()->jint_value(); + SharkValue *empty = state->pop(); + assert(empty == NULL, "should be"); + Value *offset = state->pop()->jlong_value(); + Value *object = state->pop()->jobject_value(); + Value *unsafe = state->pop()->jobject_value(); + + // Convert the offset + offset = builder->CreateCall( + SharkRuntime::unsafe_field_offset_to_byte_offset(), + offset); + + // Locate the field + Value *addr = builder->CreateIntToPtr( + builder->CreateAdd( + builder->CreatePtrToInt(object, SharkType::intptr_type()), + builder->CreateIntCast(offset, SharkType::intptr_type(), true)), + PointerType::getUnqual(SharkType::jint_type()), + "addr"); + + // Perform the operation + Value *result = builder->CreateCmpxchgInt(x, addr, e); + + // Push the result + state->push(SharkValue::create_jint(builder->CreateIntCast( + builder->CreateICmpEQ(result, e), SharkType::jint_type(), true))); +} diff -r b7948732adf2 -r 1eeb14582f5a ports/hotspot/src/share/vm/shark/sharkIntrinsics.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ports/hotspot/src/share/vm/shark/sharkIntrinsics.hpp Wed Mar 11 09:03:27 2009 -0400 @@ -0,0 +1,41 @@ +/* + * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2009 Red Hat, Inc. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + * + */ + +class SharkIntrinsics : public AllStatic { + public: + static bool is_intrinsic(ciMethod* target); + static void inline_intrinsic(ciMethod* target, + SharkState* state, + llvm::Value* thread); + + private: + static void do_Math_minmax(SharkState* state, llvm::ICmpInst::Predicate p); + static void do_Math_1to1(SharkState* state, llvm::Constant* function); + static void do_Math_2to1(SharkState* state, llvm::Constant* function); + static void do_Object_getClass(SharkState* state); + static void do_System_currentTimeMillis(SharkState* state); + static void do_Thread_currentThread(SharkState* state, llvm::Value* thread); + static void do_Unsafe_compareAndSwapInt(SharkState* state); +}; diff -r b7948732adf2 -r 1eeb14582f5a ports/hotspot/src/share/vm/shark/sharkRuntime.cpp --- a/ports/hotspot/src/share/vm/shark/sharkRuntime.cpp Mon Mar 09 12:36:47 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkRuntime.cpp Wed Mar 11 09:03:27 2009 -0400 @@ -1,6 +1,6 @@ /* * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * Copyright 2008 Red Hat, Inc. + * Copyright 2008, 2009 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ using namespace llvm; +// VM calls Constant* SharkRuntime::_find_exception_handler; Constant* SharkRuntime::_monitorenter; Constant* SharkRuntime::_monitorexit; @@ -41,16 +42,25 @@ Constant* SharkRuntime::_throw_ArrayIndexOutOfBoundsException; Constant* SharkRuntime::_throw_NullPointerException; +// Leaf calls Constant* SharkRuntime::_f2i; Constant* SharkRuntime::_f2l; Constant* SharkRuntime::_d2i; Constant* SharkRuntime::_d2l; +// Non-VM calls Constant* SharkRuntime::_dump; Constant* SharkRuntime::_is_subtype_of; Constant* SharkRuntime::_should_not_reach_here; Constant* SharkRuntime::_unimplemented; Constant* SharkRuntime::_uncommon_trap; +Constant* SharkRuntime::_current_time_millis; +Constant* SharkRuntime::_fabs; +Constant* SharkRuntime::_tan; +Constant* SharkRuntime::_atan2; +Constant* SharkRuntime::_unsafe_field_offset_to_byte_offset; + +extern jlong Unsafe_field_offset_to_byte_offset(jlong field_offset); void SharkRuntime::initialize(SharkBuilder* builder) { @@ -205,6 +215,35 @@ (intptr_t) uncommon_trap_C, FunctionType::get(Type::VoidTy, params, false), "SharkRuntime__uncommon_trap"); + + params.clear(); + _current_time_millis = builder->make_function( + (intptr_t) os::javaTimeMillis, + FunctionType::get(SharkType::jlong_type(), params, false), + "os__javaTimeMillis"); + + params.clear(); + params.push_back(SharkType::jdouble_type()); + _fabs = builder->make_function( + (intptr_t) ::fabs, + FunctionType::get(SharkType::jdouble_type(), params, false), + "fabs"); + _tan = builder->make_function( + (intptr_t) ::tan, + FunctionType::get(SharkType::jdouble_type(), params, false), + "tan"); + params.push_back(SharkType::jdouble_type()); + _atan2 = builder->make_function( + (intptr_t) ::atan2, + FunctionType::get(SharkType::jdouble_type(), params, false), + "atan2"); + + params.clear(); + params.push_back(SharkType::jlong_type()); + _unsafe_field_offset_to_byte_offset = builder->make_function( + (intptr_t) Unsafe_field_offset_to_byte_offset, + FunctionType::get(SharkType::jlong_type(), params, false), + "Unsafe_field_offset_to_byte_offset"); } JRT_ENTRY(int, SharkRuntime::find_exception_handler_C(JavaThread* thread, diff -r b7948732adf2 -r 1eeb14582f5a ports/hotspot/src/share/vm/shark/sharkRuntime.hpp --- a/ports/hotspot/src/share/vm/shark/sharkRuntime.hpp Mon Mar 09 12:36:47 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkRuntime.hpp Wed Mar 11 09:03:27 2009 -0400 @@ -174,6 +174,11 @@ static llvm::Constant* _should_not_reach_here; static llvm::Constant* _unimplemented; static llvm::Constant* _uncommon_trap; + static llvm::Constant* _current_time_millis; + static llvm::Constant* _fabs; + static llvm::Constant* _tan; + static llvm::Constant* _atan2; + static llvm::Constant* _unsafe_field_offset_to_byte_offset; public: static llvm::Constant* dump() @@ -196,6 +201,26 @@ { return _uncommon_trap; } + static llvm::Constant* current_time_millis() + { + return _current_time_millis; + } + static llvm::Constant* fabs() + { + return _fabs; + } + static llvm::Constant* tan() + { + return _tan; + } + static llvm::Constant* atan2() + { + return _atan2; + } + static llvm::Constant* unsafe_field_offset_to_byte_offset() + { + return _unsafe_field_offset_to_byte_offset; + } private: static void dump_C(const char *name, intptr_t value); diff -r b7948732adf2 -r 1eeb14582f5a ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Mon Mar 09 12:36:47 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Wed Mar 11 09:03:27 2009 -0400 @@ -1244,7 +1244,7 @@ // Try to inline the call if (call_type == CALL_DIRECT) { - if (SharkInliner::attempt_inline(method, current_state())) + if (SharkInliner::attempt_inline(method, current_state(), thread())) return; } diff -r b7948732adf2 -r 1eeb14582f5a ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp Mon Mar 09 12:36:47 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp Wed Mar 11 09:03:27 2009 -0400 @@ -26,7 +26,10 @@ class SharkTopLevelBlock : public SharkBlock { public: SharkTopLevelBlock(SharkFunction* function, ciTypeFlow::Block* ciblock) - : SharkBlock(function->builder(), function->target(), function->iter()), + : SharkBlock(function->builder(), + function->target(), + function->iter(), + function->thread()), _function(function), _ciblock(ciblock), _trap_request(TRAP_UNCHECKED), @@ -49,12 +52,6 @@ return _ciblock; } - public: - llvm::Value* thread() const - { - return function()->thread(); - } - // Typeflow properties public: int index() const diff -r b7948732adf2 -r 1eeb14582f5a ports/hotspot/src/share/vm/shark/shark_globals.hpp --- a/ports/hotspot/src/share/vm/shark/shark_globals.hpp Mon Mar 09 12:36:47 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/shark_globals.hpp Wed Mar 11 09:03:27 2009 -0400 @@ -60,5 +60,8 @@ \ develop(bool, SharkTraceInstalls, false, \ "Trace method installation") \ + \ + develop(bool, SharkPerformanceWarnings, false, \ + "Warn about things that could be made faster") \ SHARK_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_NOTPRODUCT_FLAG)