src/share/vm/shark/sharkFunction.cpp

Wed, 11 Aug 2010 05:51:21 -0700

author
twisti
date
Wed, 11 Aug 2010 05:51:21 -0700
changeset 2047
d2ede61b7a12
child 2314
f95d63e2154a
permissions
-rw-r--r--

6976186: integrate Shark HotSpot changes
Summary: Shark is a JIT compiler for Zero that uses the LLVM compiler infrastructure.
Reviewed-by: kvn, twisti
Contributed-by: Gary Benson <gbenson@redhat.com>

     1 /*
     2  * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
     3  * Copyright 2008, 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 "incls/_precompiled.incl"
    27 #include "incls/_sharkFunction.cpp.incl"
    29 using namespace llvm;
    31 void SharkFunction::initialize(const char *name) {
    32   // Create the function
    33   _function = Function::Create(
    34     entry_point_type(),
    35     GlobalVariable::InternalLinkage,
    36     name);
    38   // Get our arguments
    39   Function::arg_iterator ai = function()->arg_begin();
    40   Argument *method = ai++;
    41   method->setName("method");
    42   Argument *osr_buf = NULL;
    43   if (is_osr()) {
    44     osr_buf = ai++;
    45     osr_buf->setName("osr_buf");
    46   }
    47   Argument *base_pc = ai++;
    48   base_pc->setName("base_pc");
    49   code_buffer()->set_base_pc(base_pc);
    50   Argument *thread = ai++;
    51   thread->setName("thread");
    52   set_thread(thread);
    54   // Create the list of blocks
    55   set_block_insertion_point(NULL);
    56   _blocks = NEW_RESOURCE_ARRAY(SharkTopLevelBlock*, block_count());
    57   for (int i = 0; i < block_count(); i++) {
    58     ciTypeFlow::Block *b = flow()->pre_order_at(i);
    60     // Work around a bug in pre_order_at() that does not return
    61     // the correct pre-ordering.  If pre_order_at() were correct
    62     // this line could simply be:
    63     // _blocks[i] = new SharkTopLevelBlock(this, b);
    64     _blocks[b->pre_order()] = new SharkTopLevelBlock(this, b);
    65   }
    67   // Walk the tree from the start block to determine which
    68   // blocks are entered and which blocks require phis
    69   SharkTopLevelBlock *start_block = block(flow()->start_block_num());
    70   assert(start_block->start() == flow()->start_bci(), "blocks out of order");
    71   start_block->enter();
    73   // Initialize all entered blocks
    74   for (int i = 0; i < block_count(); i++) {
    75     if (block(i)->entered())
    76       block(i)->initialize();
    77   }
    79   // Create and push our stack frame
    80   set_block_insertion_point(&function()->front());
    81   builder()->SetInsertPoint(CreateBlock());
    82   _stack = SharkStack::CreateBuildAndPushFrame(this, method);
    84   // Create the entry state
    85   SharkState *entry_state;
    86   if (is_osr()) {
    87     entry_state = new SharkOSREntryState(start_block, method, osr_buf);
    89     // Free the OSR buffer
    90     builder()->CreateCall(builder()->osr_migration_end(), osr_buf);
    91   }
    92   else {
    93     entry_state = new SharkNormalEntryState(start_block, method);
    95     // Lock if necessary
    96     if (is_synchronized()) {
    97       SharkTopLevelBlock *locker =
    98         new SharkTopLevelBlock(this, start_block->ciblock());
    99       locker->add_incoming(entry_state);
   101       set_block_insertion_point(start_block->entry_block());
   102       locker->acquire_method_lock();
   104       entry_state = locker->current_state();
   105     }
   106   }
   108   // Transition into the method proper
   109   start_block->add_incoming(entry_state);
   110   builder()->CreateBr(start_block->entry_block());
   112   // Parse the blocks
   113   for (int i = 0; i < block_count(); i++) {
   114     if (!block(i)->entered())
   115       continue;
   117     if (i + 1 < block_count())
   118       set_block_insertion_point(block(i + 1)->entry_block());
   119     else
   120       set_block_insertion_point(NULL);
   122     block(i)->emit_IR();
   123   }
   124   do_deferred_zero_checks();
   125 }
   127 class DeferredZeroCheck : public SharkTargetInvariants {
   128  public:
   129   DeferredZeroCheck(SharkTopLevelBlock* block, SharkValue* value)
   130     : SharkTargetInvariants(block),
   131       _block(block),
   132       _value(value),
   133       _bci(block->bci()),
   134       _state(block->current_state()->copy()),
   135       _check_block(builder()->GetInsertBlock()),
   136       _continue_block(function()->CreateBlock("not_zero")) {
   137     builder()->SetInsertPoint(continue_block());
   138   }
   140  private:
   141   SharkTopLevelBlock* _block;
   142   SharkValue*         _value;
   143   int                 _bci;
   144   SharkState*         _state;
   145   BasicBlock*         _check_block;
   146   BasicBlock*         _continue_block;
   148  public:
   149   SharkTopLevelBlock* block() const {
   150     return _block;
   151   }
   152   SharkValue* value() const {
   153     return _value;
   154   }
   155   int bci() const {
   156     return _bci;
   157   }
   158   SharkState* state() const {
   159     return _state;
   160   }
   161   BasicBlock* check_block() const {
   162     return _check_block;
   163   }
   164   BasicBlock* continue_block() const {
   165     return _continue_block;
   166   }
   168  public:
   169   SharkFunction* function() const {
   170     return block()->function();
   171   }
   173  public:
   174   void process() const {
   175     builder()->SetInsertPoint(check_block());
   176     block()->do_deferred_zero_check(value(), bci(), state(), continue_block());
   177   }
   178 };
   180 void SharkFunction::add_deferred_zero_check(SharkTopLevelBlock* block,
   181                                             SharkValue*         value) {
   182   deferred_zero_checks()->append(new DeferredZeroCheck(block, value));
   183 }
   185 void SharkFunction::do_deferred_zero_checks() {
   186   for (int i = 0; i < deferred_zero_checks()->length(); i++)
   187     deferred_zero_checks()->at(i)->process();
   188 }

mercurial