src/share/vm/shark/sharkIntrinsics.cpp

Tue, 18 Jun 2013 12:31:07 -0700

author
johnc
date
Tue, 18 Jun 2013 12:31:07 -0700
changeset 5277
01522ca68fc7
parent 4314
2cd5e15048e6
child 6876
710a3c8b516e
permissions
-rw-r--r--

8015237: Parallelize string table scanning during strong root processing
Summary: Parallelize the scanning of the intern string table by having each GC worker claim a given number of buckets. Changes were also reviewed by Per Liden <per.liden@oracle.com>.
Reviewed-by: tschatzl, stefank, twisti

     1 /*
     2  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
     3  * Copyright 2009 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 "shark/llvmHeaders.hpp"
    29 #include "shark/sharkIntrinsics.hpp"
    30 #include "shark/sharkState.hpp"
    31 #include "shark/sharkValue.hpp"
    32 #include "shark/shark_globals.hpp"
    34 using namespace llvm;
    36 bool SharkIntrinsics::is_intrinsic(ciMethod *target) {
    37   switch (target->intrinsic_id()) {
    38   case vmIntrinsics::_none:
    39     return false;
    41     // java.lang.Math
    42   case vmIntrinsics::_min:
    43   case vmIntrinsics::_max:
    44   case vmIntrinsics::_dabs:
    45   case vmIntrinsics::_dsin:
    46   case vmIntrinsics::_dcos:
    47   case vmIntrinsics::_dtan:
    48   case vmIntrinsics::_datan2:
    49   case vmIntrinsics::_dsqrt:
    50   case vmIntrinsics::_dlog:
    51   case vmIntrinsics::_dlog10:
    52   case vmIntrinsics::_dpow:
    53   case vmIntrinsics::_dexp:
    54     return true;
    56     // java.lang.Object
    57   case vmIntrinsics::_getClass:
    58     return true;
    60     // java.lang.System
    61   case vmIntrinsics::_currentTimeMillis:
    62     return true;
    64     // java.lang.Thread
    65   case vmIntrinsics::_currentThread:
    66     return true;
    68     // sun.misc.Unsafe
    69   case vmIntrinsics::_compareAndSwapInt:
    70     return true;
    72   default:
    73     if (SharkPerformanceWarnings) {
    74       warning(
    75         "unhandled intrinsic vmIntrinsic::%s",
    76         vmIntrinsics::name_at(target->intrinsic_id()));
    77     }
    78   }
    79   return false;
    80 }
    82 void SharkIntrinsics::inline_intrinsic(ciMethod *target, SharkState *state) {
    83   SharkIntrinsics intrinsic(state, target);
    84   intrinsic.do_intrinsic();
    85 }
    87 void SharkIntrinsics::do_intrinsic() {
    88   switch (target()->intrinsic_id()) {
    89     // java.lang.Math
    90   case vmIntrinsics::_min:
    91     do_Math_minmax(llvm::ICmpInst::ICMP_SLE);
    92     break;
    93   case vmIntrinsics::_max:
    94     do_Math_minmax(llvm::ICmpInst::ICMP_SGE);
    95     break;
    96   case vmIntrinsics::_dabs:
    97     do_Math_1to1(builder()->fabs());
    98     break;
    99   case vmIntrinsics::_dsin:
   100     do_Math_1to1(builder()->sin());
   101     break;
   102   case vmIntrinsics::_dcos:
   103     do_Math_1to1(builder()->cos());
   104     break;
   105   case vmIntrinsics::_dtan:
   106     do_Math_1to1(builder()->tan());
   107     break;
   108   case vmIntrinsics::_datan2:
   109     do_Math_2to1(builder()->atan2());
   110     break;
   111   case vmIntrinsics::_dsqrt:
   112     do_Math_1to1(builder()->sqrt());
   113     break;
   114   case vmIntrinsics::_dlog:
   115     do_Math_1to1(builder()->log());
   116     break;
   117   case vmIntrinsics::_dlog10:
   118     do_Math_1to1(builder()->log10());
   119     break;
   120   case vmIntrinsics::_dpow:
   121     do_Math_2to1(builder()->pow());
   122     break;
   123   case vmIntrinsics::_dexp:
   124     do_Math_1to1(builder()->exp());
   125     break;
   127     // java.lang.Object
   128   case vmIntrinsics::_getClass:
   129     do_Object_getClass();
   130     break;
   132     // java.lang.System
   133   case vmIntrinsics::_currentTimeMillis:
   134     do_System_currentTimeMillis();
   135     break;
   137     // java.lang.Thread
   138   case vmIntrinsics::_currentThread:
   139     do_Thread_currentThread();
   140     break;
   142     // sun.misc.Unsafe
   143   case vmIntrinsics::_compareAndSwapInt:
   144     do_Unsafe_compareAndSwapInt();
   145     break;
   147   default:
   148     ShouldNotReachHere();
   149   }
   150 }
   152 void SharkIntrinsics::do_Math_minmax(ICmpInst::Predicate p) {
   153   // Pop the arguments
   154   SharkValue *sb = state()->pop();
   155   SharkValue *sa = state()->pop();
   156   Value *a = sa->jint_value();
   157   Value *b = sb->jint_value();
   159   // Perform the test
   160   BasicBlock *ip       = builder()->GetBlockInsertionPoint();
   161   BasicBlock *return_a = builder()->CreateBlock(ip, "return_a");
   162   BasicBlock *return_b = builder()->CreateBlock(ip, "return_b");
   163   BasicBlock *done     = builder()->CreateBlock(ip, "done");
   165   builder()->CreateCondBr(builder()->CreateICmp(p, a, b), return_a, return_b);
   167   builder()->SetInsertPoint(return_a);
   168   builder()->CreateBr(done);
   170   builder()->SetInsertPoint(return_b);
   171   builder()->CreateBr(done);
   173   builder()->SetInsertPoint(done);
   174   PHINode *phi = builder()->CreatePHI(a->getType(), 0, "result");
   175   phi->addIncoming(a, return_a);
   176   phi->addIncoming(b, return_b);
   178   // Push the result
   179   state()->push(
   180     SharkValue::create_jint(
   181       phi,
   182       sa->zero_checked() && sb->zero_checked()));
   183 }
   185 void SharkIntrinsics::do_Math_1to1(Value *function) {
   186   SharkValue *empty = state()->pop();
   187   assert(empty == NULL, "should be");
   188   state()->push(
   189     SharkValue::create_jdouble(
   190       builder()->CreateCall(
   191         function, state()->pop()->jdouble_value())));
   192   state()->push(NULL);
   193 }
   195 void SharkIntrinsics::do_Math_2to1(Value *function) {
   196   SharkValue *empty = state()->pop();
   197   assert(empty == NULL, "should be");
   198   Value *y = state()->pop()->jdouble_value();
   199   empty = state()->pop();
   200   assert(empty == NULL, "should be");
   201   Value *x = state()->pop()->jdouble_value();
   203   state()->push(
   204     SharkValue::create_jdouble(
   205       builder()->CreateCall2(function, x, y)));
   206   state()->push(NULL);
   207 }
   209 void SharkIntrinsics::do_Object_getClass() {
   210   Value *klass = builder()->CreateValueOfStructEntry(
   211     state()->pop()->jobject_value(),
   212     in_ByteSize(oopDesc::klass_offset_in_bytes()),
   213     SharkType::klass_type(),
   214     "klass");
   216   state()->push(
   217     SharkValue::create_jobject(
   218       builder()->CreateValueOfStructEntry(
   219         klass,
   220         Klass::java_mirror_offset(),
   221         SharkType::oop_type(),
   222         "java_mirror"),
   223       true));
   224 }
   226 void SharkIntrinsics::do_System_currentTimeMillis() {
   227   state()->push(
   228     SharkValue::create_jlong(
   229       builder()->CreateCall(builder()->current_time_millis()),
   230       false));
   231   state()->push(NULL);
   232 }
   234 void SharkIntrinsics::do_Thread_currentThread() {
   235   state()->push(
   236     SharkValue::create_jobject(
   237       builder()->CreateValueOfStructEntry(
   238         thread(), JavaThread::threadObj_offset(),
   239         SharkType::oop_type(),
   240         "threadObj"),
   241       true));
   242 }
   244 void SharkIntrinsics::do_Unsafe_compareAndSwapInt() {
   245   // Pop the arguments
   246   Value *x      = state()->pop()->jint_value();
   247   Value *e      = state()->pop()->jint_value();
   248   SharkValue *empty = state()->pop();
   249   assert(empty == NULL, "should be");
   250   Value *offset = state()->pop()->jlong_value();
   251   Value *object = state()->pop()->jobject_value();
   252   Value *unsafe = state()->pop()->jobject_value();
   254   // Convert the offset
   255   offset = builder()->CreateCall(
   256     builder()->unsafe_field_offset_to_byte_offset(),
   257     offset);
   259   // Locate the field
   260   Value *addr = builder()->CreateIntToPtr(
   261     builder()->CreateAdd(
   262       builder()->CreatePtrToInt(object, SharkType::intptr_type()),
   263       builder()->CreateIntCast(offset, SharkType::intptr_type(), true)),
   264     PointerType::getUnqual(SharkType::jint_type()),
   265     "addr");
   267   // Perform the operation
   268   Value *result = builder()->CreateAtomicCmpXchg(addr, e, x, llvm::SequentiallyConsistent);
   269   // Push the result
   270   state()->push(
   271     SharkValue::create_jint(
   272       builder()->CreateIntCast(
   273         builder()->CreateICmpEQ(result, e), SharkType::jint_type(), true),
   274       false));
   275 }

mercurial