Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/shark/sharkIntrinsics.cpp
32285 views
/*1* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.2* Copyright 2009 Red Hat, Inc.3* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.4*5* This code is free software; you can redistribute it and/or modify it6* under the terms of the GNU General Public License version 2 only, as7* published by the Free Software Foundation.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 2 along with this work; if not, write to the Free Software Foundation,17* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.18*19* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*23*/2425#include "precompiled.hpp"26#include "ci/ciMethod.hpp"27#include "shark/llvmHeaders.hpp"28#include "shark/sharkIntrinsics.hpp"29#include "shark/sharkState.hpp"30#include "shark/sharkValue.hpp"31#include "shark/shark_globals.hpp"3233using namespace llvm;3435bool SharkIntrinsics::is_intrinsic(ciMethod *target) {36switch (target->intrinsic_id()) {37case vmIntrinsics::_none:38return false;3940// java.lang.Math41case vmIntrinsics::_min:42case vmIntrinsics::_max:43case vmIntrinsics::_dabs:44case vmIntrinsics::_dsin:45case vmIntrinsics::_dcos:46case vmIntrinsics::_dtan:47case vmIntrinsics::_datan2:48case vmIntrinsics::_dsqrt:49case vmIntrinsics::_dlog:50case vmIntrinsics::_dlog10:51case vmIntrinsics::_dpow:52case vmIntrinsics::_dexp:53return true;5455// java.lang.Object56case vmIntrinsics::_getClass:57return true;5859// java.lang.System60case vmIntrinsics::_currentTimeMillis:61return true;6263// java.lang.Thread64case vmIntrinsics::_currentThread:65return true;6667// sun.misc.Unsafe68case vmIntrinsics::_compareAndSwapInt:69return true;7071default:72if (SharkPerformanceWarnings) {73warning(74"unhandled intrinsic vmIntrinsic::%s",75vmIntrinsics::name_at(target->intrinsic_id()));76}77}78return false;79}8081void SharkIntrinsics::inline_intrinsic(ciMethod *target, SharkState *state) {82SharkIntrinsics intrinsic(state, target);83intrinsic.do_intrinsic();84}8586void SharkIntrinsics::do_intrinsic() {87switch (target()->intrinsic_id()) {88// java.lang.Math89case vmIntrinsics::_min:90do_Math_minmax(llvm::ICmpInst::ICMP_SLE);91break;92case vmIntrinsics::_max:93do_Math_minmax(llvm::ICmpInst::ICMP_SGE);94break;95case vmIntrinsics::_dabs:96do_Math_1to1(builder()->fabs());97break;98case vmIntrinsics::_dsin:99do_Math_1to1(builder()->sin());100break;101case vmIntrinsics::_dcos:102do_Math_1to1(builder()->cos());103break;104case vmIntrinsics::_dtan:105do_Math_1to1(builder()->tan());106break;107case vmIntrinsics::_datan2:108do_Math_2to1(builder()->atan2());109break;110case vmIntrinsics::_dsqrt:111do_Math_1to1(builder()->sqrt());112break;113case vmIntrinsics::_dlog:114do_Math_1to1(builder()->log());115break;116case vmIntrinsics::_dlog10:117do_Math_1to1(builder()->log10());118break;119case vmIntrinsics::_dpow:120do_Math_2to1(builder()->pow());121break;122case vmIntrinsics::_dexp:123do_Math_1to1(builder()->exp());124break;125126// java.lang.Object127case vmIntrinsics::_getClass:128do_Object_getClass();129break;130131// java.lang.System132case vmIntrinsics::_currentTimeMillis:133do_System_currentTimeMillis();134break;135136// java.lang.Thread137case vmIntrinsics::_currentThread:138do_Thread_currentThread();139break;140141// sun.misc.Unsafe142case vmIntrinsics::_compareAndSwapInt:143do_Unsafe_compareAndSwapInt();144break;145146default:147ShouldNotReachHere();148}149}150151void SharkIntrinsics::do_Math_minmax(ICmpInst::Predicate p) {152// Pop the arguments153SharkValue *sb = state()->pop();154SharkValue *sa = state()->pop();155Value *a = sa->jint_value();156Value *b = sb->jint_value();157158// Perform the test159BasicBlock *ip = builder()->GetBlockInsertionPoint();160BasicBlock *return_a = builder()->CreateBlock(ip, "return_a");161BasicBlock *return_b = builder()->CreateBlock(ip, "return_b");162BasicBlock *done = builder()->CreateBlock(ip, "done");163164builder()->CreateCondBr(builder()->CreateICmp(p, a, b), return_a, return_b);165166builder()->SetInsertPoint(return_a);167builder()->CreateBr(done);168169builder()->SetInsertPoint(return_b);170builder()->CreateBr(done);171172builder()->SetInsertPoint(done);173PHINode *phi = builder()->CreatePHI(a->getType(), 0, "result");174phi->addIncoming(a, return_a);175phi->addIncoming(b, return_b);176177// Push the result178state()->push(179SharkValue::create_jint(180phi,181sa->zero_checked() && sb->zero_checked()));182}183184void SharkIntrinsics::do_Math_1to1(Value *function) {185SharkValue *empty = state()->pop();186assert(empty == NULL, "should be");187state()->push(188SharkValue::create_jdouble(189builder()->CreateCall(190function, state()->pop()->jdouble_value())));191state()->push(NULL);192}193194void SharkIntrinsics::do_Math_2to1(Value *function) {195SharkValue *empty = state()->pop();196assert(empty == NULL, "should be");197Value *y = state()->pop()->jdouble_value();198empty = state()->pop();199assert(empty == NULL, "should be");200Value *x = state()->pop()->jdouble_value();201202state()->push(203SharkValue::create_jdouble(204builder()->CreateCall2(function, x, y)));205state()->push(NULL);206}207208void SharkIntrinsics::do_Object_getClass() {209Value *klass = builder()->CreateValueOfStructEntry(210state()->pop()->jobject_value(),211in_ByteSize(oopDesc::klass_offset_in_bytes()),212SharkType::klass_type(),213"klass");214215state()->push(216SharkValue::create_jobject(217builder()->CreateValueOfStructEntry(218klass,219Klass::java_mirror_offset(),220SharkType::oop_type(),221"java_mirror"),222true));223}224225void SharkIntrinsics::do_System_currentTimeMillis() {226state()->push(227SharkValue::create_jlong(228builder()->CreateCall(builder()->current_time_millis()),229false));230state()->push(NULL);231}232233void SharkIntrinsics::do_Thread_currentThread() {234state()->push(235SharkValue::create_jobject(236builder()->CreateValueOfStructEntry(237thread(), JavaThread::threadObj_offset(),238SharkType::oop_type(),239"threadObj"),240true));241}242243void SharkIntrinsics::do_Unsafe_compareAndSwapInt() {244// Pop the arguments245Value *x = state()->pop()->jint_value();246Value *e = state()->pop()->jint_value();247SharkValue *empty = state()->pop();248assert(empty == NULL, "should be");249Value *offset = state()->pop()->jlong_value();250Value *object = state()->pop()->jobject_value();251Value *unsafe = state()->pop()->jobject_value();252253// Convert the offset254offset = builder()->CreateCall(255builder()->unsafe_field_offset_to_byte_offset(),256offset);257258// Locate the field259Value *addr = builder()->CreateIntToPtr(260builder()->CreateAdd(261builder()->CreatePtrToInt(object, SharkType::intptr_type()),262builder()->CreateIntCast(offset, SharkType::intptr_type(), true)),263PointerType::getUnqual(SharkType::jint_type()),264"addr");265266// Perform the operation267Value *result = builder()->CreateAtomicCmpXchg(addr, e, x, llvm::SequentiallyConsistent);268// Push the result269state()->push(270SharkValue::create_jint(271builder()->CreateIntCast(272builder()->CreateICmpEQ(result, e), SharkType::jint_type(), true),273false));274}275276277