hotspot/src/share/vm/c1/c1_GraphBuilder.cpp
author iveresov
Thu, 02 Dec 2010 17:21:12 -0800
changeset 7432 f06f1253c317
parent 7427 d7b79a367474
child 8065 7ca689ce3d32
child 7913 dd096a83bdbb
permissions -rw-r--r--
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer Summary: C1 with profiling doesn't check whether the MDO has been really allocated, which can silently fail if the perm gen is full. The solution is to check if the allocation failed and bailout out of inlining or compilation. Reviewed-by: kvn, never
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5535
diff changeset
     2
 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5535
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5535
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 5535
diff changeset
    21
 * questions.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
7397
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6751
diff changeset
    25
#include "precompiled.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6751
diff changeset
    26
#include "c1/c1_CFGPrinter.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6751
diff changeset
    27
#include "c1/c1_Canonicalizer.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6751
diff changeset
    28
#include "c1/c1_Compilation.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6751
diff changeset
    29
#include "c1/c1_GraphBuilder.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6751
diff changeset
    30
#include "c1/c1_InstructionPrinter.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6751
diff changeset
    31
#include "ci/ciField.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6751
diff changeset
    32
#include "ci/ciKlass.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6751
diff changeset
    33
#include "interpreter/bytecode.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6751
diff changeset
    34
#include "runtime/sharedRuntime.hpp"
5b173b4ca846 6989984: Use standard include model for Hospot
stefank
parents: 6751
diff changeset
    35
#include "utilities/bitMap.inline.hpp"
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
class BlockListBuilder VALUE_OBJ_CLASS_SPEC {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
  Compilation* _compilation;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
  IRScope*     _scope;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
  BlockList    _blocks;                // internal list of all blocks
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
  BlockList*   _bci2block;             // mapping from bci to blocks for GraphBuilder
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
  // fields used by mark_loops
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
  BitMap       _active;                // for iteration of control flow graph
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
  BitMap       _visited;               // for iteration of control flow graph
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
  intArray     _loop_map;              // caches the information if a block is contained in a loop
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
  int          _next_loop_index;       // next free loop number
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
  int          _next_block_number;     // for reverse postorder numbering of blocks
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
  // accessors
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
  Compilation*  compilation() const              { return _compilation; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
  IRScope*      scope() const                    { return _scope; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
  ciMethod*     method() const                   { return scope()->method(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
  XHandlers*    xhandlers() const                { return scope()->xhandlers(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
  // unified bailout support
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
  void          bailout(const char* msg) const   { compilation()->bailout(msg); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
  bool          bailed_out() const               { return compilation()->bailed_out(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
  // helper functions
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
  BlockBegin* make_block_at(int bci, BlockBegin* predecessor);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
  void handle_exceptions(BlockBegin* current, int cur_bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
  void handle_jsr(BlockBegin* current, int sr_bci, int next_bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
  void store_one(BlockBegin* current, int local);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
  void store_two(BlockBegin* current, int local);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
  void set_entries(int osr_bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
  void set_leaders();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
  void make_loop_header(BlockBegin* block);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
  void mark_loops();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
  int  mark_loops(BlockBegin* b, bool in_subroutine);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
  // debugging
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
  void print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
  // creation
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
  BlockListBuilder(Compilation* compilation, IRScope* scope, int osr_bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
  // accessors for GraphBuilder
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
  BlockList*    bci2block() const                { return _bci2block; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
// Implementation of BlockListBuilder
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
BlockListBuilder::BlockListBuilder(Compilation* compilation, IRScope* scope, int osr_bci)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
 : _compilation(compilation)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
 , _scope(scope)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
 , _blocks(16)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
 , _bci2block(new BlockList(scope->method()->code_size(), NULL))
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
 , _next_block_number(0)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
 , _active()         // size not known yet
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
 , _visited()        // size not known yet
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
 , _next_loop_index(0)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
 , _loop_map() // size not known yet
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
  set_entries(osr_bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
  set_leaders();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
  CHECK_BAILOUT();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
  mark_loops();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
  NOT_PRODUCT(if (PrintInitialBlockList) print());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
  if (PrintCFGToFile) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
    stringStream title;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
    title.print("BlockListBuilder ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
    scope->method()->print_name(&title);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
    CFGPrinter::print_cfg(_bci2block, title.as_string(), false, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
void BlockListBuilder::set_entries(int osr_bci) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
  // generate start blocks
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
  BlockBegin* std_entry = make_block_at(0, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
  if (scope()->caller() == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
    std_entry->set(BlockBegin::std_entry_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
  if (osr_bci != -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
    BlockBegin* osr_entry = make_block_at(osr_bci, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
    osr_entry->set(BlockBegin::osr_entry_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
  // generate exception entry blocks
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
  XHandlers* list = xhandlers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
  const int n = list->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
  for (int i = 0; i < n; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
    XHandler* h = list->handler_at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
    BlockBegin* entry = make_block_at(h->handler_bci(), NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
    entry->set(BlockBegin::exception_entry_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
    h->set_entry_block(entry);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
BlockBegin* BlockListBuilder::make_block_at(int cur_bci, BlockBegin* predecessor) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
  assert(method()->bci_block_start().at(cur_bci), "wrong block starts of MethodLivenessAnalyzer");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
  BlockBegin* block = _bci2block->at(cur_bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
  if (block == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
    block = new BlockBegin(cur_bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
    block->init_stores_to_locals(method()->max_locals());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
    _bci2block->at_put(cur_bci, block);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
    _blocks.append(block);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
    assert(predecessor == NULL || predecessor->bci() < cur_bci, "targets for backward branches must already exist");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
  if (predecessor != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
    if (block->is_set(BlockBegin::exception_entry_flag)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
      BAILOUT_("Exception handler can be reached by both normal and exceptional control flow", block);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
    predecessor->add_successor(block);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
    block->increment_total_preds();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
  return block;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
inline void BlockListBuilder::store_one(BlockBegin* current, int local) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
  current->stores_to_locals().set_bit(local);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
inline void BlockListBuilder::store_two(BlockBegin* current, int local) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
  store_one(current, local);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
  store_one(current, local + 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
void BlockListBuilder::handle_exceptions(BlockBegin* current, int cur_bci) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
  // Draws edges from a block to its exception handlers
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
  XHandlers* list = xhandlers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
  const int n = list->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
  for (int i = 0; i < n; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
    XHandler* h = list->handler_at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
    if (h->covers(cur_bci)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
      BlockBegin* entry = h->entry_block();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
      assert(entry != NULL && entry == _bci2block->at(h->handler_bci()), "entry must be set");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
      assert(entry->is_set(BlockBegin::exception_entry_flag), "flag must be set");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
      // add each exception handler only once
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
      if (!current->is_successor(entry)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
        current->add_successor(entry);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
        entry->increment_total_preds();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
      // stop when reaching catchall
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
      if (h->catch_type() == 0) break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
void BlockListBuilder::handle_jsr(BlockBegin* current, int sr_bci, int next_bci) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
  // start a new block after jsr-bytecode and link this block into cfg
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
  make_block_at(next_bci, current);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
  // start a new block at the subroutine entry at mark it with special flag
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
  BlockBegin* sr_block = make_block_at(sr_bci, current);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
  if (!sr_block->is_set(BlockBegin::subroutine_entry_flag)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
    sr_block->set(BlockBegin::subroutine_entry_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
void BlockListBuilder::set_leaders() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
  bool has_xhandlers = xhandlers()->has_handlers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
  BlockBegin* current = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
  // The information which bci starts a new block simplifies the analysis
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
  // Without it, backward branches could jump to a bci where no block was created
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
  // during bytecode iteration. This would require the creation of a new block at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
  // branch target and a modification of the successor lists.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
  BitMap bci_block_start = method()->bci_block_start();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
  ciBytecodeStream s(method());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
  while (s.next() != ciBytecodeStream::EOBC()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
    int cur_bci = s.cur_bci();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
    if (bci_block_start.at(cur_bci)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
      current = make_block_at(cur_bci, current);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
    assert(current != NULL, "must have current block");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
    if (has_xhandlers && GraphBuilder::can_trap(method(), s.cur_bc())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
      handle_exceptions(current, cur_bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
    switch (s.cur_bc()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
      // track stores to local variables for selective creation of phi functions
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
      case Bytecodes::_iinc:     store_one(current, s.get_index()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
      case Bytecodes::_istore:   store_one(current, s.get_index()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
      case Bytecodes::_lstore:   store_two(current, s.get_index()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
      case Bytecodes::_fstore:   store_one(current, s.get_index()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
      case Bytecodes::_dstore:   store_two(current, s.get_index()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
      case Bytecodes::_astore:   store_one(current, s.get_index()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
      case Bytecodes::_istore_0: store_one(current, 0); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
      case Bytecodes::_istore_1: store_one(current, 1); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
      case Bytecodes::_istore_2: store_one(current, 2); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
      case Bytecodes::_istore_3: store_one(current, 3); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
      case Bytecodes::_lstore_0: store_two(current, 0); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
      case Bytecodes::_lstore_1: store_two(current, 1); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
      case Bytecodes::_lstore_2: store_two(current, 2); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
      case Bytecodes::_lstore_3: store_two(current, 3); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
      case Bytecodes::_fstore_0: store_one(current, 0); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
      case Bytecodes::_fstore_1: store_one(current, 1); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
      case Bytecodes::_fstore_2: store_one(current, 2); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
      case Bytecodes::_fstore_3: store_one(current, 3); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
      case Bytecodes::_dstore_0: store_two(current, 0); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
      case Bytecodes::_dstore_1: store_two(current, 1); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
      case Bytecodes::_dstore_2: store_two(current, 2); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
      case Bytecodes::_dstore_3: store_two(current, 3); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
      case Bytecodes::_astore_0: store_one(current, 0); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
      case Bytecodes::_astore_1: store_one(current, 1); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
      case Bytecodes::_astore_2: store_one(current, 2); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
      case Bytecodes::_astore_3: store_one(current, 3); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
      // track bytecodes that affect the control flow
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
      case Bytecodes::_athrow:  // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
      case Bytecodes::_ret:     // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
      case Bytecodes::_ireturn: // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
      case Bytecodes::_lreturn: // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
      case Bytecodes::_freturn: // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
      case Bytecodes::_dreturn: // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
      case Bytecodes::_areturn: // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
      case Bytecodes::_return:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
        current = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
      case Bytecodes::_ifeq:      // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
      case Bytecodes::_ifne:      // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
      case Bytecodes::_iflt:      // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
      case Bytecodes::_ifge:      // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
      case Bytecodes::_ifgt:      // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
      case Bytecodes::_ifle:      // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
      case Bytecodes::_if_icmpeq: // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
      case Bytecodes::_if_icmpne: // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
      case Bytecodes::_if_icmplt: // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
      case Bytecodes::_if_icmpge: // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
      case Bytecodes::_if_icmpgt: // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
      case Bytecodes::_if_icmple: // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
      case Bytecodes::_if_acmpeq: // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
      case Bytecodes::_if_acmpne: // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
      case Bytecodes::_ifnull:    // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
      case Bytecodes::_ifnonnull:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
        make_block_at(s.next_bci(), current);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
        make_block_at(s.get_dest(), current);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
        current = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
      case Bytecodes::_goto:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
        make_block_at(s.get_dest(), current);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
        current = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
      case Bytecodes::_goto_w:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
        make_block_at(s.get_far_dest(), current);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
        current = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
      case Bytecodes::_jsr:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
        handle_jsr(current, s.get_dest(), s.next_bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
        current = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
      case Bytecodes::_jsr_w:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
        handle_jsr(current, s.get_far_dest(), s.next_bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
        current = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
      case Bytecodes::_tableswitch: {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
        // set block for each case
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
        Bytecode_tableswitch *switch_ = Bytecode_tableswitch_at(s.cur_bcp());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
        int l = switch_->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
        for (int i = 0; i < l; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
          make_block_at(cur_bci + switch_->dest_offset_at(i), current);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
        make_block_at(cur_bci + switch_->default_offset(), current);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
        current = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
      case Bytecodes::_lookupswitch: {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
        // set block for each case
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
        Bytecode_lookupswitch *switch_ = Bytecode_lookupswitch_at(s.cur_bcp());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
        int l = switch_->number_of_pairs();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
        for (int i = 0; i < l; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
          make_block_at(cur_bci + switch_->pair_at(i)->offset(), current);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
        make_block_at(cur_bci + switch_->default_offset(), current);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
        current = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
void BlockListBuilder::mark_loops() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
  ResourceMark rm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
  _active = BitMap(BlockBegin::number_of_blocks());         _active.clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
  _visited = BitMap(BlockBegin::number_of_blocks());        _visited.clear();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
  _loop_map = intArray(BlockBegin::number_of_blocks(), 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
  _next_loop_index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
  _next_block_number = _blocks.length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
  // recursively iterate the control flow graph
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
  mark_loops(_bci2block->at(0), false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
  assert(_next_block_number >= 0, "invalid block numbers");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
void BlockListBuilder::make_loop_header(BlockBegin* block) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
  if (block->is_set(BlockBegin::exception_entry_flag)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
    // exception edges may look like loops but don't mark them as such
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
    // since it screws up block ordering.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
  if (!block->is_set(BlockBegin::parser_loop_header_flag)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
    block->set(BlockBegin::parser_loop_header_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
    assert(_loop_map.at(block->block_id()) == 0, "must not be set yet");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
    assert(0 <= _next_loop_index && _next_loop_index < BitsPerInt, "_next_loop_index is used as a bit-index in integer");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
    _loop_map.at_put(block->block_id(), 1 << _next_loop_index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
    if (_next_loop_index < 31) _next_loop_index++;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
    // block already marked as loop header
4430
95b539dfa1e8 6769124: various 64-bit fixes for c1
roland
parents: 3908
diff changeset
   377
    assert(is_power_of_2((unsigned int)_loop_map.at(block->block_id())), "exactly one bit must be set");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
int BlockListBuilder::mark_loops(BlockBegin* block, bool in_subroutine) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
  int block_id = block->block_id();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
  if (_visited.at(block_id)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
    if (_active.at(block_id)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
      // reached block via backward branch
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
      make_loop_header(block);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
    // return cached loop information for this block
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
    return _loop_map.at(block_id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
  if (block->is_set(BlockBegin::subroutine_entry_flag)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
    in_subroutine = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
  // set active and visited bits before successors are processed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
  _visited.set_bit(block_id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
  _active.set_bit(block_id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
  intptr_t loop_state = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
  for (int i = block->number_of_sux() - 1; i >= 0; i--) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
    // recursively process all successors
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
    loop_state |= mark_loops(block->sux_at(i), in_subroutine);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
  // clear active-bit after all successors are processed
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
  _active.clear_bit(block_id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
  // reverse-post-order numbering of all blocks
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
  block->set_depth_first_number(_next_block_number);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
  _next_block_number--;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
  if (loop_state != 0 || in_subroutine ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
    // block is contained at least in one loop, so phi functions are necessary
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
    // phi functions are also necessary for all locals stored in a subroutine
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
    scope()->requires_phi_function().set_union(block->stores_to_locals());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
  if (block->is_set(BlockBegin::parser_loop_header_flag)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
    int header_loop_state = _loop_map.at(block_id);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
    assert(is_power_of_2((unsigned)header_loop_state), "exactly one bit must be set");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
    // If the highest bit is set (i.e. when integer value is negative), the method
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
    // has 32 or more loops. This bit is never cleared because it is used for multiple loops
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
    if (header_loop_state >= 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
      clear_bits(loop_state, header_loop_state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
  // cache and return loop information for this block
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
  _loop_map.at_put(block_id, loop_state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
  return loop_state;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
int compare_depth_first(BlockBegin** a, BlockBegin** b) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
  return (*a)->depth_first_number() - (*b)->depth_first_number();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
void BlockListBuilder::print() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
  tty->print("----- initial block list of BlockListBuilder for method ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
  method()->print_short_name();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
  tty->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
  // better readability if blocks are sorted in processing order
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
  _blocks.sort(compare_depth_first);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
  for (int i = 0; i < _blocks.length(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
    BlockBegin* cur = _blocks.at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
    tty->print("%4d: B%-4d bci: %-4d  preds: %-4d ", cur->depth_first_number(), cur->block_id(), cur->bci(), cur->total_preds());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
    tty->print(cur->is_set(BlockBegin::std_entry_flag)               ? " std" : "    ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
    tty->print(cur->is_set(BlockBegin::osr_entry_flag)               ? " osr" : "    ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
    tty->print(cur->is_set(BlockBegin::exception_entry_flag)         ? " ex" : "   ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
    tty->print(cur->is_set(BlockBegin::subroutine_entry_flag)        ? " sr" : "   ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
    tty->print(cur->is_set(BlockBegin::parser_loop_header_flag)      ? " lh" : "   ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
    if (cur->number_of_sux() > 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
      tty->print("    sux: ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
      for (int j = 0; j < cur->number_of_sux(); j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
        BlockBegin* sux = cur->sux_at(j);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
        tty->print("B%d ", sux->block_id());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
    tty->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
// A simple growable array of Values indexed by ciFields
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
class FieldBuffer: public CompilationResourceObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
  GrowableArray<Value> _values;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
  FieldBuffer() {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
  void kill() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
    _values.trunc_to(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
  Value at(ciField* field) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
    assert(field->holder()->is_loaded(), "must be a loaded field");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
    int offset = field->offset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
    if (offset < _values.length()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
      return _values.at(offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
      return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
  void at_put(ciField* field, Value value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
    assert(field->holder()->is_loaded(), "must be a loaded field");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
    int offset = field->offset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
    _values.at_put_grow(offset, value, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
// MemoryBuffer is fairly simple model of the current state of memory.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
// It partitions memory into several pieces.  The first piece is
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
// generic memory where little is known about the owner of the memory.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
// This is conceptually represented by the tuple <O, F, V> which says
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
// that the field F of object O has value V.  This is flattened so
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
// that F is represented by the offset of the field and the parallel
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
// arrays _objects and _values are used for O and V.  Loads of O.F can
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
// simply use V.  Newly allocated objects are kept in a separate list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
// along with a parallel array for each object which represents the
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
// current value of its fields.  Stores of the default value to fields
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
// which have never been stored to before are eliminated since they
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
// are redundant.  Once newly allocated objects are stored into
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
// another object or they are passed out of the current compile they
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
// are treated like generic memory.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
class MemoryBuffer: public CompilationResourceObj {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
  FieldBuffer                 _values;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
  GrowableArray<Value>        _objects;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
  GrowableArray<Value>        _newobjects;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
  GrowableArray<FieldBuffer*> _fields;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
  MemoryBuffer() {}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
  StoreField* store(StoreField* st) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
    if (!EliminateFieldAccess) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
      return st;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
    Value object = st->obj();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
    Value value = st->value();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
    ciField* field = st->field();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
    if (field->holder()->is_loaded()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
      int offset = field->offset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
      int index = _newobjects.find(object);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
      if (index != -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
        // newly allocated object with no other stores performed on this field
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
        FieldBuffer* buf = _fields.at(index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
        if (buf->at(field) == NULL && is_default_value(value)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
          if (PrintIRDuringConstruction && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
            tty->print_cr("Eliminated store for object %d:", index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
            st->print_line();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
          return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
          buf->at_put(field, value);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
      } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
        _objects.at_put_grow(offset, object, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
        _values.at_put(field, value);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
      store_value(value);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
      // if we held onto field names we could alias based on names but
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
      // we don't know what's being stored to so kill it all.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
      kill();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
    return st;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
  // return true if this value correspond to the default value of a field.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
  bool is_default_value(Value value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
    Constant* con = value->as_Constant();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   574
    if (con) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   575
      switch (con->type()->tag()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
        case intTag:    return con->type()->as_IntConstant()->value() == 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
        case longTag:   return con->type()->as_LongConstant()->value() == 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
        case floatTag:  return jint_cast(con->type()->as_FloatConstant()->value()) == 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
        case doubleTag: return jlong_cast(con->type()->as_DoubleConstant()->value()) == jlong_cast(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
        case objectTag: return con->type() == objectNull;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
        default:  ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
    return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
  // return either the actual value of a load or the load itself
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
  Value load(LoadField* load) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
    if (!EliminateFieldAccess) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
      return load;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
    if (RoundFPResults && UseSSE < 2 && load->type()->is_float_kind()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
      // can't skip load since value might get rounded as a side effect
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
      return load;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
    ciField* field = load->field();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
    Value object   = load->obj();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
    if (field->holder()->is_loaded() && !field->is_volatile()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
      int offset = field->offset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
      Value result = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
      int index = _newobjects.find(object);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
      if (index != -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
        result = _fields.at(index)->at(field);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
      } else if (_objects.at_grow(offset, NULL) == object) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
        result = _values.at(field);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
      if (result != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
        if (PrintIRDuringConstruction && Verbose) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
          tty->print_cr("Eliminated load: ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
          load->print_line();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
        assert(result->type()->tag() == load->type()->tag(), "wrong types");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
        return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
    return load;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
  // Record this newly allocated object
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
  void new_instance(NewInstance* object) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
    int index = _newobjects.length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
    _newobjects.append(object);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
    if (_fields.at_grow(index, NULL) == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
      _fields.at_put(index, new FieldBuffer());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
      _fields.at(index)->kill();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
489c9b5090e2 Initial load
duke
parents:
diff changeset
   635
  void store_value(Value value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
    int index = _newobjects.find(value);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
    if (index != -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
      // stored a newly allocated object into another object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
      // Assume we've lost track of it as separate slice of memory.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
      // We could do better by keeping track of whether individual
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
      // fields could alias each other.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
      _newobjects.remove_at(index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   643
      // pull out the field info and store it at the end up the list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
      // of field info list to be reused later.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   645
      _fields.append(_fields.at(index));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   646
      _fields.remove_at(index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   647
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   648
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   649
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
  void kill() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   651
    _newobjects.trunc_to(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
    _objects.trunc_to(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
    _values.kill();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
// Implementation of GraphBuilder's ScopeData
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
489c9b5090e2 Initial load
duke
parents:
diff changeset
   660
GraphBuilder::ScopeData::ScopeData(ScopeData* parent)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
  : _parent(parent)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   662
  , _bci2block(NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   663
  , _scope(NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
  , _has_handler(false)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
  , _stream(NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   666
  , _work_list(NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   667
  , _parsing_jsr(false)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
  , _jsr_xhandlers(NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   669
  , _caller_stack_size(-1)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   670
  , _continuation(NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
  , _num_returns(0)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
  , _cleanup_block(NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   673
  , _cleanup_return_prev(NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
  , _cleanup_state(NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
  if (parent != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
    _max_inline_size = (intx) ((float) NestedInliningSizeRatio * (float) parent->max_inline_size() / 100.0f);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
    _max_inline_size = MaxInlineSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
  if (_max_inline_size < MaxTrivialSize) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
    _max_inline_size = MaxTrivialSize;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   683
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   684
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   685
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
489c9b5090e2 Initial load
duke
parents:
diff changeset
   687
void GraphBuilder::kill_all() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   688
  if (UseLocalValueNumbering) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   689
    vmap()->kill_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
  _memory->kill();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
BlockBegin* GraphBuilder::ScopeData::block_at(int bci) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   696
  if (parsing_jsr()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
    // It is necessary to clone all blocks associated with a
489c9b5090e2 Initial load
duke
parents:
diff changeset
   698
    // subroutine, including those for exception handlers in the scope
489c9b5090e2 Initial load
duke
parents:
diff changeset
   699
    // of the method containing the jsr (because those exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
   700
    // handlers may contain ret instructions in some cases).
489c9b5090e2 Initial load
duke
parents:
diff changeset
   701
    BlockBegin* block = bci2block()->at(bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   702
    if (block != NULL && block == parent()->bci2block()->at(bci)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   703
      BlockBegin* new_block = new BlockBegin(block->bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   704
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
   705
      if (PrintInitialBlockList) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   706
        tty->print_cr("CFG: cloned block %d (bci %d) as block %d for jsr",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   707
                      block->block_id(), block->bci(), new_block->block_id());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   708
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   709
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
   710
      // copy data from cloned blocked
489c9b5090e2 Initial load
duke
parents:
diff changeset
   711
      new_block->set_depth_first_number(block->depth_first_number());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   712
      if (block->is_set(BlockBegin::parser_loop_header_flag)) new_block->set(BlockBegin::parser_loop_header_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   713
      // Preserve certain flags for assertion checking
489c9b5090e2 Initial load
duke
parents:
diff changeset
   714
      if (block->is_set(BlockBegin::subroutine_entry_flag)) new_block->set(BlockBegin::subroutine_entry_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   715
      if (block->is_set(BlockBegin::exception_entry_flag))  new_block->set(BlockBegin::exception_entry_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   716
489c9b5090e2 Initial load
duke
parents:
diff changeset
   717
      // copy was_visited_flag to allow early detection of bailouts
489c9b5090e2 Initial load
duke
parents:
diff changeset
   718
      // if a block that is used in a jsr has already been visited before,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   719
      // it is shared between the normal control flow and a subroutine
489c9b5090e2 Initial load
duke
parents:
diff changeset
   720
      // BlockBegin::try_merge returns false when the flag is set, this leads
489c9b5090e2 Initial load
duke
parents:
diff changeset
   721
      // to a compilation bailout
489c9b5090e2 Initial load
duke
parents:
diff changeset
   722
      if (block->is_set(BlockBegin::was_visited_flag))  new_block->set(BlockBegin::was_visited_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   723
489c9b5090e2 Initial load
duke
parents:
diff changeset
   724
      bci2block()->at_put(bci, new_block);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   725
      block = new_block;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   726
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   727
    return block;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   728
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   729
    return bci2block()->at(bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   730
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   731
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   732
489c9b5090e2 Initial load
duke
parents:
diff changeset
   733
489c9b5090e2 Initial load
duke
parents:
diff changeset
   734
XHandlers* GraphBuilder::ScopeData::xhandlers() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   735
  if (_jsr_xhandlers == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   736
    assert(!parsing_jsr(), "");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   737
    return scope()->xhandlers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   738
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   739
  assert(parsing_jsr(), "");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   740
  return _jsr_xhandlers;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   741
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   742
489c9b5090e2 Initial load
duke
parents:
diff changeset
   743
489c9b5090e2 Initial load
duke
parents:
diff changeset
   744
void GraphBuilder::ScopeData::set_scope(IRScope* scope) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   745
  _scope = scope;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   746
  bool parent_has_handler = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   747
  if (parent() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   748
    parent_has_handler = parent()->has_handler();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   749
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   750
  _has_handler = parent_has_handler || scope->xhandlers()->has_handlers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   751
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   752
489c9b5090e2 Initial load
duke
parents:
diff changeset
   753
489c9b5090e2 Initial load
duke
parents:
diff changeset
   754
void GraphBuilder::ScopeData::set_inline_cleanup_info(BlockBegin* block,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   755
                                                      Instruction* return_prev,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   756
                                                      ValueStack* return_state) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   757
  _cleanup_block       = block;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   758
  _cleanup_return_prev = return_prev;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   759
  _cleanup_state       = return_state;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   760
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   761
489c9b5090e2 Initial load
duke
parents:
diff changeset
   762
489c9b5090e2 Initial load
duke
parents:
diff changeset
   763
void GraphBuilder::ScopeData::add_to_work_list(BlockBegin* block) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   764
  if (_work_list == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   765
    _work_list = new BlockList();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   766
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   767
489c9b5090e2 Initial load
duke
parents:
diff changeset
   768
  if (!block->is_set(BlockBegin::is_on_work_list_flag)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   769
    // Do not start parsing the continuation block while in a
489c9b5090e2 Initial load
duke
parents:
diff changeset
   770
    // sub-scope
489c9b5090e2 Initial load
duke
parents:
diff changeset
   771
    if (parsing_jsr()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   772
      if (block == jsr_continuation()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   773
        return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   774
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   775
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   776
      if (block == continuation()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   777
        return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   778
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   779
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   780
    block->set(BlockBegin::is_on_work_list_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   781
    _work_list->push(block);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   782
489c9b5090e2 Initial load
duke
parents:
diff changeset
   783
    sort_top_into_worklist(_work_list, block);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   784
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   785
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   786
489c9b5090e2 Initial load
duke
parents:
diff changeset
   787
489c9b5090e2 Initial load
duke
parents:
diff changeset
   788
void GraphBuilder::sort_top_into_worklist(BlockList* worklist, BlockBegin* top) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   789
  assert(worklist->top() == top, "");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   790
  // sort block descending into work list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   791
  const int dfn = top->depth_first_number();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   792
  assert(dfn != -1, "unknown depth first number");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   793
  int i = worklist->length()-2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   794
  while (i >= 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   795
    BlockBegin* b = worklist->at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   796
    if (b->depth_first_number() < dfn) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   797
      worklist->at_put(i+1, b);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   798
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   799
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   800
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   801
    i --;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   802
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   803
  if (i >= -1) worklist->at_put(i + 1, top);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   804
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   805
489c9b5090e2 Initial load
duke
parents:
diff changeset
   806
489c9b5090e2 Initial load
duke
parents:
diff changeset
   807
BlockBegin* GraphBuilder::ScopeData::remove_from_work_list() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   808
  if (is_work_list_empty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   809
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   810
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   811
  return _work_list->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   812
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   813
489c9b5090e2 Initial load
duke
parents:
diff changeset
   814
489c9b5090e2 Initial load
duke
parents:
diff changeset
   815
bool GraphBuilder::ScopeData::is_work_list_empty() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   816
  return (_work_list == NULL || _work_list->length() == 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   817
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   818
489c9b5090e2 Initial load
duke
parents:
diff changeset
   819
489c9b5090e2 Initial load
duke
parents:
diff changeset
   820
void GraphBuilder::ScopeData::setup_jsr_xhandlers() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   821
  assert(parsing_jsr(), "");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   822
  // clone all the exception handlers from the scope
489c9b5090e2 Initial load
duke
parents:
diff changeset
   823
  XHandlers* handlers = new XHandlers(scope()->xhandlers());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   824
  const int n = handlers->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   825
  for (int i = 0; i < n; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   826
    // The XHandlers need to be adjusted to dispatch to the cloned
489c9b5090e2 Initial load
duke
parents:
diff changeset
   827
    // handler block instead of the default one but the synthetic
489c9b5090e2 Initial load
duke
parents:
diff changeset
   828
    // unlocker needs to be handled specially.  The synthetic unlocker
489c9b5090e2 Initial load
duke
parents:
diff changeset
   829
    // should be left alone since there can be only one and all code
489c9b5090e2 Initial load
duke
parents:
diff changeset
   830
    // should dispatch to the same one.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   831
    XHandler* h = handlers->handler_at(i);
5334
b2d040a8d375 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 5046
diff changeset
   832
    assert(h->handler_bci() != SynchronizationEntryBCI, "must be real");
b2d040a8d375 6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents: 5046
diff changeset
   833
    h->set_entry_block(block_at(h->handler_bci()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   834
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   835
  _jsr_xhandlers = handlers;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   836
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   837
489c9b5090e2 Initial load
duke
parents:
diff changeset
   838
489c9b5090e2 Initial load
duke
parents:
diff changeset
   839
int GraphBuilder::ScopeData::num_returns() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   840
  if (parsing_jsr()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   841
    return parent()->num_returns();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   842
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   843
  return _num_returns;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   844
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   845
489c9b5090e2 Initial load
duke
parents:
diff changeset
   846
489c9b5090e2 Initial load
duke
parents:
diff changeset
   847
void GraphBuilder::ScopeData::incr_num_returns() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   848
  if (parsing_jsr()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   849
    parent()->incr_num_returns();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   850
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   851
    ++_num_returns;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   852
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   853
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   854
489c9b5090e2 Initial load
duke
parents:
diff changeset
   855
489c9b5090e2 Initial load
duke
parents:
diff changeset
   856
// Implementation of GraphBuilder
489c9b5090e2 Initial load
duke
parents:
diff changeset
   857
489c9b5090e2 Initial load
duke
parents:
diff changeset
   858
#define INLINE_BAILOUT(msg)        { inline_bailout(msg); return false; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   859
489c9b5090e2 Initial load
duke
parents:
diff changeset
   860
489c9b5090e2 Initial load
duke
parents:
diff changeset
   861
void GraphBuilder::load_constant() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   862
  ciConstant con = stream()->get_constant();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   863
  if (con.basic_type() == T_ILLEGAL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   864
    BAILOUT("could not resolve a constant");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   865
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   866
    ValueType* t = illegalType;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   867
    ValueStack* patch_state = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   868
    switch (con.basic_type()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   869
      case T_BOOLEAN: t = new IntConstant     (con.as_boolean()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   870
      case T_BYTE   : t = new IntConstant     (con.as_byte   ()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   871
      case T_CHAR   : t = new IntConstant     (con.as_char   ()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   872
      case T_SHORT  : t = new IntConstant     (con.as_short  ()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   873
      case T_INT    : t = new IntConstant     (con.as_int    ()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   874
      case T_LONG   : t = new LongConstant    (con.as_long   ()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   875
      case T_FLOAT  : t = new FloatConstant   (con.as_float  ()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   876
      case T_DOUBLE : t = new DoubleConstant  (con.as_double ()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   877
      case T_ARRAY  : t = new ArrayConstant   (con.as_object ()->as_array   ()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   878
      case T_OBJECT :
489c9b5090e2 Initial load
duke
parents:
diff changeset
   879
       {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   880
        ciObject* obj = con.as_object();
5882
6b2aecc4f7d8 6939203: JSR 292 needs method handle constants
jrose
parents: 5707
diff changeset
   881
        if (!obj->is_loaded()
6b2aecc4f7d8 6939203: JSR 292 needs method handle constants
jrose
parents: 5707
diff changeset
   882
            || (PatchALot && obj->klass() != ciEnv::current()->String_klass())) {
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
   883
          patch_state = copy_state_before();
5882
6b2aecc4f7d8 6939203: JSR 292 needs method handle constants
jrose
parents: 5707
diff changeset
   884
          t = new ObjectConstant(obj);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   885
        } else {
5882
6b2aecc4f7d8 6939203: JSR 292 needs method handle constants
jrose
parents: 5707
diff changeset
   886
          assert(!obj->is_klass(), "must be java_mirror of klass");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   887
          t = new InstanceConstant(obj->as_instance());
489c9b5090e2 Initial load
duke
parents:
diff changeset
   888
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   889
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   890
       }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   891
      default       : ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   892
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   893
    Value x;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   894
    if (patch_state != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   895
      x = new Constant(t, patch_state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   896
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   897
      x = new Constant(t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   898
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   899
    push(t, append(x));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   900
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   901
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   902
489c9b5090e2 Initial load
duke
parents:
diff changeset
   903
489c9b5090e2 Initial load
duke
parents:
diff changeset
   904
void GraphBuilder::load_local(ValueType* type, int index) {
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
   905
  Value x = state()->local_at(index);
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
   906
  assert(x != NULL && !x->type()->is_illegal(), "access of illegal local variable");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   907
  push(type, x);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   908
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   909
489c9b5090e2 Initial load
duke
parents:
diff changeset
   910
489c9b5090e2 Initial load
duke
parents:
diff changeset
   911
void GraphBuilder::store_local(ValueType* type, int index) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   912
  Value x = pop(type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   913
  store_local(state(), x, type, index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   914
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   915
489c9b5090e2 Initial load
duke
parents:
diff changeset
   916
489c9b5090e2 Initial load
duke
parents:
diff changeset
   917
void GraphBuilder::store_local(ValueStack* state, Value x, ValueType* type, int index) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   918
  if (parsing_jsr()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   919
    // We need to do additional tracking of the location of the return
489c9b5090e2 Initial load
duke
parents:
diff changeset
   920
    // address for jsrs since we don't handle arbitrary jsr/ret
489c9b5090e2 Initial load
duke
parents:
diff changeset
   921
    // constructs. Here we are figuring out in which circumstances we
489c9b5090e2 Initial load
duke
parents:
diff changeset
   922
    // need to bail out.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   923
    if (x->type()->is_address()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   924
      scope_data()->set_jsr_return_address_local(index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   925
489c9b5090e2 Initial load
duke
parents:
diff changeset
   926
      // Also check parent jsrs (if any) at this time to see whether
489c9b5090e2 Initial load
duke
parents:
diff changeset
   927
      // they are using this local. We don't handle skipping over a
489c9b5090e2 Initial load
duke
parents:
diff changeset
   928
      // ret.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   929
      for (ScopeData* cur_scope_data = scope_data()->parent();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   930
           cur_scope_data != NULL && cur_scope_data->parsing_jsr() && cur_scope_data->scope() == scope();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   931
           cur_scope_data = cur_scope_data->parent()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   932
        if (cur_scope_data->jsr_return_address_local() == index) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   933
          BAILOUT("subroutine overwrites return address from previous subroutine");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   934
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   935
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   936
    } else if (index == scope_data()->jsr_return_address_local()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   937
      scope_data()->set_jsr_return_address_local(-1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   938
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   939
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   940
489c9b5090e2 Initial load
duke
parents:
diff changeset
   941
  state->store_local(index, round_fp(x));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   942
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   943
489c9b5090e2 Initial load
duke
parents:
diff changeset
   944
489c9b5090e2 Initial load
duke
parents:
diff changeset
   945
void GraphBuilder::load_indexed(BasicType type) {
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
   946
  ValueStack* state_before = copy_state_for_exception();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   947
  Value index = ipop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   948
  Value array = apop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   949
  Value length = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   950
  if (CSEArrayLength ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   951
      (array->as_AccessField() && array->as_AccessField()->field()->is_constant()) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   952
      (array->as_NewArray() && array->as_NewArray()->length() && array->as_NewArray()->length()->type()->is_constant())) {
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
   953
    length = append(new ArrayLength(array, state_before));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   954
  }
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
   955
  push(as_ValueType(type), append(new LoadIndexed(array, index, length, type, state_before)));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   956
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   957
489c9b5090e2 Initial load
duke
parents:
diff changeset
   958
489c9b5090e2 Initial load
duke
parents:
diff changeset
   959
void GraphBuilder::store_indexed(BasicType type) {
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
   960
  ValueStack* state_before = copy_state_for_exception();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   961
  Value value = pop(as_ValueType(type));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   962
  Value index = ipop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   963
  Value array = apop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   964
  Value length = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   965
  if (CSEArrayLength ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   966
      (array->as_AccessField() && array->as_AccessField()->field()->is_constant()) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   967
      (array->as_NewArray() && array->as_NewArray()->length() && array->as_NewArray()->length()->type()->is_constant())) {
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
   968
    length = append(new ArrayLength(array, state_before));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   969
  }
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
   970
  StoreIndexed* result = new StoreIndexed(array, index, length, type, value, state_before);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   971
  append(result);
1612
2488b45ded37 6756768: C1 generates invalid code
never
parents: 1
diff changeset
   972
  _memory->store_value(value);
6461
cfc616b49f58 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 6453
diff changeset
   973
cfc616b49f58 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 6453
diff changeset
   974
  if (type == T_OBJECT && is_profiling()) {
cfc616b49f58 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 6453
diff changeset
   975
    // Note that we'd collect profile data in this method if we wanted it.
cfc616b49f58 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 6453
diff changeset
   976
    compilation()->set_would_profile(true);
cfc616b49f58 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 6453
diff changeset
   977
cfc616b49f58 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 6453
diff changeset
   978
    if (profile_checkcasts()) {
cfc616b49f58 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 6453
diff changeset
   979
      result->set_profiled_method(method());
cfc616b49f58 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 6453
diff changeset
   980
      result->set_profiled_bci(bci());
cfc616b49f58 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 6453
diff changeset
   981
      result->set_should_profile(true);
cfc616b49f58 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 6453
diff changeset
   982
    }
cfc616b49f58 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 6453
diff changeset
   983
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   984
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   985
489c9b5090e2 Initial load
duke
parents:
diff changeset
   986
489c9b5090e2 Initial load
duke
parents:
diff changeset
   987
void GraphBuilder::stack_op(Bytecodes::Code code) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   988
  switch (code) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   989
    case Bytecodes::_pop:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   990
      { state()->raw_pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   991
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   992
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   993
    case Bytecodes::_pop2:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   994
      { state()->raw_pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   995
        state()->raw_pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   996
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   997
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   998
    case Bytecodes::_dup:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   999
      { Value w = state()->raw_pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1000
        state()->raw_push(w);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1001
        state()->raw_push(w);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1002
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1003
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1004
    case Bytecodes::_dup_x1:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1005
      { Value w1 = state()->raw_pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1006
        Value w2 = state()->raw_pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1007
        state()->raw_push(w1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1008
        state()->raw_push(w2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1009
        state()->raw_push(w1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1010
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1011
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1012
    case Bytecodes::_dup_x2:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1013
      { Value w1 = state()->raw_pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1014
        Value w2 = state()->raw_pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1015
        Value w3 = state()->raw_pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1016
        state()->raw_push(w1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1017
        state()->raw_push(w3);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1018
        state()->raw_push(w2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1019
        state()->raw_push(w1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1020
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1021
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1022
    case Bytecodes::_dup2:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1023
      { Value w1 = state()->raw_pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1024
        Value w2 = state()->raw_pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1025
        state()->raw_push(w2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1026
        state()->raw_push(w1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1027
        state()->raw_push(w2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1028
        state()->raw_push(w1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1029
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1030
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1031
    case Bytecodes::_dup2_x1:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1032
      { Value w1 = state()->raw_pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1033
        Value w2 = state()->raw_pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1034
        Value w3 = state()->raw_pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1035
        state()->raw_push(w2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1036
        state()->raw_push(w1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1037
        state()->raw_push(w3);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1038
        state()->raw_push(w2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1039
        state()->raw_push(w1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1040
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1041
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1042
    case Bytecodes::_dup2_x2:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1043
      { Value w1 = state()->raw_pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1044
        Value w2 = state()->raw_pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1045
        Value w3 = state()->raw_pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1046
        Value w4 = state()->raw_pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1047
        state()->raw_push(w2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1048
        state()->raw_push(w1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1049
        state()->raw_push(w4);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1050
        state()->raw_push(w3);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1051
        state()->raw_push(w2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1052
        state()->raw_push(w1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1053
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1054
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1055
    case Bytecodes::_swap:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1056
      { Value w1 = state()->raw_pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1057
        Value w2 = state()->raw_pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1058
        state()->raw_push(w1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1059
        state()->raw_push(w2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1060
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1061
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1062
    default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1063
      ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1064
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1065
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1066
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1067
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1068
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1069
void GraphBuilder::arithmetic_op(ValueType* type, Bytecodes::Code code, ValueStack* state_before) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1070
  Value y = pop(type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1071
  Value x = pop(type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1072
  // NOTE: strictfp can be queried from current method since we don't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1073
  // inline methods with differing strictfp bits
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1074
  Value res = new ArithmeticOp(code, x, y, method()->is_strict(), state_before);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1075
  // Note: currently single-precision floating-point rounding on Intel is handled at the LIRGenerator level
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1076
  res = append(res);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1077
  if (method()->is_strict()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1078
    res = round_fp(res);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1079
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1080
  push(type, res);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1081
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1082
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1083
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1084
void GraphBuilder::negate_op(ValueType* type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1085
  push(type, append(new NegateOp(pop(type))));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1086
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1087
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1088
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1089
void GraphBuilder::shift_op(ValueType* type, Bytecodes::Code code) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1090
  Value s = ipop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1091
  Value x = pop(type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1092
  // try to simplify
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1093
  // Note: This code should go into the canonicalizer as soon as it can
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1094
  //       can handle canonicalized forms that contain more than one node.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1095
  if (CanonicalizeNodes && code == Bytecodes::_iushr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1096
    // pattern: x >>> s
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1097
    IntConstant* s1 = s->type()->as_IntConstant();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1098
    if (s1 != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1099
      // pattern: x >>> s1, with s1 constant
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1100
      ShiftOp* l = x->as_ShiftOp();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1101
      if (l != NULL && l->op() == Bytecodes::_ishl) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1102
        // pattern: (a << b) >>> s1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1103
        IntConstant* s0 = l->y()->type()->as_IntConstant();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1104
        if (s0 != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1105
          // pattern: (a << s0) >>> s1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1106
          const int s0c = s0->value() & 0x1F; // only the low 5 bits are significant for shifts
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1107
          const int s1c = s1->value() & 0x1F; // only the low 5 bits are significant for shifts
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1108
          if (s0c == s1c) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1109
            if (s0c == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1110
              // pattern: (a << 0) >>> 0 => simplify to: a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1111
              ipush(l->x());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1112
            } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1113
              // pattern: (a << s0c) >>> s0c => simplify to: a & m, with m constant
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1114
              assert(0 < s0c && s0c < BitsPerInt, "adjust code below to handle corner cases");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1115
              const int m = (1 << (BitsPerInt - s0c)) - 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1116
              Value s = append(new Constant(new IntConstant(m)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1117
              ipush(append(new LogicOp(Bytecodes::_iand, l->x(), s)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1118
            }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1119
            return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1120
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1121
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1122
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1123
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1124
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1125
  // could not simplify
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1126
  push(type, append(new ShiftOp(code, x, s)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1127
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1128
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1129
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1130
void GraphBuilder::logic_op(ValueType* type, Bytecodes::Code code) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1131
  Value y = pop(type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1132
  Value x = pop(type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1133
  push(type, append(new LogicOp(code, x, y)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1134
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1135
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1136
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1137
void GraphBuilder::compare_op(ValueType* type, Bytecodes::Code code) {
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1138
  ValueStack* state_before = copy_state_before();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1139
  Value y = pop(type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1140
  Value x = pop(type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1141
  ipush(append(new CompareOp(code, x, y, state_before)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1142
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1143
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1144
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1145
void GraphBuilder::convert(Bytecodes::Code op, BasicType from, BasicType to) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1146
  push(as_ValueType(to), append(new Convert(op, pop(as_ValueType(from)), as_ValueType(to))));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1147
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1148
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1149
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1150
void GraphBuilder::increment() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1151
  int index = stream()->get_index();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1152
  int delta = stream()->is_wide() ? (signed short)Bytes::get_Java_u2(stream()->cur_bcp() + 4) : (signed char)(stream()->cur_bcp()[2]);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1153
  load_local(intType, index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1154
  ipush(append(new Constant(new IntConstant(delta))));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1155
  arithmetic_op(intType, Bytecodes::_iadd);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1156
  store_local(intType, index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1157
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1158
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1159
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1160
void GraphBuilder::_goto(int from_bci, int to_bci) {
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1161
  Goto *x = new Goto(block_at(to_bci), to_bci <= from_bci);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1162
  if (is_profiling()) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1163
    compilation()->set_would_profile(true);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1164
  }
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1165
  if (profile_branches()) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1166
    x->set_profiled_method(method());
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1167
    x->set_profiled_bci(bci());
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1168
    x->set_should_profile(true);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1169
  }
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1170
  append(x);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1171
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1172
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1173
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1174
void GraphBuilder::if_node(Value x, If::Condition cond, Value y, ValueStack* state_before) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1175
  BlockBegin* tsux = block_at(stream()->get_dest());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1176
  BlockBegin* fsux = block_at(stream()->next_bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1177
  bool is_bb = tsux->bci() < stream()->cur_bci() || fsux->bci() < stream()->cur_bci();
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1178
  Instruction *i = append(new If(x, cond, false, y, tsux, fsux, is_bb ? state_before : NULL, is_bb));
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1179
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1180
  if (is_profiling()) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1181
    If* if_node = i->as_If();
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1182
    if (if_node != NULL) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1183
      // Note that we'd collect profile data in this method if we wanted it.
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1184
      compilation()->set_would_profile(true);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1185
      // At level 2 we need the proper bci to count backedges
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1186
      if_node->set_profiled_bci(bci());
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1187
      if (profile_branches()) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1188
        // Successors can be rotated by the canonicalizer, check for this case.
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1189
        if_node->set_profiled_method(method());
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1190
        if_node->set_should_profile(true);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1191
        if (if_node->tsux() == fsux) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1192
          if_node->set_swapped(true);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1193
        }
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1194
      }
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1195
      return;
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1196
    }
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1197
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1198
    // Check if this If was reduced to Goto.
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1199
    Goto *goto_node = i->as_Goto();
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1200
    if (goto_node != NULL) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1201
      compilation()->set_would_profile(true);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1202
      if (profile_branches()) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1203
        goto_node->set_profiled_method(method());
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1204
        goto_node->set_profiled_bci(bci());
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1205
        goto_node->set_should_profile(true);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1206
        // Find out which successor is used.
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1207
        if (goto_node->default_sux() == tsux) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1208
          goto_node->set_direction(Goto::taken);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1209
        } else if (goto_node->default_sux() == fsux) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1210
          goto_node->set_direction(Goto::not_taken);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1211
        } else {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1212
          ShouldNotReachHere();
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1213
        }
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1214
      }
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1215
      return;
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1216
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1217
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1218
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1219
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1220
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1221
void GraphBuilder::if_zero(ValueType* type, If::Condition cond) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1222
  Value y = append(new Constant(intZero));
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1223
  ValueStack* state_before = copy_state_before();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1224
  Value x = ipop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1225
  if_node(x, cond, y, state_before);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1226
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1227
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1228
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1229
void GraphBuilder::if_null(ValueType* type, If::Condition cond) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1230
  Value y = append(new Constant(objectNull));
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1231
  ValueStack* state_before = copy_state_before();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1232
  Value x = apop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1233
  if_node(x, cond, y, state_before);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1234
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1235
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1236
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1237
void GraphBuilder::if_same(ValueType* type, If::Condition cond) {
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1238
  ValueStack* state_before = copy_state_before();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1239
  Value y = pop(type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1240
  Value x = pop(type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1241
  if_node(x, cond, y, state_before);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1242
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1243
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1244
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1245
void GraphBuilder::jsr(int dest) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1246
  // We only handle well-formed jsrs (those which are "block-structured").
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1247
  // If the bytecodes are strange (jumping out of a jsr block) then we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1248
  // might end up trying to re-parse a block containing a jsr which
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1249
  // has already been activated. Watch for this case and bail out.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1250
  for (ScopeData* cur_scope_data = scope_data();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1251
       cur_scope_data != NULL && cur_scope_data->parsing_jsr() && cur_scope_data->scope() == scope();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1252
       cur_scope_data = cur_scope_data->parent()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1253
    if (cur_scope_data->jsr_entry_bci() == dest) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1254
      BAILOUT("too-complicated jsr/ret structure");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1255
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1256
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1257
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1258
  push(addressType, append(new Constant(new AddressConstant(next_bci()))));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1259
  if (!try_inline_jsr(dest)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1260
    return; // bailed out while parsing and inlining subroutine
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1261
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1262
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1263
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1264
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1265
void GraphBuilder::ret(int local_index) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1266
  if (!parsing_jsr()) BAILOUT("ret encountered while not parsing subroutine");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1267
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1268
  if (local_index != scope_data()->jsr_return_address_local()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1269
    BAILOUT("can not handle complicated jsr/ret constructs");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1270
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1271
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1272
  // Rets simply become (NON-SAFEPOINT) gotos to the jsr continuation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1273
  append(new Goto(scope_data()->jsr_continuation(), false));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1274
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1275
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1276
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1277
void GraphBuilder::table_switch() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1278
  Bytecode_tableswitch* switch_ = Bytecode_tableswitch_at(method()->code() + bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1279
  const int l = switch_->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1280
  if (CanonicalizeNodes && l == 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1281
    // total of 2 successors => use If instead of switch
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1282
    // Note: This code should go into the canonicalizer as soon as it can
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1283
    //       can handle canonicalized forms that contain more than one node.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1284
    Value key = append(new Constant(new IntConstant(switch_->low_key())));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1285
    BlockBegin* tsux = block_at(bci() + switch_->dest_offset_at(0));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1286
    BlockBegin* fsux = block_at(bci() + switch_->default_offset());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1287
    bool is_bb = tsux->bci() < bci() || fsux->bci() < bci();
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1288
    ValueStack* state_before = is_bb ? copy_state_before() : NULL;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1289
    append(new If(ipop(), If::eql, true, key, tsux, fsux, state_before, is_bb));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1290
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1291
    // collect successors
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1292
    BlockList* sux = new BlockList(l + 1, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1293
    int i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1294
    bool has_bb = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1295
    for (i = 0; i < l; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1296
      sux->at_put(i, block_at(bci() + switch_->dest_offset_at(i)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1297
      if (switch_->dest_offset_at(i) < 0) has_bb = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1298
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1299
    // add default successor
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1300
    sux->at_put(i, block_at(bci() + switch_->default_offset()));
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1301
    ValueStack* state_before = has_bb ? copy_state_before() : NULL;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1302
    append(new TableSwitch(ipop(), sux, switch_->low_key(), state_before, has_bb));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1303
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1304
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1305
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1306
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1307
void GraphBuilder::lookup_switch() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1308
  Bytecode_lookupswitch* switch_ = Bytecode_lookupswitch_at(method()->code() + bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1309
  const int l = switch_->number_of_pairs();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1310
  if (CanonicalizeNodes && l == 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1311
    // total of 2 successors => use If instead of switch
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1312
    // Note: This code should go into the canonicalizer as soon as it can
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1313
    //       can handle canonicalized forms that contain more than one node.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1314
    // simplify to If
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1315
    LookupswitchPair* pair = switch_->pair_at(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1316
    Value key = append(new Constant(new IntConstant(pair->match())));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1317
    BlockBegin* tsux = block_at(bci() + pair->offset());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1318
    BlockBegin* fsux = block_at(bci() + switch_->default_offset());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1319
    bool is_bb = tsux->bci() < bci() || fsux->bci() < bci();
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1320
    ValueStack* state_before = is_bb ? copy_state_before() : NULL;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1321
    append(new If(ipop(), If::eql, true, key, tsux, fsux, state_before, is_bb));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1322
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1323
    // collect successors & keys
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1324
    BlockList* sux = new BlockList(l + 1, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1325
    intArray* keys = new intArray(l, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1326
    int i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1327
    bool has_bb = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1328
    for (i = 0; i < l; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1329
      LookupswitchPair* pair = switch_->pair_at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1330
      if (pair->offset() < 0) has_bb = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1331
      sux->at_put(i, block_at(bci() + pair->offset()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1332
      keys->at_put(i, pair->match());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1333
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1334
    // add default successor
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1335
    sux->at_put(i, block_at(bci() + switch_->default_offset()));
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1336
    ValueStack* state_before = has_bb ? copy_state_before() : NULL;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1337
    append(new LookupSwitch(ipop(), sux, keys, state_before, has_bb));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1338
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1339
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1340
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1341
void GraphBuilder::call_register_finalizer() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1342
  // If the receiver requires finalization then emit code to perform
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1343
  // the registration on return.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1344
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1345
  // Gather some type information about the receiver
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1346
  Value receiver = state()->local_at(0);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1347
  assert(receiver != NULL, "must have a receiver");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1348
  ciType* declared_type = receiver->declared_type();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1349
  ciType* exact_type = receiver->exact_type();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1350
  if (exact_type == NULL &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1351
      receiver->as_Local() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1352
      receiver->as_Local()->java_index() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1353
    ciInstanceKlass* ik = compilation()->method()->holder();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1354
    if (ik->is_final()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1355
      exact_type = ik;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1356
    } else if (UseCHA && !(ik->has_subklass() || ik->is_interface())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1357
      // test class is leaf class
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1358
      compilation()->dependency_recorder()->assert_leaf_type(ik);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1359
      exact_type = ik;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1360
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1361
      declared_type = ik;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1362
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1363
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1364
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1365
  // see if we know statically that registration isn't required
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1366
  bool needs_check = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1367
  if (exact_type != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1368
    needs_check = exact_type->as_instance_klass()->has_finalizer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1369
  } else if (declared_type != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1370
    ciInstanceKlass* ik = declared_type->as_instance_klass();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1371
    if (!Dependencies::has_finalizable_subclass(ik)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1372
      compilation()->dependency_recorder()->assert_has_no_finalizable_subclasses(ik);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1373
      needs_check = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1374
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1375
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1376
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1377
  if (needs_check) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1378
    // Perform the registration of finalizable objects.
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1379
    ValueStack* state_before = copy_state_for_exception();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1380
    load_local(objectType, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1381
    append_split(new Intrinsic(voidType, vmIntrinsics::_Object_init,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1382
                               state()->pop_arguments(1),
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1383
                               true, state_before, true));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1384
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1385
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1386
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1387
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1388
void GraphBuilder::method_return(Value x) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1389
  if (RegisterFinalizersAtInit &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1390
      method()->intrinsic_id() == vmIntrinsics::_Object_init) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1391
    call_register_finalizer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1392
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1393
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1394
  // Check to see whether we are inlining. If so, Return
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1395
  // instructions become Gotos to the continuation point.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1396
  if (continuation() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1397
    assert(!method()->is_synchronized() || InlineSynchronizedMethods, "can not inline synchronized methods yet");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1398
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1399
    // If the inlined method is synchronized, the monitor must be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1400
    // released before we jump to the continuation block.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1401
    if (method()->is_synchronized()) {
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1402
      assert(state()->locks_size() == 1, "receiver must be locked here");
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1403
      monitorexit(state()->lock_at(0), SynchronizationEntryBCI);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1404
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1405
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1406
    // State at end of inlined method is the state of the caller
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1407
    // without the method parameters on stack, including the
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1408
    // return value, if any, of the inlined method on operand stack.
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1409
    set_state(state()->caller_state()->copy_for_parsing());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1410
    if (x != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1411
      state()->push(x->type(), x);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1412
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1413
    Goto* goto_callee = new Goto(continuation(), false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1414
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1415
    // See whether this is the first return; if so, store off some
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1416
    // of the state for later examination
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1417
    if (num_returns() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1418
      set_inline_cleanup_info(_block, _last, state());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1419
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1420
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1421
    // The current bci() is in the wrong scope, so use the bci() of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1422
    // the continuation point.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1423
    append_with_bci(goto_callee, scope_data()->continuation()->bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1424
    incr_num_returns();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1425
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1426
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1427
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1428
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1429
  state()->truncate_stack(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1430
  if (method()->is_synchronized()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1431
    // perform the unlocking before exiting the method
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1432
    Value receiver;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1433
    if (!method()->is_static()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1434
      receiver = _initial_state->local_at(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1435
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1436
      receiver = append(new Constant(new ClassConstant(method()->holder())));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1437
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1438
    append_split(new MonitorExit(receiver, state()->unlock()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1439
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1440
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1441
  append(new Return(x));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1442
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1443
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1444
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1445
void GraphBuilder::access_field(Bytecodes::Code code) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1446
  bool will_link;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1447
  ciField* field = stream()->get_field(will_link);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1448
  ciInstanceKlass* holder = field->holder();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1449
  BasicType field_type = field->type()->basic_type();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1450
  ValueType* type = as_ValueType(field_type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1451
  // call will_link again to determine if the field is valid.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1452
  const bool is_loaded = holder->is_loaded() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1453
                         field->will_link(method()->holder(), code);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1454
  const bool is_initialized = is_loaded && holder->is_initialized();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1455
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1456
  ValueStack* state_before = NULL;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1457
  if (!is_initialized || PatchALot) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1458
    // save state before instruction for debug info when
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1459
    // deoptimization happens during patching
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1460
    state_before = copy_state_before();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1461
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1462
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1463
  Value obj = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1464
  if (code == Bytecodes::_getstatic || code == Bytecodes::_putstatic) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1465
    // commoning of class constants should only occur if the class is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1466
    // fully initialized and resolved in this constant pool.  The will_link test
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1467
    // above essentially checks if this class is resolved in this constant pool
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1468
    // so, the is_initialized flag should be suffiect.
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1469
    if (state_before != NULL) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1470
      // build a patching constant
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1471
      obj = new Constant(new ClassConstant(holder), state_before);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1472
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1473
      obj = new Constant(new ClassConstant(holder));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1474
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1475
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1476
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1477
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1478
  const int offset = is_loaded ? field->offset() : -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1479
  switch (code) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1480
    case Bytecodes::_getstatic: {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1481
      // check for compile-time constants, i.e., initialized static final fields
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1482
      Instruction* constant = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1483
      if (field->is_constant() && !PatchALot) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1484
        ciConstant field_val = field->constant_value();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1485
        BasicType field_type = field_val.basic_type();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1486
        switch (field_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1487
        case T_ARRAY:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1488
        case T_OBJECT:
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 3261
diff changeset
  1489
          if (field_val.as_object()->should_be_constant()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1490
            constant =  new Constant(as_ValueType(field_val));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1491
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1492
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1493
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1494
        default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1495
          constant = new Constant(as_ValueType(field_val));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1496
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1497
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1498
      if (constant != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1499
        push(type, append(constant));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1500
      } else {
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1501
        if (state_before == NULL) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1502
          state_before = copy_state_for_exception();
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1503
        }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1504
        push(type, append(new LoadField(append(obj), offset, field, true,
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1505
                                        state_before, is_loaded, is_initialized)));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1506
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1507
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1508
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1509
    case Bytecodes::_putstatic:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1510
      { Value val = pop(type);
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1511
        if (state_before == NULL) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1512
          state_before = copy_state_for_exception();
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1513
        }
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1514
        append(new StoreField(append(obj), offset, field, val, true, state_before, is_loaded, is_initialized));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1515
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1516
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1517
    case Bytecodes::_getfield :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1518
      {
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1519
        if (state_before == NULL) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1520
          state_before = copy_state_for_exception();
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1521
        }
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1522
        LoadField* load = new LoadField(apop(), offset, field, false, state_before, is_loaded, true);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1523
        Value replacement = is_loaded ? _memory->load(load) : load;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1524
        if (replacement != load) {
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1525
          assert(replacement->is_linked() || !replacement->can_be_linked(), "should already by linked");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1526
          push(type, replacement);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1527
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1528
          push(type, append(load));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1529
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1530
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1531
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1532
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1533
    case Bytecodes::_putfield :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1534
      { Value val = pop(type);
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1535
        if (state_before == NULL) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1536
          state_before = copy_state_for_exception();
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1537
        }
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1538
        StoreField* store = new StoreField(apop(), offset, field, val, false, state_before, is_loaded, true);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1539
        if (is_loaded) store = _memory->store(store);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1540
        if (store != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1541
          append(store);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1542
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1543
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1544
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1545
    default                   :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1546
      ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1547
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1548
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1549
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1550
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1551
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1552
Dependencies* GraphBuilder::dependency_recorder() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1553
  assert(DeoptC1, "need debug information");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1554
  return compilation()->dependency_recorder();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1555
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1556
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1557
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1558
void GraphBuilder::invoke(Bytecodes::Code code) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1559
  bool will_link;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1560
  ciMethod* target = stream()->get_method(will_link);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1561
  // we have to make sure the argument size (incl. the receiver)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1562
  // is correct for compilation (the call would fail later during
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1563
  // linkage anyway) - was bug (gri 7/28/99)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1564
  if (target->is_loaded() && target->is_static() != (code == Bytecodes::_invokestatic)) BAILOUT("will cause link error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1565
  ciInstanceKlass* klass = target->holder();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1566
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1567
  // check if CHA possible: if so, change the code to invoke_special
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1568
  ciInstanceKlass* calling_klass = method()->holder();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1569
  ciKlass* holder = stream()->get_declared_method_holder();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1570
  ciInstanceKlass* callee_holder = ciEnv::get_instance_klass_for_declared_method_holder(holder);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1571
  ciInstanceKlass* actual_recv = callee_holder;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1572
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1573
  // some methods are obviously bindable without any type checks so
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1574
  // convert them directly to an invokespecial.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1575
  if (target->is_loaded() && !target->is_abstract() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1576
      target->can_be_statically_bound() && code == Bytecodes::_invokevirtual) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1577
    code = Bytecodes::_invokespecial;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1578
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1579
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1580
  // NEEDS_CLEANUP
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1581
  // I've added the target-is_loaded() test below but I don't really understand
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1582
  // how klass->is_loaded() can be true and yet target->is_loaded() is false.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1583
  // this happened while running the JCK invokevirtual tests under doit.  TKR
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1584
  ciMethod* cha_monomorphic_target = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1585
  ciMethod* exact_target = NULL;
5046
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4430
diff changeset
  1586
  if (UseCHA && DeoptC1 && klass->is_loaded() && target->is_loaded() &&
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4430
diff changeset
  1587
      !target->is_method_handle_invoke()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1588
    Value receiver = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1589
    ciInstanceKlass* receiver_klass = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1590
    bool type_is_exact = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1591
    // try to find a precise receiver type
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1592
    if (will_link && !target->is_static()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1593
      int index = state()->stack_size() - (target->arg_size_no_receiver() + 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1594
      receiver = state()->stack_at(index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1595
      ciType* type = receiver->exact_type();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1596
      if (type != NULL && type->is_loaded() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1597
          type->is_instance_klass() && !type->as_instance_klass()->is_interface()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1598
        receiver_klass = (ciInstanceKlass*) type;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1599
        type_is_exact = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1600
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1601
      if (type == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1602
        type = receiver->declared_type();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1603
        if (type != NULL && type->is_loaded() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1604
            type->is_instance_klass() && !type->as_instance_klass()->is_interface()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1605
          receiver_klass = (ciInstanceKlass*) type;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1606
          if (receiver_klass->is_leaf_type() && !receiver_klass->is_final()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1607
            // Insert a dependency on this type since
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1608
            // find_monomorphic_target may assume it's already done.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1609
            dependency_recorder()->assert_leaf_type(receiver_klass);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1610
            type_is_exact = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1611
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1612
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1613
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1614
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1615
    if (receiver_klass != NULL && type_is_exact &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1616
        receiver_klass->is_loaded() && code != Bytecodes::_invokespecial) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1617
      // If we have the exact receiver type we can bind directly to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1618
      // the method to call.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1619
      exact_target = target->resolve_invoke(calling_klass, receiver_klass);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1620
      if (exact_target != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1621
        target = exact_target;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1622
        code = Bytecodes::_invokespecial;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1623
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1624
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1625
    if (receiver_klass != NULL &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1626
        receiver_klass->is_subtype_of(actual_recv) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1627
        actual_recv->is_initialized()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1628
      actual_recv = receiver_klass;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1629
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1630
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1631
    if ((code == Bytecodes::_invokevirtual && callee_holder->is_initialized()) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1632
        (code == Bytecodes::_invokeinterface && callee_holder->is_initialized() && !actual_recv->is_interface())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1633
      // Use CHA on the receiver to select a more precise method.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1634
      cha_monomorphic_target = target->find_monomorphic_target(calling_klass, callee_holder, actual_recv);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1635
    } else if (code == Bytecodes::_invokeinterface && callee_holder->is_loaded() && receiver != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1636
      // if there is only one implementor of this interface then we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1637
      // may be able bind this invoke directly to the implementing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1638
      // klass but we need both a dependence on the single interface
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1639
      // and on the method we bind to.  Additionally since all we know
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1640
      // about the receiver type is the it's supposed to implement the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1641
      // interface we have to insert a check that it's the class we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1642
      // expect.  Interface types are not checked by the verifier so
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1643
      // they are roughly equivalent to Object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1644
      ciInstanceKlass* singleton = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1645
      if (target->holder()->nof_implementors() == 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1646
        singleton = target->holder()->implementor(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1647
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1648
      if (singleton) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1649
        cha_monomorphic_target = target->find_monomorphic_target(calling_klass, target->holder(), singleton);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1650
        if (cha_monomorphic_target != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1651
          // If CHA is able to bind this invoke then update the class
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1652
          // to match that class, otherwise klass will refer to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1653
          // interface.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1654
          klass = cha_monomorphic_target->holder();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1655
          actual_recv = target->holder();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1656
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1657
          // insert a check it's really the expected class.
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1658
          CheckCast* c = new CheckCast(klass, receiver, copy_state_for_exception());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1659
          c->set_incompatible_class_change_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1660
          c->set_direct_compare(klass->is_final());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1661
          append_split(c);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1662
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1663
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1664
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1665
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1666
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1667
  if (cha_monomorphic_target != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1668
    if (cha_monomorphic_target->is_abstract()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1669
      // Do not optimize for abstract methods
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1670
      cha_monomorphic_target = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1671
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1672
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1673
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1674
  if (cha_monomorphic_target != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1675
    if (!(target->is_final_method())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1676
      // If we inlined because CHA revealed only a single target method,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1677
      // then we are dependent on that target method not getting overridden
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1678
      // by dynamic class loading.  Be sure to test the "static" receiver
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1679
      // dest_method here, as opposed to the actual receiver, which may
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1680
      // falsely lead us to believe that the receiver is final or private.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1681
      dependency_recorder()->assert_unique_concrete_method(actual_recv, cha_monomorphic_target);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1682
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1683
    code = Bytecodes::_invokespecial;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1684
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1685
  // check if we could do inlining
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1686
  if (!PatchALot && Inline && klass->is_loaded() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1687
      (klass->is_initialized() || klass->is_interface() && target->holder()->is_initialized())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1688
      && target->will_link(klass, callee_holder, code)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1689
    // callee is known => check if we have static binding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1690
    assert(target->is_loaded(), "callee must be known");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1691
    if (code == Bytecodes::_invokestatic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1692
     || code == Bytecodes::_invokespecial
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1693
     || code == Bytecodes::_invokevirtual && target->is_final_method()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1694
    ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1695
      // static binding => check if callee is ok
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1696
      ciMethod* inline_target = (cha_monomorphic_target != NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1697
                                  ? cha_monomorphic_target
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1698
                                  : target;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1699
      bool res = try_inline(inline_target, (cha_monomorphic_target != NULL) || (exact_target != NULL));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1700
      CHECK_BAILOUT();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1701
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1702
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1703
      // printing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1704
      if (PrintInlining && !res) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1705
        // if it was successfully inlined, then it was already printed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1706
        print_inline_result(inline_target, res);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1707
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1708
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1709
      clear_inline_bailout();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1710
      if (res) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1711
        // Register dependence if JVMTI has either breakpoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1712
        // setting or hotswapping of methods capabilities since they may
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1713
        // cause deoptimization.
2867
69187054225f 6788527: Server vm intermittently fails with assertion "live value must not be garbage" with fastdebug bits
kvn
parents: 2570
diff changeset
  1714
        if (compilation()->env()->jvmti_can_hotswap_or_post_breakpoint()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1715
          dependency_recorder()->assert_evol_method(inline_target);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1716
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1717
        return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1718
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1719
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1720
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1721
  // If we attempted an inline which did not succeed because of a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1722
  // bailout during construction of the callee graph, the entire
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1723
  // compilation has to be aborted. This is fairly rare and currently
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1724
  // seems to only occur for jasm-generated classes which contain
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1725
  // jsr/ret pairs which are not associated with finally clauses and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1726
  // do not have exception handlers in the containing method, and are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1727
  // therefore not caught early enough to abort the inlining without
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1728
  // corrupting the graph. (We currently bail out with a non-empty
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1729
  // stack at a ret in these situations.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1730
  CHECK_BAILOUT();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1731
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1732
  // inlining not successful => standard invoke
5046
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4430
diff changeset
  1733
  bool is_loaded = target->is_loaded();
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4430
diff changeset
  1734
  bool has_receiver =
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4430
diff changeset
  1735
    code == Bytecodes::_invokespecial   ||
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4430
diff changeset
  1736
    code == Bytecodes::_invokevirtual   ||
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4430
diff changeset
  1737
    code == Bytecodes::_invokeinterface;
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4430
diff changeset
  1738
  bool is_invokedynamic = code == Bytecodes::_invokedynamic;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1739
  ValueType* result_type = as_ValueType(target->return_type());
5046
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4430
diff changeset
  1740
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4430
diff changeset
  1741
  // We require the debug info to be the "state before" because
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4430
diff changeset
  1742
  // invokedynamics may deoptimize.
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1743
  ValueStack* state_before = is_invokedynamic ? copy_state_before() : copy_state_exhandling();
5046
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4430
diff changeset
  1744
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1745
  Values* args = state()->pop_arguments(target->arg_size_no_receiver());
5046
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4430
diff changeset
  1746
  Value recv = has_receiver ? apop() : NULL;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1747
  int vtable_index = methodOopDesc::invalid_vtable_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1748
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1749
#ifdef SPARC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1750
  // Currently only supported on Sparc.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1751
  // The UseInlineCaches only controls dispatch to invokevirtuals for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1752
  // loaded classes which we weren't able to statically bind.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1753
  if (!UseInlineCaches && is_loaded && code == Bytecodes::_invokevirtual
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1754
      && !target->can_be_statically_bound()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1755
    // Find a vtable index if one is available
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1756
    vtable_index = target->resolve_vtable_index(calling_klass, callee_holder);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1757
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1758
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1759
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1760
  if (recv != NULL &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1761
      (code == Bytecodes::_invokespecial ||
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1762
       !is_loaded || target->is_final())) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1763
    // invokespecial always needs a NULL check.  invokevirtual where
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1764
    // the target is final or where it's not known that whether the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1765
    // target is final requires a NULL check.  Otherwise normal
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1766
    // invokevirtual will perform the null check during the lookup
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1767
    // logic or the unverified entry point.  Profiling of calls
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1768
    // requires that the null check is performed in all cases.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1769
    null_check(recv);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1770
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1771
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1772
  if (is_profiling()) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1773
    if (recv != NULL && profile_calls()) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1774
      null_check(recv);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1775
    }
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1776
    // Note that we'd collect profile data in this method if we wanted it.
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1777
    compilation()->set_would_profile(true);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1778
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1779
    if (profile_calls()) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1780
      assert(cha_monomorphic_target == NULL || exact_target == NULL, "both can not be set");
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1781
      ciKlass* target_klass = NULL;
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1782
      if (cha_monomorphic_target != NULL) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1783
        target_klass = cha_monomorphic_target->holder();
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1784
      } else if (exact_target != NULL) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1785
        target_klass = exact_target->holder();
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1786
      }
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1787
      profile_call(recv, target_klass);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1788
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1789
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1790
5046
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4430
diff changeset
  1791
  Invoke* result = new Invoke(code, result_type, recv, args, vtable_index, target, state_before);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1792
  // push result
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1793
  append_split(result);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1794
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1795
  if (result_type != voidType) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1796
    if (method()->is_strict()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1797
      push(result_type, round_fp(result));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1798
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1799
      push(result_type, result);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1800
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1801
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1802
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1803
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1804
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1805
void GraphBuilder::new_instance(int klass_index) {
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1806
  ValueStack* state_before = copy_state_exhandling();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1807
  bool will_link;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1808
  ciKlass* klass = stream()->get_klass(will_link);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1809
  assert(klass->is_instance_klass(), "must be an instance klass");
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1810
  NewInstance* new_instance = new NewInstance(klass->as_instance_klass(), state_before);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1811
  _memory->new_instance(new_instance);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1812
  apush(append_split(new_instance));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1813
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1814
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1815
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1816
void GraphBuilder::new_type_array() {
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1817
  ValueStack* state_before = copy_state_exhandling();
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1818
  apush(append_split(new NewTypeArray(ipop(), (BasicType)stream()->get_index(), state_before)));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1819
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1820
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1821
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1822
void GraphBuilder::new_object_array() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1823
  bool will_link;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1824
  ciKlass* klass = stream()->get_klass(will_link);
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1825
  ValueStack* state_before = !klass->is_loaded() || PatchALot ? copy_state_before() : copy_state_exhandling();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1826
  NewArray* n = new NewObjectArray(klass, ipop(), state_before);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1827
  apush(append_split(n));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1828
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1829
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1830
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1831
bool GraphBuilder::direct_compare(ciKlass* k) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1832
  if (k->is_loaded() && k->is_instance_klass() && !UseSlowPath) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1833
    ciInstanceKlass* ik = k->as_instance_klass();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1834
    if (ik->is_final()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1835
      return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1836
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1837
      if (DeoptC1 && UseCHA && !(ik->has_subklass() || ik->is_interface())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1838
        // test class is leaf class
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1839
        dependency_recorder()->assert_leaf_type(ik);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1840
        return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1841
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1842
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1843
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1844
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1845
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1846
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1847
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1848
void GraphBuilder::check_cast(int klass_index) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1849
  bool will_link;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1850
  ciKlass* klass = stream()->get_klass(will_link);
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1851
  ValueStack* state_before = !klass->is_loaded() || PatchALot ? copy_state_before() : copy_state_for_exception();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1852
  CheckCast* c = new CheckCast(klass, apop(), state_before);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1853
  apush(append_split(c));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1854
  c->set_direct_compare(direct_compare(klass));
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1855
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1856
  if (is_profiling()) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1857
    // Note that we'd collect profile data in this method if we wanted it.
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1858
    compilation()->set_would_profile(true);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1859
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1860
    if (profile_checkcasts()) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1861
      c->set_profiled_method(method());
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1862
      c->set_profiled_bci(bci());
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1863
      c->set_should_profile(true);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1864
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1865
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1866
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1867
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1868
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1869
void GraphBuilder::instance_of(int klass_index) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1870
  bool will_link;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1871
  ciKlass* klass = stream()->get_klass(will_link);
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1872
  ValueStack* state_before = !klass->is_loaded() || PatchALot ? copy_state_before() : copy_state_exhandling();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1873
  InstanceOf* i = new InstanceOf(klass, apop(), state_before);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1874
  ipush(append_split(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1875
  i->set_direct_compare(direct_compare(klass));
6461
cfc616b49f58 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 6453
diff changeset
  1876
cfc616b49f58 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 6453
diff changeset
  1877
  if (is_profiling()) {
cfc616b49f58 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 6453
diff changeset
  1878
    // Note that we'd collect profile data in this method if we wanted it.
cfc616b49f58 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 6453
diff changeset
  1879
    compilation()->set_would_profile(true);
cfc616b49f58 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 6453
diff changeset
  1880
cfc616b49f58 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 6453
diff changeset
  1881
    if (profile_checkcasts()) {
cfc616b49f58 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 6453
diff changeset
  1882
      i->set_profiled_method(method());
cfc616b49f58 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 6453
diff changeset
  1883
      i->set_profiled_bci(bci());
cfc616b49f58 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 6453
diff changeset
  1884
      i->set_should_profile(true);
cfc616b49f58 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 6453
diff changeset
  1885
    }
cfc616b49f58 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 6453
diff changeset
  1886
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1887
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1888
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1889
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1890
void GraphBuilder::monitorenter(Value x, int bci) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1891
  // save state before locking in case of deoptimization after a NullPointerException
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1892
  ValueStack* state_before = copy_state_for_exception_with_bci(bci);
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1893
  append_with_bci(new MonitorEnter(x, state()->lock(x), state_before), bci);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1894
  kill_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1895
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1896
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1897
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1898
void GraphBuilder::monitorexit(Value x, int bci) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1899
  append_with_bci(new MonitorExit(x, state()->unlock()), bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1900
  kill_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1901
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1902
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1903
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1904
void GraphBuilder::new_multi_array(int dimensions) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1905
  bool will_link;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1906
  ciKlass* klass = stream()->get_klass(will_link);
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1907
  ValueStack* state_before = !klass->is_loaded() || PatchALot ? copy_state_before() : copy_state_exhandling();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1908
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1909
  Values* dims = new Values(dimensions, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1910
  // fill in all dimensions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1911
  int i = dimensions;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1912
  while (i-- > 0) dims->at_put(i, ipop());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1913
  // create array
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1914
  NewArray* n = new NewMultiArray(klass, dims, state_before);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1915
  apush(append_split(n));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1916
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1917
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1918
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1919
void GraphBuilder::throw_op(int bci) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1920
  // We require that the debug info for a Throw be the "state before"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1921
  // the Throw (i.e., exception oop is still on TOS)
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1922
  ValueStack* state_before = copy_state_before_with_bci(bci);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1923
  Throw* t = new Throw(apop(), state_before);
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1924
  // operand stack not needed after a throw
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1925
  state()->truncate_stack(0);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1926
  append_with_bci(t, bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1927
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1928
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1929
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1930
Value GraphBuilder::round_fp(Value fp_value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1931
  // no rounding needed if SSE2 is used
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1932
  if (RoundFPResults && UseSSE < 2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1933
    // Must currently insert rounding node for doubleword values that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1934
    // are results of expressions (i.e., not loads from memory or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1935
    // constants)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1936
    if (fp_value->type()->tag() == doubleTag &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1937
        fp_value->as_Constant() == NULL &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1938
        fp_value->as_Local() == NULL &&       // method parameters need no rounding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1939
        fp_value->as_RoundFP() == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1940
      return append(new RoundFP(fp_value));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1941
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1942
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1943
  return fp_value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1944
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1945
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1946
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1947
Instruction* GraphBuilder::append_with_bci(Instruction* instr, int bci) {
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1948
  Canonicalizer canon(compilation(), instr, bci);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1949
  Instruction* i1 = canon.canonical();
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1950
  if (i1->is_linked() || !i1->can_be_linked()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1951
    // Canonicalizer returned an instruction which was already
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1952
    // appended so simply return it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1953
    return i1;
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1954
  }
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1955
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1956
  if (UseLocalValueNumbering) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1957
    // Lookup the instruction in the ValueMap and add it to the map if
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1958
    // it's not found.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1959
    Instruction* i2 = vmap()->find_insert(i1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1960
    if (i2 != i1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1961
      // found an entry in the value map, so just return it.
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1962
      assert(i2->is_linked(), "should already be linked");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1963
      return i2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1964
    }
1612
2488b45ded37 6756768: C1 generates invalid code
never
parents: 1
diff changeset
  1965
    ValueNumberingEffects vne(vmap());
2488b45ded37 6756768: C1 generates invalid code
never
parents: 1
diff changeset
  1966
    i1->visit(&vne);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1967
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1968
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1969
  // i1 was not eliminated => append it
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1970
  assert(i1->next() == NULL, "shouldn't already be linked");
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1971
  _last = _last->set_next(i1, canon.bci());
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1972
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1973
  if (++_instruction_count >= InstructionCountCutoff && !bailed_out()) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1974
    // set the bailout state but complete normal processing.  We
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1975
    // might do a little more work before noticing the bailout so we
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1976
    // want processing to continue normally until it's noticed.
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1977
    bailout("Method and/or inlining is too large");
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1978
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1979
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1980
#ifndef PRODUCT
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1981
  if (PrintIRDuringConstruction) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1982
    InstructionPrinter ip;
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1983
    ip.print_line(i1);
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1984
    if (Verbose) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1985
      state()->print();
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1986
    }
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1987
  }
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1988
#endif
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1989
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1990
  // save state after modification of operand stack for StateSplit instructions
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1991
  StateSplit* s = i1->as_StateSplit();
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1992
  if (s != NULL) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1993
    if (EliminateFieldAccess) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1994
      Intrinsic* intrinsic = s->as_Intrinsic();
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1995
      if (s->as_Invoke() != NULL || (intrinsic && !intrinsic->preserves_state())) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1996
        _memory->kill();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1997
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1998
    }
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1999
    s->set_state(state()->copy(ValueStack::StateAfter, canon.bci()));
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2000
  }
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2001
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2002
  // set up exception handlers for this instruction if necessary
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2003
  if (i1->can_trap()) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2004
    i1->set_exception_handlers(handle_exception(i1));
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2005
    assert(i1->exception_state() != NULL || !i1->needs_exception_state() || bailed_out(), "handle_exception must set exception state");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2006
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2007
  return i1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2008
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2009
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2010
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2011
Instruction* GraphBuilder::append(Instruction* instr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2012
  assert(instr->as_StateSplit() == NULL || instr->as_BlockEnd() != NULL, "wrong append used");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2013
  return append_with_bci(instr, bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2014
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2015
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2016
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2017
Instruction* GraphBuilder::append_split(StateSplit* instr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2018
  return append_with_bci(instr, bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2019
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2020
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2021
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2022
void GraphBuilder::null_check(Value value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2023
  if (value->as_NewArray() != NULL || value->as_NewInstance() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2024
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2025
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2026
    Constant* con = value->as_Constant();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2027
    if (con) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2028
      ObjectType* c = con->type()->as_ObjectType();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2029
      if (c && c->is_loaded()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2030
        ObjectConstant* oc = c->as_ObjectConstant();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2031
        if (!oc || !oc->value()->is_null_object()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2032
          return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2033
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2034
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2035
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2036
  }
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2037
  append(new NullCheck(value, copy_state_for_exception()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2038
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2039
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2040
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2041
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2042
XHandlers* GraphBuilder::handle_exception(Instruction* instruction) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2043
  if (!has_handler() && (!instruction->needs_exception_state() || instruction->exception_state() != NULL)) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2044
    assert(instruction->exception_state() == NULL
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2045
           || instruction->exception_state()->kind() == ValueStack::EmptyExceptionState
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2046
           || (instruction->exception_state()->kind() == ValueStack::ExceptionState && _compilation->env()->jvmti_can_access_local_variables()),
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2047
           "exception_state should be of exception kind");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2048
    return new XHandlers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2049
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2050
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2051
  XHandlers*  exception_handlers = new XHandlers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2052
  ScopeData*  cur_scope_data = scope_data();
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2053
  ValueStack* cur_state = instruction->state_before();
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2054
  ValueStack* prev_state = NULL;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2055
  int scope_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2056
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2057
  assert(cur_state != NULL, "state_before must be set");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2058
  do {
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2059
    int cur_bci = cur_state->bci();
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2060
    assert(cur_scope_data->scope() == cur_state->scope(), "scopes do not match");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2061
    assert(cur_bci == SynchronizationEntryBCI || cur_bci == cur_scope_data->stream()->cur_bci(), "invalid bci");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2062
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2063
    // join with all potential exception handlers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2064
    XHandlers* list = cur_scope_data->xhandlers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2065
    const int n = list->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2066
    for (int i = 0; i < n; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2067
      XHandler* h = list->handler_at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2068
      if (h->covers(cur_bci)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2069
        // h is a potential exception handler => join it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2070
        compilation()->set_has_exception_handlers(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2071
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2072
        BlockBegin* entry = h->entry_block();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2073
        if (entry == block()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2074
          // It's acceptable for an exception handler to cover itself
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2075
          // but we don't handle that in the parser currently.  It's
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2076
          // very rare so we bailout instead of trying to handle it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2077
          BAILOUT_("exception handler covers itself", exception_handlers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2078
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2079
        assert(entry->bci() == h->handler_bci(), "must match");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2080
        assert(entry->bci() == -1 || entry == cur_scope_data->block_at(entry->bci()), "blocks must correspond");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2081
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2082
        // previously this was a BAILOUT, but this is not necessary
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2083
        // now because asynchronous exceptions are not handled this way.
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2084
        assert(entry->state() == NULL || cur_state->total_locks_size() == entry->state()->total_locks_size(), "locks do not match");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2085
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2086
        // xhandler start with an empty expression stack
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2087
        if (cur_state->stack_size() != 0) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2088
          cur_state = cur_state->copy(ValueStack::ExceptionState, cur_state->bci());
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2089
        }
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2090
        if (instruction->exception_state() == NULL) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2091
          instruction->set_exception_state(cur_state);
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2092
        }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2093
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2094
        // Note: Usually this join must work. However, very
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2095
        // complicated jsr-ret structures where we don't ret from
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2096
        // the subroutine can cause the objects on the monitor
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2097
        // stacks to not match because blocks can be parsed twice.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2098
        // The only test case we've seen so far which exhibits this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2099
        // problem is caught by the infinite recursion test in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2100
        // GraphBuilder::jsr() if the join doesn't work.
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2101
        if (!entry->try_merge(cur_state)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2102
          BAILOUT_("error while joining with exception handler, prob. due to complicated jsr/rets", exception_handlers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2103
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2104
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2105
        // add current state for correct handling of phi functions at begin of xhandler
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2106
        int phi_operand = entry->add_exception_state(cur_state);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2107
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2108
        // add entry to the list of xhandlers of this block
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2109
        _block->add_exception_handler(entry);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2110
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2111
        // add back-edge from xhandler entry to this block
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2112
        if (!entry->is_predecessor(_block)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2113
          entry->add_predecessor(_block);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2114
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2115
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2116
        // clone XHandler because phi_operand and scope_count can not be shared
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2117
        XHandler* new_xhandler = new XHandler(h);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2118
        new_xhandler->set_phi_operand(phi_operand);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2119
        new_xhandler->set_scope_count(scope_count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2120
        exception_handlers->append(new_xhandler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2121
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2122
        // fill in exception handler subgraph lazily
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2123
        assert(!entry->is_set(BlockBegin::was_visited_flag), "entry must not be visited yet");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2124
        cur_scope_data->add_to_work_list(entry);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2125
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2126
        // stop when reaching catchall
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2127
        if (h->catch_type() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2128
          return exception_handlers;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2129
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2130
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2131
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2132
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2133
    if (exception_handlers->length() == 0) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2134
      // This scope and all callees do not handle exceptions, so the local
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2135
      // variables of this scope are not needed. However, the scope itself is
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2136
      // required for a correct exception stack trace -> clear out the locals.
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2137
      if (_compilation->env()->jvmti_can_access_local_variables()) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2138
        cur_state = cur_state->copy(ValueStack::ExceptionState, cur_state->bci());
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2139
      } else {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2140
        cur_state = cur_state->copy(ValueStack::EmptyExceptionState, cur_state->bci());
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2141
      }
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2142
      if (prev_state != NULL) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2143
        prev_state->set_caller_state(cur_state);
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2144
      }
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2145
      if (instruction->exception_state() == NULL) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2146
        instruction->set_exception_state(cur_state);
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2147
      }
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2148
    }
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2149
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2150
    // Set up iteration for next time.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2151
    // If parsing a jsr, do not grab exception handlers from the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2152
    // parent scopes for this method (already got them, and they
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2153
    // needed to be cloned)
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2154
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2155
    while (cur_scope_data->parsing_jsr()) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2156
      cur_scope_data = cur_scope_data->parent();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2157
    }
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2158
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2159
    assert(cur_scope_data->scope() == cur_state->scope(), "scopes do not match");
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2160
    assert(cur_state->locks_size() == 0 || cur_state->locks_size() == 1, "unlocking must be done in a catchall exception handler");
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2161
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2162
    prev_state = cur_state;
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2163
    cur_state = cur_state->caller_state();
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2164
    cur_scope_data = cur_scope_data->parent();
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2165
    scope_count++;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2166
  } while (cur_scope_data != NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2167
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2168
  return exception_handlers;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2169
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2170
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2171
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2172
// Helper class for simplifying Phis.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2173
class PhiSimplifier : public BlockClosure {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2174
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2175
  bool _has_substitutions;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2176
  Value simplify(Value v);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2177
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2178
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2179
  PhiSimplifier(BlockBegin* start) : _has_substitutions(false) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2180
    start->iterate_preorder(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2181
    if (_has_substitutions) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2182
      SubstitutionResolver sr(start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2183
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2184
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2185
  void block_do(BlockBegin* b);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2186
  bool has_substitutions() const { return _has_substitutions; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2187
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2188
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2189
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2190
Value PhiSimplifier::simplify(Value v) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2191
  Phi* phi = v->as_Phi();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2192
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2193
  if (phi == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2194
    // no phi function
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2195
    return v;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2196
  } else if (v->has_subst()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2197
    // already substituted; subst can be phi itself -> simplify
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2198
    return simplify(v->subst());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2199
  } else if (phi->is_set(Phi::cannot_simplify)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2200
    // already tried to simplify phi before
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2201
    return phi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2202
  } else if (phi->is_set(Phi::visited)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2203
    // break cycles in phi functions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2204
    return phi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2205
  } else if (phi->type()->is_illegal()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2206
    // illegal phi functions are ignored anyway
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2207
    return phi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2208
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2209
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2210
    // mark phi function as processed to break cycles in phi functions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2211
    phi->set(Phi::visited);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2212
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2213
    // simplify x = [y, x] and x = [y, y] to y
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2214
    Value subst = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2215
    int opd_count = phi->operand_count();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2216
    for (int i = 0; i < opd_count; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2217
      Value opd = phi->operand_at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2218
      assert(opd != NULL, "Operand must exist!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2219
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2220
      if (opd->type()->is_illegal()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2221
        // if one operand is illegal, the entire phi function is illegal
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2222
        phi->make_illegal();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2223
        phi->clear(Phi::visited);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2224
        return phi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2225
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2226
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2227
      Value new_opd = simplify(opd);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2228
      assert(new_opd != NULL, "Simplified operand must exist!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2229
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2230
      if (new_opd != phi && new_opd != subst) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2231
        if (subst == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2232
          subst = new_opd;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2233
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2234
          // no simplification possible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2235
          phi->set(Phi::cannot_simplify);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2236
          phi->clear(Phi::visited);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2237
          return phi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2238
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2239
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2240
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2241
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2242
    // sucessfully simplified phi function
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2243
    assert(subst != NULL, "illegal phi function");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2244
    _has_substitutions = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2245
    phi->clear(Phi::visited);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2246
    phi->set_subst(subst);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2247
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2248
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2249
    if (PrintPhiFunctions) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2250
      tty->print_cr("simplified phi function %c%d to %c%d (Block B%d)", phi->type()->tchar(), phi->id(), subst->type()->tchar(), subst->id(), phi->block()->block_id());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2251
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2252
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2253
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2254
    return subst;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2255
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2256
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2257
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2258
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2259
void PhiSimplifier::block_do(BlockBegin* b) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2260
  for_each_phi_fun(b, phi,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2261
    simplify(phi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2262
  );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2263
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2264
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2265
  for_each_phi_fun(b, phi,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2266
                   assert(phi->operand_count() != 1 || phi->subst() != phi, "missed trivial simplification");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2267
  );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2268
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2269
  ValueStack* state = b->state()->caller_state();
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2270
  for_each_state_value(state, value,
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2271
    Phi* phi = value->as_Phi();
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2272
    assert(phi == NULL || phi->block() != b, "must not have phi function to simplify in caller state");
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2273
  );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2274
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2275
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2276
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2277
// This method is called after all blocks are filled with HIR instructions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2278
// It eliminates all Phi functions of the form x = [y, y] and x = [y, x]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2279
void GraphBuilder::eliminate_redundant_phis(BlockBegin* start) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2280
  PhiSimplifier simplifier(start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2281
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2282
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2283
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2284
void GraphBuilder::connect_to_end(BlockBegin* beg) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2285
  // setup iteration
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2286
  kill_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2287
  _block = beg;
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2288
  _state = beg->state()->copy_for_parsing();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2289
  _last  = beg;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2290
  iterate_bytecodes_for_block(beg->bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2291
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2292
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2293
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2294
BlockEnd* GraphBuilder::iterate_bytecodes_for_block(int bci) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2295
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2296
  if (PrintIRDuringConstruction) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2297
    tty->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2298
    InstructionPrinter ip;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2299
    ip.print_instr(_block); tty->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2300
    ip.print_stack(_block->state()); tty->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2301
    ip.print_inline_level(_block);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2302
    ip.print_head();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2303
    tty->print_cr("locals size: %d stack size: %d", state()->locals_size(), state()->stack_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2304
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2305
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2306
  _skip_block = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2307
  assert(state() != NULL, "ValueStack missing!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2308
  ciBytecodeStream s(method());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2309
  s.reset_to_bci(bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2310
  int prev_bci = bci;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2311
  scope_data()->set_stream(&s);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2312
  // iterate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2313
  Bytecodes::Code code = Bytecodes::_illegal;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2314
  bool push_exception = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2315
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2316
  if (block()->is_set(BlockBegin::exception_entry_flag) && block()->next() == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2317
    // first thing in the exception entry block should be the exception object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2318
    push_exception = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2319
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2320
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2321
  while (!bailed_out() && last()->as_BlockEnd() == NULL &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2322
         (code = stream()->next()) != ciBytecodeStream::EOBC() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2323
         (block_at(s.cur_bci()) == NULL || block_at(s.cur_bci()) == block())) {
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2324
    assert(state()->kind() == ValueStack::Parsing, "invalid state kind");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2325
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2326
    // Check for active jsr during OSR compilation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2327
    if (compilation()->is_osr_compile()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2328
        && scope()->is_top_scope()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2329
        && parsing_jsr()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2330
        && s.cur_bci() == compilation()->osr_bci()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2331
      bailout("OSR not supported while a jsr is active");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2332
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2333
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2334
    if (push_exception) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2335
      apush(append(new ExceptionObject()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2336
      push_exception = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2337
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2338
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2339
    // handle bytecode
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2340
    switch (code) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2341
      case Bytecodes::_nop            : /* nothing to do */ break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2342
      case Bytecodes::_aconst_null    : apush(append(new Constant(objectNull            ))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2343
      case Bytecodes::_iconst_m1      : ipush(append(new Constant(new IntConstant   (-1)))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2344
      case Bytecodes::_iconst_0       : ipush(append(new Constant(intZero               ))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2345
      case Bytecodes::_iconst_1       : ipush(append(new Constant(intOne                ))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2346
      case Bytecodes::_iconst_2       : ipush(append(new Constant(new IntConstant   ( 2)))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2347
      case Bytecodes::_iconst_3       : ipush(append(new Constant(new IntConstant   ( 3)))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2348
      case Bytecodes::_iconst_4       : ipush(append(new Constant(new IntConstant   ( 4)))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2349
      case Bytecodes::_iconst_5       : ipush(append(new Constant(new IntConstant   ( 5)))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2350
      case Bytecodes::_lconst_0       : lpush(append(new Constant(new LongConstant  ( 0)))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2351
      case Bytecodes::_lconst_1       : lpush(append(new Constant(new LongConstant  ( 1)))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2352
      case Bytecodes::_fconst_0       : fpush(append(new Constant(new FloatConstant ( 0)))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2353
      case Bytecodes::_fconst_1       : fpush(append(new Constant(new FloatConstant ( 1)))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2354
      case Bytecodes::_fconst_2       : fpush(append(new Constant(new FloatConstant ( 2)))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2355
      case Bytecodes::_dconst_0       : dpush(append(new Constant(new DoubleConstant( 0)))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2356
      case Bytecodes::_dconst_1       : dpush(append(new Constant(new DoubleConstant( 1)))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2357
      case Bytecodes::_bipush         : ipush(append(new Constant(new IntConstant(((signed char*)s.cur_bcp())[1])))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2358
      case Bytecodes::_sipush         : ipush(append(new Constant(new IntConstant((short)Bytes::get_Java_u2(s.cur_bcp()+1))))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2359
      case Bytecodes::_ldc            : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2360
      case Bytecodes::_ldc_w          : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2361
      case Bytecodes::_ldc2_w         : load_constant(); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2362
      case Bytecodes::_iload          : load_local(intType     , s.get_index()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2363
      case Bytecodes::_lload          : load_local(longType    , s.get_index()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2364
      case Bytecodes::_fload          : load_local(floatType   , s.get_index()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2365
      case Bytecodes::_dload          : load_local(doubleType  , s.get_index()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2366
      case Bytecodes::_aload          : load_local(instanceType, s.get_index()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2367
      case Bytecodes::_iload_0        : load_local(intType   , 0); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2368
      case Bytecodes::_iload_1        : load_local(intType   , 1); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2369
      case Bytecodes::_iload_2        : load_local(intType   , 2); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2370
      case Bytecodes::_iload_3        : load_local(intType   , 3); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2371
      case Bytecodes::_lload_0        : load_local(longType  , 0); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2372
      case Bytecodes::_lload_1        : load_local(longType  , 1); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2373
      case Bytecodes::_lload_2        : load_local(longType  , 2); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2374
      case Bytecodes::_lload_3        : load_local(longType  , 3); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2375
      case Bytecodes::_fload_0        : load_local(floatType , 0); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2376
      case Bytecodes::_fload_1        : load_local(floatType , 1); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2377
      case Bytecodes::_fload_2        : load_local(floatType , 2); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2378
      case Bytecodes::_fload_3        : load_local(floatType , 3); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2379
      case Bytecodes::_dload_0        : load_local(doubleType, 0); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2380
      case Bytecodes::_dload_1        : load_local(doubleType, 1); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2381
      case Bytecodes::_dload_2        : load_local(doubleType, 2); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2382
      case Bytecodes::_dload_3        : load_local(doubleType, 3); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2383
      case Bytecodes::_aload_0        : load_local(objectType, 0); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2384
      case Bytecodes::_aload_1        : load_local(objectType, 1); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2385
      case Bytecodes::_aload_2        : load_local(objectType, 2); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2386
      case Bytecodes::_aload_3        : load_local(objectType, 3); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2387
      case Bytecodes::_iaload         : load_indexed(T_INT   ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2388
      case Bytecodes::_laload         : load_indexed(T_LONG  ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2389
      case Bytecodes::_faload         : load_indexed(T_FLOAT ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2390
      case Bytecodes::_daload         : load_indexed(T_DOUBLE); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2391
      case Bytecodes::_aaload         : load_indexed(T_OBJECT); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2392
      case Bytecodes::_baload         : load_indexed(T_BYTE  ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2393
      case Bytecodes::_caload         : load_indexed(T_CHAR  ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2394
      case Bytecodes::_saload         : load_indexed(T_SHORT ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2395
      case Bytecodes::_istore         : store_local(intType   , s.get_index()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2396
      case Bytecodes::_lstore         : store_local(longType  , s.get_index()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2397
      case Bytecodes::_fstore         : store_local(floatType , s.get_index()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2398
      case Bytecodes::_dstore         : store_local(doubleType, s.get_index()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2399
      case Bytecodes::_astore         : store_local(objectType, s.get_index()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2400
      case Bytecodes::_istore_0       : store_local(intType   , 0); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2401
      case Bytecodes::_istore_1       : store_local(intType   , 1); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2402
      case Bytecodes::_istore_2       : store_local(intType   , 2); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2403
      case Bytecodes::_istore_3       : store_local(intType   , 3); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2404
      case Bytecodes::_lstore_0       : store_local(longType  , 0); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2405
      case Bytecodes::_lstore_1       : store_local(longType  , 1); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2406
      case Bytecodes::_lstore_2       : store_local(longType  , 2); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2407
      case Bytecodes::_lstore_3       : store_local(longType  , 3); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2408
      case Bytecodes::_fstore_0       : store_local(floatType , 0); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2409
      case Bytecodes::_fstore_1       : store_local(floatType , 1); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2410
      case Bytecodes::_fstore_2       : store_local(floatType , 2); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2411
      case Bytecodes::_fstore_3       : store_local(floatType , 3); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2412
      case Bytecodes::_dstore_0       : store_local(doubleType, 0); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2413
      case Bytecodes::_dstore_1       : store_local(doubleType, 1); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2414
      case Bytecodes::_dstore_2       : store_local(doubleType, 2); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2415
      case Bytecodes::_dstore_3       : store_local(doubleType, 3); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2416
      case Bytecodes::_astore_0       : store_local(objectType, 0); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2417
      case Bytecodes::_astore_1       : store_local(objectType, 1); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2418
      case Bytecodes::_astore_2       : store_local(objectType, 2); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2419
      case Bytecodes::_astore_3       : store_local(objectType, 3); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2420
      case Bytecodes::_iastore        : store_indexed(T_INT   ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2421
      case Bytecodes::_lastore        : store_indexed(T_LONG  ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2422
      case Bytecodes::_fastore        : store_indexed(T_FLOAT ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2423
      case Bytecodes::_dastore        : store_indexed(T_DOUBLE); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2424
      case Bytecodes::_aastore        : store_indexed(T_OBJECT); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2425
      case Bytecodes::_bastore        : store_indexed(T_BYTE  ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2426
      case Bytecodes::_castore        : store_indexed(T_CHAR  ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2427
      case Bytecodes::_sastore        : store_indexed(T_SHORT ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2428
      case Bytecodes::_pop            : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2429
      case Bytecodes::_pop2           : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2430
      case Bytecodes::_dup            : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2431
      case Bytecodes::_dup_x1         : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2432
      case Bytecodes::_dup_x2         : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2433
      case Bytecodes::_dup2           : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2434
      case Bytecodes::_dup2_x1        : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2435
      case Bytecodes::_dup2_x2        : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2436
      case Bytecodes::_swap           : stack_op(code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2437
      case Bytecodes::_iadd           : arithmetic_op(intType   , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2438
      case Bytecodes::_ladd           : arithmetic_op(longType  , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2439
      case Bytecodes::_fadd           : arithmetic_op(floatType , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2440
      case Bytecodes::_dadd           : arithmetic_op(doubleType, code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2441
      case Bytecodes::_isub           : arithmetic_op(intType   , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2442
      case Bytecodes::_lsub           : arithmetic_op(longType  , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2443
      case Bytecodes::_fsub           : arithmetic_op(floatType , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2444
      case Bytecodes::_dsub           : arithmetic_op(doubleType, code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2445
      case Bytecodes::_imul           : arithmetic_op(intType   , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2446
      case Bytecodes::_lmul           : arithmetic_op(longType  , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2447
      case Bytecodes::_fmul           : arithmetic_op(floatType , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2448
      case Bytecodes::_dmul           : arithmetic_op(doubleType, code); break;
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2449
      case Bytecodes::_idiv           : arithmetic_op(intType   , code, copy_state_for_exception()); break;
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2450
      case Bytecodes::_ldiv           : arithmetic_op(longType  , code, copy_state_for_exception()); break;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2451
      case Bytecodes::_fdiv           : arithmetic_op(floatType , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2452
      case Bytecodes::_ddiv           : arithmetic_op(doubleType, code); break;
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2453
      case Bytecodes::_irem           : arithmetic_op(intType   , code, copy_state_for_exception()); break;
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2454
      case Bytecodes::_lrem           : arithmetic_op(longType  , code, copy_state_for_exception()); break;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2455
      case Bytecodes::_frem           : arithmetic_op(floatType , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2456
      case Bytecodes::_drem           : arithmetic_op(doubleType, code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2457
      case Bytecodes::_ineg           : negate_op(intType   ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2458
      case Bytecodes::_lneg           : negate_op(longType  ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2459
      case Bytecodes::_fneg           : negate_op(floatType ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2460
      case Bytecodes::_dneg           : negate_op(doubleType); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2461
      case Bytecodes::_ishl           : shift_op(intType , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2462
      case Bytecodes::_lshl           : shift_op(longType, code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2463
      case Bytecodes::_ishr           : shift_op(intType , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2464
      case Bytecodes::_lshr           : shift_op(longType, code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2465
      case Bytecodes::_iushr          : shift_op(intType , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2466
      case Bytecodes::_lushr          : shift_op(longType, code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2467
      case Bytecodes::_iand           : logic_op(intType , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2468
      case Bytecodes::_land           : logic_op(longType, code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2469
      case Bytecodes::_ior            : logic_op(intType , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2470
      case Bytecodes::_lor            : logic_op(longType, code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2471
      case Bytecodes::_ixor           : logic_op(intType , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2472
      case Bytecodes::_lxor           : logic_op(longType, code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2473
      case Bytecodes::_iinc           : increment(); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2474
      case Bytecodes::_i2l            : convert(code, T_INT   , T_LONG  ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2475
      case Bytecodes::_i2f            : convert(code, T_INT   , T_FLOAT ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2476
      case Bytecodes::_i2d            : convert(code, T_INT   , T_DOUBLE); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2477
      case Bytecodes::_l2i            : convert(code, T_LONG  , T_INT   ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2478
      case Bytecodes::_l2f            : convert(code, T_LONG  , T_FLOAT ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2479
      case Bytecodes::_l2d            : convert(code, T_LONG  , T_DOUBLE); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2480
      case Bytecodes::_f2i            : convert(code, T_FLOAT , T_INT   ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2481
      case Bytecodes::_f2l            : convert(code, T_FLOAT , T_LONG  ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2482
      case Bytecodes::_f2d            : convert(code, T_FLOAT , T_DOUBLE); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2483
      case Bytecodes::_d2i            : convert(code, T_DOUBLE, T_INT   ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2484
      case Bytecodes::_d2l            : convert(code, T_DOUBLE, T_LONG  ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2485
      case Bytecodes::_d2f            : convert(code, T_DOUBLE, T_FLOAT ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2486
      case Bytecodes::_i2b            : convert(code, T_INT   , T_BYTE  ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2487
      case Bytecodes::_i2c            : convert(code, T_INT   , T_CHAR  ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2488
      case Bytecodes::_i2s            : convert(code, T_INT   , T_SHORT ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2489
      case Bytecodes::_lcmp           : compare_op(longType  , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2490
      case Bytecodes::_fcmpl          : compare_op(floatType , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2491
      case Bytecodes::_fcmpg          : compare_op(floatType , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2492
      case Bytecodes::_dcmpl          : compare_op(doubleType, code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2493
      case Bytecodes::_dcmpg          : compare_op(doubleType, code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2494
      case Bytecodes::_ifeq           : if_zero(intType   , If::eql); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2495
      case Bytecodes::_ifne           : if_zero(intType   , If::neq); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2496
      case Bytecodes::_iflt           : if_zero(intType   , If::lss); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2497
      case Bytecodes::_ifge           : if_zero(intType   , If::geq); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2498
      case Bytecodes::_ifgt           : if_zero(intType   , If::gtr); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2499
      case Bytecodes::_ifle           : if_zero(intType   , If::leq); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2500
      case Bytecodes::_if_icmpeq      : if_same(intType   , If::eql); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2501
      case Bytecodes::_if_icmpne      : if_same(intType   , If::neq); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2502
      case Bytecodes::_if_icmplt      : if_same(intType   , If::lss); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2503
      case Bytecodes::_if_icmpge      : if_same(intType   , If::geq); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2504
      case Bytecodes::_if_icmpgt      : if_same(intType   , If::gtr); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2505
      case Bytecodes::_if_icmple      : if_same(intType   , If::leq); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2506
      case Bytecodes::_if_acmpeq      : if_same(objectType, If::eql); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2507
      case Bytecodes::_if_acmpne      : if_same(objectType, If::neq); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2508
      case Bytecodes::_goto           : _goto(s.cur_bci(), s.get_dest()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2509
      case Bytecodes::_jsr            : jsr(s.get_dest()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2510
      case Bytecodes::_ret            : ret(s.get_index()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2511
      case Bytecodes::_tableswitch    : table_switch(); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2512
      case Bytecodes::_lookupswitch   : lookup_switch(); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2513
      case Bytecodes::_ireturn        : method_return(ipop()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2514
      case Bytecodes::_lreturn        : method_return(lpop()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2515
      case Bytecodes::_freturn        : method_return(fpop()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2516
      case Bytecodes::_dreturn        : method_return(dpop()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2517
      case Bytecodes::_areturn        : method_return(apop()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2518
      case Bytecodes::_return         : method_return(NULL  ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2519
      case Bytecodes::_getstatic      : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2520
      case Bytecodes::_putstatic      : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2521
      case Bytecodes::_getfield       : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2522
      case Bytecodes::_putfield       : access_field(code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2523
      case Bytecodes::_invokevirtual  : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2524
      case Bytecodes::_invokespecial  : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2525
      case Bytecodes::_invokestatic   : // fall through
2570
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 1623
diff changeset
  2526
      case Bytecodes::_invokedynamic  : // fall through
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2527
      case Bytecodes::_invokeinterface: invoke(code); break;
5688
9052dc91ea67 6939207: refactor constant pool index processing
jrose
parents: 5535
diff changeset
  2528
      case Bytecodes::_new            : new_instance(s.get_index_u2()); break;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2529
      case Bytecodes::_newarray       : new_type_array(); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2530
      case Bytecodes::_anewarray      : new_object_array(); break;
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2531
      case Bytecodes::_arraylength    : { ValueStack* state_before = copy_state_for_exception(); ipush(append(new ArrayLength(apop(), state_before))); break; }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2532
      case Bytecodes::_athrow         : throw_op(s.cur_bci()); break;
5688
9052dc91ea67 6939207: refactor constant pool index processing
jrose
parents: 5535
diff changeset
  2533
      case Bytecodes::_checkcast      : check_cast(s.get_index_u2()); break;
9052dc91ea67 6939207: refactor constant pool index processing
jrose
parents: 5535
diff changeset
  2534
      case Bytecodes::_instanceof     : instance_of(s.get_index_u2()); break;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2535
      case Bytecodes::_monitorenter   : monitorenter(apop(), s.cur_bci()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2536
      case Bytecodes::_monitorexit    : monitorexit (apop(), s.cur_bci()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2537
      case Bytecodes::_wide           : ShouldNotReachHere(); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2538
      case Bytecodes::_multianewarray : new_multi_array(s.cur_bcp()[3]); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2539
      case Bytecodes::_ifnull         : if_null(objectType, If::eql); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2540
      case Bytecodes::_ifnonnull      : if_null(objectType, If::neq); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2541
      case Bytecodes::_goto_w         : _goto(s.cur_bci(), s.get_far_dest()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2542
      case Bytecodes::_jsr_w          : jsr(s.get_far_dest()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2543
      case Bytecodes::_breakpoint     : BAILOUT_("concurrent setting of breakpoint", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2544
      default                         : ShouldNotReachHere(); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2545
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2546
    // save current bci to setup Goto at the end
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2547
    prev_bci = s.cur_bci();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2548
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2549
  CHECK_BAILOUT_(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2550
  // stop processing of this block (see try_inline_full)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2551
  if (_skip_block) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2552
    _skip_block = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2553
    assert(_last && _last->as_BlockEnd(), "");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2554
    return _last->as_BlockEnd();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2555
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2556
  // if there are any, check if last instruction is a BlockEnd instruction
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2557
  BlockEnd* end = last()->as_BlockEnd();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2558
  if (end == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2559
    // all blocks must end with a BlockEnd instruction => add a Goto
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2560
    end = new Goto(block_at(s.cur_bci()), false);
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2561
    append(end);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2562
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2563
  assert(end == last()->as_BlockEnd(), "inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2564
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2565
  assert(end->state() != NULL, "state must already be present");
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2566
  assert(end->as_Return() == NULL || end->as_Throw() == NULL || end->state()->stack_size() == 0, "stack not needed for return and throw");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2567
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2568
  // connect to begin & set state
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2569
  // NOTE that inlining may have changed the block we are parsing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2570
  block()->set_end(end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2571
  // propagate state
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2572
  for (int i = end->number_of_sux() - 1; i >= 0; i--) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2573
    BlockBegin* sux = end->sux_at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2574
    assert(sux->is_predecessor(block()), "predecessor missing");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2575
    // be careful, bailout if bytecodes are strange
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2576
    if (!sux->try_merge(end->state())) BAILOUT_("block join failed", NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2577
    scope_data()->add_to_work_list(end->sux_at(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2578
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2579
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2580
  scope_data()->set_stream(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2581
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2582
  // done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2583
  return end;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2584
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2585
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2586
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2587
void GraphBuilder::iterate_all_blocks(bool start_in_current_block_for_inlining) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2588
  do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2589
    if (start_in_current_block_for_inlining && !bailed_out()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2590
      iterate_bytecodes_for_block(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2591
      start_in_current_block_for_inlining = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2592
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2593
      BlockBegin* b;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2594
      while ((b = scope_data()->remove_from_work_list()) != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2595
        if (!b->is_set(BlockBegin::was_visited_flag)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2596
          if (b->is_set(BlockBegin::osr_entry_flag)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2597
            // we're about to parse the osr entry block, so make sure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2598
            // we setup the OSR edge leading into this block so that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2599
            // Phis get setup correctly.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2600
            setup_osr_entry_block();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2601
            // this is no longer the osr entry block, so clear it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2602
            b->clear(BlockBegin::osr_entry_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2603
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2604
          b->set(BlockBegin::was_visited_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2605
          connect_to_end(b);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2606
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2607
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2608
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2609
  } while (!bailed_out() && !scope_data()->is_work_list_empty());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2610
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2611
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2612
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2613
bool GraphBuilder::_can_trap      [Bytecodes::number_of_java_codes];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2614
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2615
void GraphBuilder::initialize() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2616
  // the following bytecodes are assumed to potentially
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2617
  // throw exceptions in compiled code - note that e.g.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2618
  // monitorexit & the return bytecodes do not throw
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2619
  // exceptions since monitor pairing proved that they
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2620
  // succeed (if monitor pairing succeeded)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2621
  Bytecodes::Code can_trap_list[] =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2622
    { Bytecodes::_ldc
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2623
    , Bytecodes::_ldc_w
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2624
    , Bytecodes::_ldc2_w
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2625
    , Bytecodes::_iaload
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2626
    , Bytecodes::_laload
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2627
    , Bytecodes::_faload
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2628
    , Bytecodes::_daload
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2629
    , Bytecodes::_aaload
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2630
    , Bytecodes::_baload
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2631
    , Bytecodes::_caload
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2632
    , Bytecodes::_saload
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2633
    , Bytecodes::_iastore
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2634
    , Bytecodes::_lastore
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2635
    , Bytecodes::_fastore
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2636
    , Bytecodes::_dastore
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2637
    , Bytecodes::_aastore
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2638
    , Bytecodes::_bastore
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2639
    , Bytecodes::_castore
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2640
    , Bytecodes::_sastore
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2641
    , Bytecodes::_idiv
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2642
    , Bytecodes::_ldiv
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2643
    , Bytecodes::_irem
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2644
    , Bytecodes::_lrem
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2645
    , Bytecodes::_getstatic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2646
    , Bytecodes::_putstatic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2647
    , Bytecodes::_getfield
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2648
    , Bytecodes::_putfield
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2649
    , Bytecodes::_invokevirtual
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2650
    , Bytecodes::_invokespecial
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2651
    , Bytecodes::_invokestatic
2570
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 1623
diff changeset
  2652
    , Bytecodes::_invokedynamic
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2653
    , Bytecodes::_invokeinterface
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2654
    , Bytecodes::_new
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2655
    , Bytecodes::_newarray
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2656
    , Bytecodes::_anewarray
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2657
    , Bytecodes::_arraylength
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2658
    , Bytecodes::_athrow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2659
    , Bytecodes::_checkcast
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2660
    , Bytecodes::_instanceof
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2661
    , Bytecodes::_monitorenter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2662
    , Bytecodes::_multianewarray
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2663
    };
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2664
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2665
  // inititialize trap tables
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2666
  for (int i = 0; i < Bytecodes::number_of_java_codes; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2667
    _can_trap[i] = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2668
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2669
  // set standard trap info
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2670
  for (uint j = 0; j < ARRAY_SIZE(can_trap_list); j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2671
    _can_trap[can_trap_list[j]] = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2672
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2673
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2674
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2675
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2676
BlockBegin* GraphBuilder::header_block(BlockBegin* entry, BlockBegin::Flag f, ValueStack* state) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2677
  assert(entry->is_set(f), "entry/flag mismatch");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2678
  // create header block
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2679
  BlockBegin* h = new BlockBegin(entry->bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2680
  h->set_depth_first_number(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2681
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2682
  Value l = h;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2683
  BlockEnd* g = new Goto(entry, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2684
  l->set_next(g, entry->bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2685
  h->set_end(g);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2686
  h->set(f);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2687
  // setup header block end state
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2688
  ValueStack* s = state->copy(ValueStack::StateAfter, entry->bci()); // can use copy since stack is empty (=> no phis)
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2689
  assert(s->stack_is_empty(), "must have empty stack at entry point");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2690
  g->set_state(s);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2691
  return h;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2692
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2693
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2694
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2695
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2696
BlockBegin* GraphBuilder::setup_start_block(int osr_bci, BlockBegin* std_entry, BlockBegin* osr_entry, ValueStack* state) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2697
  BlockBegin* start = new BlockBegin(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2698
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2699
  // This code eliminates the empty start block at the beginning of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2700
  // each method.  Previously, each method started with the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2701
  // start-block created below, and this block was followed by the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2702
  // header block that was always empty.  This header block is only
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2703
  // necesary if std_entry is also a backward branch target because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2704
  // then phi functions may be necessary in the header block.  It's
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2705
  // also necessary when profiling so that there's a single block that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2706
  // can increment the interpreter_invocation_count.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2707
  BlockBegin* new_header_block;
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  2708
  if (std_entry->number_of_preds() > 0 || count_invocations() || count_backedges()) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  2709
    new_header_block = header_block(std_entry, BlockBegin::std_entry_flag, state);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  2710
  } else {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2711
    new_header_block = std_entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2712
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2713
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2714
  // setup start block (root for the IR graph)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2715
  Base* base =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2716
    new Base(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2717
      new_header_block,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2718
      osr_entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2719
    );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2720
  start->set_next(base, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2721
  start->set_end(base);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2722
  // create & setup state for start block
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2723
  start->set_state(state->copy(ValueStack::StateAfter, std_entry->bci()));
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2724
  base->set_state(state->copy(ValueStack::StateAfter, std_entry->bci()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2725
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2726
  if (base->std_entry()->state() == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2727
    // setup states for header blocks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2728
    base->std_entry()->merge(state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2729
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2730
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2731
  assert(base->std_entry()->state() != NULL, "");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2732
  return start;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2733
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2734
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2735
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2736
void GraphBuilder::setup_osr_entry_block() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2737
  assert(compilation()->is_osr_compile(), "only for osrs");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2738
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2739
  int osr_bci = compilation()->osr_bci();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2740
  ciBytecodeStream s(method());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2741
  s.reset_to_bci(osr_bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2742
  s.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2743
  scope_data()->set_stream(&s);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2744
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2745
  // create a new block to be the osr setup code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2746
  _osr_entry = new BlockBegin(osr_bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2747
  _osr_entry->set(BlockBegin::osr_entry_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2748
  _osr_entry->set_depth_first_number(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2749
  BlockBegin* target = bci2block()->at(osr_bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2750
  assert(target != NULL && target->is_set(BlockBegin::osr_entry_flag), "must be there");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2751
  // the osr entry has no values for locals
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2752
  ValueStack* state = target->state()->copy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2753
  _osr_entry->set_state(state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2754
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2755
  kill_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2756
  _block = _osr_entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2757
  _state = _osr_entry->state()->copy();
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2758
  assert(_state->bci() == osr_bci, "mismatch");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2759
  _last  = _osr_entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2760
  Value e = append(new OsrEntry());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2761
  e->set_needs_null_check(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2762
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2763
  // OSR buffer is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2764
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2765
  // locals[nlocals-1..0]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2766
  // monitors[number_of_locks-1..0]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2767
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2768
  // locals is a direct copy of the interpreter frame so in the osr buffer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2769
  // so first slot in the local array is the last local from the interpreter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2770
  // and last slot is local[0] (receiver) from the interpreter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2771
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2772
  // Similarly with locks. The first lock slot in the osr buffer is the nth lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2773
  // from the interpreter frame, the nth lock slot in the osr buffer is 0th lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2774
  // in the interpreter frame (the method lock if a sync method)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2775
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2776
  // Initialize monitors in the compiled activation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2777
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2778
  int index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2779
  Value local;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2780
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2781
  // find all the locals that the interpreter thinks contain live oops
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2782
  const BitMap live_oops = method()->live_local_oops_at_bci(osr_bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2783
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2784
  // compute the offset into the locals so that we can treat the buffer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2785
  // as if the locals were still in the interpreter frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2786
  int locals_offset = BytesPerWord * (method()->max_locals() - 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2787
  for_each_local_value(state, index, local) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2788
    int offset = locals_offset - (index + local->type()->size() - 1) * BytesPerWord;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2789
    Value get;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2790
    if (local->type()->is_object_kind() && !live_oops.at(index)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2791
      // The interpreter thinks this local is dead but the compiler
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2792
      // doesn't so pretend that the interpreter passed in null.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2793
      get = append(new Constant(objectNull));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2794
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2795
      get = append(new UnsafeGetRaw(as_BasicType(local->type()), e,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2796
                                    append(new Constant(new IntConstant(offset))),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2797
                                    0,
7427
d7b79a367474 6985015: C1 needs to support compressed oops
iveresov
parents: 7397
diff changeset
  2798
                                    true /*unaligned*/, true /*wide*/));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2799
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2800
    _state->store_local(index, get);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2801
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2802
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2803
  // the storage for the OSR buffer is freed manually in the LIRGenerator.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2804
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2805
  assert(state->caller_state() == NULL, "should be top scope");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2806
  state->clear_locals();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2807
  Goto* g = new Goto(target, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2808
  append(g);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2809
  _osr_entry->set_end(g);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2810
  target->merge(_osr_entry->end()->state());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2811
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2812
  scope_data()->set_stream(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2813
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2814
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2815
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2816
ValueStack* GraphBuilder::state_at_entry() {
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2817
  ValueStack* state = new ValueStack(scope(), NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2818
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2819
  // Set up locals for receiver
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2820
  int idx = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2821
  if (!method()->is_static()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2822
    // we should always see the receiver
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2823
    state->store_local(idx, new Local(objectType, idx));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2824
    idx = 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2825
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2826
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2827
  // Set up locals for incoming arguments
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2828
  ciSignature* sig = method()->signature();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2829
  for (int i = 0; i < sig->count(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2830
    ciType* type = sig->type_at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2831
    BasicType basic_type = type->basic_type();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2832
    // don't allow T_ARRAY to propagate into locals types
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2833
    if (basic_type == T_ARRAY) basic_type = T_OBJECT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2834
    ValueType* vt = as_ValueType(basic_type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2835
    state->store_local(idx, new Local(vt, idx));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2836
    idx += type->size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2837
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2838
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2839
  // lock synchronized method
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2840
  if (method()->is_synchronized()) {
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2841
    state->lock(NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2842
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2843
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2844
  return state;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2845
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2846
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2847
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2848
GraphBuilder::GraphBuilder(Compilation* compilation, IRScope* scope)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2849
  : _scope_data(NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2850
  , _instruction_count(0)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2851
  , _osr_entry(NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2852
  , _memory(new MemoryBuffer())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2853
  , _compilation(compilation)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2854
  , _inline_bailout_msg(NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2855
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2856
  int osr_bci = compilation->osr_bci();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2857
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2858
  // determine entry points and bci2block mapping
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2859
  BlockListBuilder blm(compilation, scope, osr_bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2860
  CHECK_BAILOUT();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2861
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2862
  BlockList* bci2block = blm.bci2block();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2863
  BlockBegin* start_block = bci2block->at(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2864
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2865
  push_root_scope(scope, bci2block, start_block);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2866
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2867
  // setup state for std entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2868
  _initial_state = state_at_entry();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2869
  start_block->merge(_initial_state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2870
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2871
  // complete graph
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2872
  _vmap        = new ValueMap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2873
  switch (scope->method()->intrinsic_id()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2874
  case vmIntrinsics::_dabs          : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2875
  case vmIntrinsics::_dsqrt         : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2876
  case vmIntrinsics::_dsin          : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2877
  case vmIntrinsics::_dcos          : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2878
  case vmIntrinsics::_dtan          : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2879
  case vmIntrinsics::_dlog          : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2880
  case vmIntrinsics::_dlog10        : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2881
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2882
      // Compiles where the root method is an intrinsic need a special
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2883
      // compilation environment because the bytecodes for the method
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2884
      // shouldn't be parsed during the compilation, only the special
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2885
      // Intrinsic node should be emitted.  If this isn't done the the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2886
      // code for the inlined version will be different than the root
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2887
      // compiled version which could lead to monotonicity problems on
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2888
      // intel.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2889
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2890
      // Set up a stream so that appending instructions works properly.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2891
      ciBytecodeStream s(scope->method());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2892
      s.reset_to_bci(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2893
      scope_data()->set_stream(&s);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2894
      s.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2895
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2896
      // setup the initial block state
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2897
      _block = start_block;
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2898
      _state = start_block->state()->copy_for_parsing();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2899
      _last  = start_block;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2900
      load_local(doubleType, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2901
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2902
      // Emit the intrinsic node.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2903
      bool result = try_inline_intrinsics(scope->method());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2904
      if (!result) BAILOUT("failed to inline intrinsic");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2905
      method_return(dpop());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2906
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2907
      // connect the begin and end blocks and we're all done.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2908
      BlockEnd* end = last()->as_BlockEnd();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2909
      block()->set_end(end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2910
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2911
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2912
  default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2913
    scope_data()->add_to_work_list(start_block);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2914
    iterate_all_blocks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2915
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2916
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2917
  CHECK_BAILOUT();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2918
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2919
  _start = setup_start_block(osr_bci, start_block, _osr_entry, _initial_state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2920
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2921
  eliminate_redundant_phis(_start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2922
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2923
  NOT_PRODUCT(if (PrintValueNumbering && Verbose) print_stats());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2924
  // for osr compile, bailout if some requirements are not fulfilled
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2925
  if (osr_bci != -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2926
    BlockBegin* osr_block = blm.bci2block()->at(osr_bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2927
    assert(osr_block->is_set(BlockBegin::was_visited_flag),"osr entry must have been visited for osr compile");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2928
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2929
    // check if osr entry point has empty stack - we cannot handle non-empty stacks at osr entry points
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2930
    if (!osr_block->state()->stack_is_empty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2931
      BAILOUT("stack not empty at OSR entry point");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2932
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2933
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2934
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2935
  if (PrintCompilation && Verbose) tty->print_cr("Created %d Instructions", _instruction_count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2936
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2937
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2938
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2939
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2940
ValueStack* GraphBuilder::copy_state_before() {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2941
  return copy_state_before_with_bci(bci());
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2942
}
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2943
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2944
ValueStack* GraphBuilder::copy_state_exhandling() {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2945
  return copy_state_exhandling_with_bci(bci());
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2946
}
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2947
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2948
ValueStack* GraphBuilder::copy_state_for_exception() {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2949
  return copy_state_for_exception_with_bci(bci());
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2950
}
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2951
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2952
ValueStack* GraphBuilder::copy_state_before_with_bci(int bci) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2953
  return state()->copy(ValueStack::StateBefore, bci);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2954
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2955
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2956
ValueStack* GraphBuilder::copy_state_exhandling_with_bci(int bci) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2957
  if (!has_handler()) return NULL;
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2958
  return state()->copy(ValueStack::StateBefore, bci);
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2959
}
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2960
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2961
ValueStack* GraphBuilder::copy_state_for_exception_with_bci(int bci) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2962
  ValueStack* s = copy_state_exhandling_with_bci(bci);
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2963
  if (s == NULL) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2964
    if (_compilation->env()->jvmti_can_access_local_variables()) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2965
      s = state()->copy(ValueStack::ExceptionState, bci);
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2966
    } else {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2967
      s = state()->copy(ValueStack::EmptyExceptionState, bci);
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2968
    }
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2969
  }
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2970
  return s;
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2971
}
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2972
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2973
int GraphBuilder::recursive_inline_level(ciMethod* cur_callee) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2974
  int recur_level = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2975
  for (IRScope* s = scope(); s != NULL; s = s->caller()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2976
    if (s->method() == cur_callee) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2977
      ++recur_level;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2978
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2979
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2980
  return recur_level;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2981
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2982
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2983
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2984
bool GraphBuilder::try_inline(ciMethod* callee, bool holder_known) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2985
  // Clear out any existing inline bailout condition
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2986
  clear_inline_bailout();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2987
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2988
  if (callee->should_exclude()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2989
    // callee is excluded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2990
    INLINE_BAILOUT("excluded by CompilerOracle")
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2991
  } else if (!callee->can_be_compiled()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2992
    // callee is not compilable (prob. has breakpoints)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2993
    INLINE_BAILOUT("not compilable")
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2994
  } else if (callee->intrinsic_id() != vmIntrinsics::_none && try_inline_intrinsics(callee)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2995
    // intrinsics can be native or not
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2996
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2997
  } else if (callee->is_native()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2998
    // non-intrinsic natives cannot be inlined
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2999
    INLINE_BAILOUT("non-intrinsic native")
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3000
  } else if (callee->is_abstract()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3001
    INLINE_BAILOUT("abstract")
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3002
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3003
    return try_inline_full(callee, holder_known);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3004
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3005
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3006
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3007
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3008
bool GraphBuilder::try_inline_intrinsics(ciMethod* callee) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3009
  if (!InlineNatives           ) INLINE_BAILOUT("intrinsic method inlining disabled");
5535
a747f18b3d7e 6953539: after 6892658 c1 reports that it doesn't inline StringBuffer.append
never
parents: 5353
diff changeset
  3010
  if (callee->is_synchronized()) {
a747f18b3d7e 6953539: after 6892658 c1 reports that it doesn't inline StringBuffer.append
never
parents: 5353
diff changeset
  3011
    // We don't currently support any synchronized intrinsics
a747f18b3d7e 6953539: after 6892658 c1 reports that it doesn't inline StringBuffer.append
never
parents: 5353
diff changeset
  3012
    return false;
a747f18b3d7e 6953539: after 6892658 c1 reports that it doesn't inline StringBuffer.append
never
parents: 5353
diff changeset
  3013
  }
a747f18b3d7e 6953539: after 6892658 c1 reports that it doesn't inline StringBuffer.append
never
parents: 5353
diff changeset
  3014
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3015
  // callee seems like a good candidate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3016
  // determine id
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3017
  bool preserves_state = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3018
  bool cantrap = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3019
  vmIntrinsics::ID id = callee->intrinsic_id();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3020
  switch (id) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3021
    case vmIntrinsics::_arraycopy     :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3022
      if (!InlineArrayCopy) return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3023
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3024
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3025
    case vmIntrinsics::_currentTimeMillis:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3026
    case vmIntrinsics::_nanoTime:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3027
      preserves_state = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3028
      cantrap = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3029
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3030
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3031
    case vmIntrinsics::_floatToRawIntBits   :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3032
    case vmIntrinsics::_intBitsToFloat      :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3033
    case vmIntrinsics::_doubleToRawLongBits :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3034
    case vmIntrinsics::_longBitsToDouble    :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3035
      if (!InlineMathNatives) return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3036
      preserves_state = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3037
      cantrap = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3038
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3039
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3040
    case vmIntrinsics::_getClass      :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3041
      if (!InlineClassNatives) return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3042
      preserves_state = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3043
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3044
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3045
    case vmIntrinsics::_currentThread :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3046
      if (!InlineThreadNatives) return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3047
      preserves_state = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3048
      cantrap = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3049
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3050
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3051
    case vmIntrinsics::_dabs          : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3052
    case vmIntrinsics::_dsqrt         : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3053
    case vmIntrinsics::_dsin          : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3054
    case vmIntrinsics::_dcos          : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3055
    case vmIntrinsics::_dtan          : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3056
    case vmIntrinsics::_dlog          : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3057
    case vmIntrinsics::_dlog10        : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3058
      if (!InlineMathNatives) return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3059
      cantrap = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3060
      preserves_state = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3061
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3062
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3063
    // sun/misc/AtomicLong.attemptUpdate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3064
    case vmIntrinsics::_attemptUpdate :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3065
      if (!VM_Version::supports_cx8()) return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3066
      if (!InlineAtomicLong) return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3067
      preserves_state = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3068
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3069
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3070
    // Use special nodes for Unsafe instructions so we can more easily
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3071
    // perform an address-mode optimization on the raw variants
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3072
    case vmIntrinsics::_getObject : return append_unsafe_get_obj(callee, T_OBJECT,  false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3073
    case vmIntrinsics::_getBoolean: return append_unsafe_get_obj(callee, T_BOOLEAN, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3074
    case vmIntrinsics::_getByte   : return append_unsafe_get_obj(callee, T_BYTE,    false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3075
    case vmIntrinsics::_getShort  : return append_unsafe_get_obj(callee, T_SHORT,   false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3076
    case vmIntrinsics::_getChar   : return append_unsafe_get_obj(callee, T_CHAR,    false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3077
    case vmIntrinsics::_getInt    : return append_unsafe_get_obj(callee, T_INT,     false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3078
    case vmIntrinsics::_getLong   : return append_unsafe_get_obj(callee, T_LONG,    false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3079
    case vmIntrinsics::_getFloat  : return append_unsafe_get_obj(callee, T_FLOAT,   false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3080
    case vmIntrinsics::_getDouble : return append_unsafe_get_obj(callee, T_DOUBLE,  false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3081
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3082
    case vmIntrinsics::_putObject : return append_unsafe_put_obj(callee, T_OBJECT,  false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3083
    case vmIntrinsics::_putBoolean: return append_unsafe_put_obj(callee, T_BOOLEAN, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3084
    case vmIntrinsics::_putByte   : return append_unsafe_put_obj(callee, T_BYTE,    false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3085
    case vmIntrinsics::_putShort  : return append_unsafe_put_obj(callee, T_SHORT,   false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3086
    case vmIntrinsics::_putChar   : return append_unsafe_put_obj(callee, T_CHAR,    false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3087
    case vmIntrinsics::_putInt    : return append_unsafe_put_obj(callee, T_INT,     false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3088
    case vmIntrinsics::_putLong   : return append_unsafe_put_obj(callee, T_LONG,    false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3089
    case vmIntrinsics::_putFloat  : return append_unsafe_put_obj(callee, T_FLOAT,   false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3090
    case vmIntrinsics::_putDouble : return append_unsafe_put_obj(callee, T_DOUBLE,  false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3091
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3092
    case vmIntrinsics::_getObjectVolatile : return append_unsafe_get_obj(callee, T_OBJECT,  true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3093
    case vmIntrinsics::_getBooleanVolatile: return append_unsafe_get_obj(callee, T_BOOLEAN, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3094
    case vmIntrinsics::_getByteVolatile   : return append_unsafe_get_obj(callee, T_BYTE,    true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3095
    case vmIntrinsics::_getShortVolatile  : return append_unsafe_get_obj(callee, T_SHORT,   true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3096
    case vmIntrinsics::_getCharVolatile   : return append_unsafe_get_obj(callee, T_CHAR,    true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3097
    case vmIntrinsics::_getIntVolatile    : return append_unsafe_get_obj(callee, T_INT,     true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3098
    case vmIntrinsics::_getLongVolatile   : return append_unsafe_get_obj(callee, T_LONG,    true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3099
    case vmIntrinsics::_getFloatVolatile  : return append_unsafe_get_obj(callee, T_FLOAT,   true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3100
    case vmIntrinsics::_getDoubleVolatile : return append_unsafe_get_obj(callee, T_DOUBLE,  true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3101
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3102
    case vmIntrinsics::_putObjectVolatile : return append_unsafe_put_obj(callee, T_OBJECT,  true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3103
    case vmIntrinsics::_putBooleanVolatile: return append_unsafe_put_obj(callee, T_BOOLEAN, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3104
    case vmIntrinsics::_putByteVolatile   : return append_unsafe_put_obj(callee, T_BYTE,    true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3105
    case vmIntrinsics::_putShortVolatile  : return append_unsafe_put_obj(callee, T_SHORT,   true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3106
    case vmIntrinsics::_putCharVolatile   : return append_unsafe_put_obj(callee, T_CHAR,    true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3107
    case vmIntrinsics::_putIntVolatile    : return append_unsafe_put_obj(callee, T_INT,     true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3108
    case vmIntrinsics::_putLongVolatile   : return append_unsafe_put_obj(callee, T_LONG,    true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3109
    case vmIntrinsics::_putFloatVolatile  : return append_unsafe_put_obj(callee, T_FLOAT,   true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3110
    case vmIntrinsics::_putDoubleVolatile : return append_unsafe_put_obj(callee, T_DOUBLE,  true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3111
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3112
    case vmIntrinsics::_getByte_raw   : return append_unsafe_get_raw(callee, T_BYTE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3113
    case vmIntrinsics::_getShort_raw  : return append_unsafe_get_raw(callee, T_SHORT);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3114
    case vmIntrinsics::_getChar_raw   : return append_unsafe_get_raw(callee, T_CHAR);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3115
    case vmIntrinsics::_getInt_raw    : return append_unsafe_get_raw(callee, T_INT);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3116
    case vmIntrinsics::_getLong_raw   : return append_unsafe_get_raw(callee, T_LONG);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3117
    case vmIntrinsics::_getFloat_raw  : return append_unsafe_get_raw(callee, T_FLOAT);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3118
    case vmIntrinsics::_getDouble_raw : return append_unsafe_get_raw(callee, T_DOUBLE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3119
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3120
    case vmIntrinsics::_putByte_raw   : return append_unsafe_put_raw(callee, T_BYTE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3121
    case vmIntrinsics::_putShort_raw  : return append_unsafe_put_raw(callee, T_SHORT);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3122
    case vmIntrinsics::_putChar_raw   : return append_unsafe_put_raw(callee, T_CHAR);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3123
    case vmIntrinsics::_putInt_raw    : return append_unsafe_put_raw(callee, T_INT);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3124
    case vmIntrinsics::_putLong_raw   : return append_unsafe_put_raw(callee, T_LONG);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3125
    case vmIntrinsics::_putFloat_raw  : return append_unsafe_put_raw(callee, T_FLOAT);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3126
    case vmIntrinsics::_putDouble_raw : return append_unsafe_put_raw(callee, T_DOUBLE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3127
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3128
    case vmIntrinsics::_prefetchRead        : return append_unsafe_prefetch(callee, false, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3129
    case vmIntrinsics::_prefetchWrite       : return append_unsafe_prefetch(callee, false, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3130
    case vmIntrinsics::_prefetchReadStatic  : return append_unsafe_prefetch(callee, true,  false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3131
    case vmIntrinsics::_prefetchWriteStatic : return append_unsafe_prefetch(callee, true,  true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3132
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3133
    case vmIntrinsics::_checkIndex    :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3134
      if (!InlineNIOCheckIndex) return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3135
      preserves_state = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3136
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3137
    case vmIntrinsics::_putOrderedObject : return append_unsafe_put_obj(callee, T_OBJECT,  true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3138
    case vmIntrinsics::_putOrderedInt    : return append_unsafe_put_obj(callee, T_INT,     true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3139
    case vmIntrinsics::_putOrderedLong   : return append_unsafe_put_obj(callee, T_LONG,    true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3140
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3141
    case vmIntrinsics::_compareAndSwapLong:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3142
      if (!VM_Version::supports_cx8()) return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3143
      // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3144
    case vmIntrinsics::_compareAndSwapInt:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3145
    case vmIntrinsics::_compareAndSwapObject:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3146
      append_unsafe_CAS(callee);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3147
      return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3148
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3149
    default                       : return false; // do not inline
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3150
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3151
  // create intrinsic node
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3152
  const bool has_receiver = !callee->is_static();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3153
  ValueType* result_type = as_ValueType(callee->return_type());
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3154
  ValueStack* state_before = copy_state_for_exception();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3155
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3156
  Values* args = state()->pop_arguments(callee->arg_size());
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3157
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3158
  if (is_profiling()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3159
    // Don't profile in the special case where the root method
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3160
    // is the intrinsic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3161
    if (callee != method()) {
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3162
      // Note that we'd collect profile data in this method if we wanted it.
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3163
      compilation()->set_would_profile(true);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3164
      if (profile_calls()) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3165
        Value recv = NULL;
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3166
        if (has_receiver) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3167
          recv = args->at(0);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3168
          null_check(recv);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3169
        }
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3170
        profile_call(recv, NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3171
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3172
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3173
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3174
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3175
  Intrinsic* result = new Intrinsic(result_type, id, args, has_receiver, state_before,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3176
                                    preserves_state, cantrap);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3177
  // append instruction & push result
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3178
  Value value = append_split(result);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3179
  if (result_type != voidType) push(result_type, value);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3180
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3181
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3182
  // printing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3183
  if (PrintInlining) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3184
    print_inline_result(callee, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3185
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3186
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3187
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3188
  // done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3189
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3190
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3191
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3192
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3193
bool GraphBuilder::try_inline_jsr(int jsr_dest_bci) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3194
  // Introduce a new callee continuation point - all Ret instructions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3195
  // will be replaced with Gotos to this point.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3196
  BlockBegin* cont = block_at(next_bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3197
  assert(cont != NULL, "continuation must exist (BlockListBuilder starts a new block after a jsr");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3198
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3199
  // Note: can not assign state to continuation yet, as we have to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3200
  // pick up the state from the Ret instructions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3201
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3202
  // Push callee scope
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3203
  push_scope_for_jsr(cont, jsr_dest_bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3204
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3205
  // Temporarily set up bytecode stream so we can append instructions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3206
  // (only using the bci of this stream)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3207
  scope_data()->set_stream(scope_data()->parent()->stream());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3208
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3209
  BlockBegin* jsr_start_block = block_at(jsr_dest_bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3210
  assert(jsr_start_block != NULL, "jsr start block must exist");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3211
  assert(!jsr_start_block->is_set(BlockBegin::was_visited_flag), "should not have visited jsr yet");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3212
  Goto* goto_sub = new Goto(jsr_start_block, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3213
  // Must copy state to avoid wrong sharing when parsing bytecodes
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3214
  assert(jsr_start_block->state() == NULL, "should have fresh jsr starting block");
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3215
  jsr_start_block->set_state(copy_state_before_with_bci(jsr_dest_bci));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3216
  append(goto_sub);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3217
  _block->set_end(goto_sub);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3218
  _last = _block = jsr_start_block;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3219
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3220
  // Clear out bytecode stream
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3221
  scope_data()->set_stream(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3222
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3223
  scope_data()->add_to_work_list(jsr_start_block);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3224
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3225
  // Ready to resume parsing in subroutine
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3226
  iterate_all_blocks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3227
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3228
  // If we bailed out during parsing, return immediately (this is bad news)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3229
  CHECK_BAILOUT_(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3230
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3231
  // Detect whether the continuation can actually be reached. If not,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3232
  // it has not had state set by the join() operations in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3233
  // iterate_bytecodes_for_block()/ret() and we should not touch the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3234
  // iteration state. The calling activation of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3235
  // iterate_bytecodes_for_block will then complete normally.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3236
  if (cont->state() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3237
    if (!cont->is_set(BlockBegin::was_visited_flag)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3238
      // add continuation to work list instead of parsing it immediately
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3239
      scope_data()->parent()->add_to_work_list(cont);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3240
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3241
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3242
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3243
  assert(jsr_continuation() == cont, "continuation must not have changed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3244
  assert(!jsr_continuation()->is_set(BlockBegin::was_visited_flag) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3245
         jsr_continuation()->is_set(BlockBegin::parser_loop_header_flag),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3246
         "continuation can only be visited in case of backward branches");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3247
  assert(_last && _last->as_BlockEnd(), "block must have end");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3248
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3249
  // continuation is in work list, so end iteration of current block
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3250
  _skip_block = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3251
  pop_scope_for_jsr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3252
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3253
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3254
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3255
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3256
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3257
// Inline the entry of a synchronized method as a monitor enter and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3258
// register the exception handler which releases the monitor if an
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3259
// exception is thrown within the callee. Note that the monitor enter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3260
// cannot throw an exception itself, because the receiver is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3261
// guaranteed to be non-null by the explicit null check at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3262
// beginning of inlining.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3263
void GraphBuilder::inline_sync_entry(Value lock, BlockBegin* sync_handler) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3264
  assert(lock != NULL && sync_handler != NULL, "lock or handler missing");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3265
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3266
  monitorenter(lock, SynchronizationEntryBCI);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3267
  assert(_last->as_MonitorEnter() != NULL, "monitor enter expected");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3268
  _last->set_needs_null_check(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3269
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3270
  sync_handler->set(BlockBegin::exception_entry_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3271
  sync_handler->set(BlockBegin::is_on_work_list_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3272
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3273
  ciExceptionHandler* desc = new ciExceptionHandler(method()->holder(), 0, method()->code_size(), -1, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3274
  XHandler* h = new XHandler(desc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3275
  h->set_entry_block(sync_handler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3276
  scope_data()->xhandlers()->append(h);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3277
  scope_data()->set_has_handler();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3278
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3279
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3280
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3281
// If an exception is thrown and not handled within an inlined
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3282
// synchronized method, the monitor must be released before the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3283
// exception is rethrown in the outer scope. Generate the appropriate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3284
// instructions here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3285
void GraphBuilder::fill_sync_handler(Value lock, BlockBegin* sync_handler, bool default_handler) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3286
  BlockBegin* orig_block = _block;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3287
  ValueStack* orig_state = _state;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3288
  Instruction* orig_last = _last;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3289
  _last = _block = sync_handler;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3290
  _state = sync_handler->state()->copy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3291
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3292
  assert(sync_handler != NULL, "handler missing");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3293
  assert(!sync_handler->is_set(BlockBegin::was_visited_flag), "is visited here");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3294
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3295
  assert(lock != NULL || default_handler, "lock or handler missing");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3296
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3297
  XHandler* h = scope_data()->xhandlers()->remove_last();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3298
  assert(h->entry_block() == sync_handler, "corrupt list of handlers");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3299
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3300
  block()->set(BlockBegin::was_visited_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3301
  Value exception = append_with_bci(new ExceptionObject(), SynchronizationEntryBCI);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3302
  assert(exception->is_pinned(), "must be");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3303
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3304
  int bci = SynchronizationEntryBCI;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3305
  if (lock) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3306
    assert(state()->locks_size() > 0 && state()->lock_at(state()->locks_size() - 1) == lock, "lock is missing");
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3307
    if (!lock->is_linked()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3308
      lock = append_with_bci(lock, -1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3309
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3310
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3311
    // exit the monitor in the context of the synchronized method
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3312
    monitorexit(lock, SynchronizationEntryBCI);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3313
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3314
    // exit the context of the synchronized method
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3315
    if (!default_handler) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3316
      pop_scope();
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3317
      bci = _state->caller_state()->bci();
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3318
      _state = _state->caller_state()->copy_for_parsing();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3319
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3320
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3321
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3322
  // perform the throw as if at the the call site
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3323
  apush(exception);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3324
  throw_op(bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3325
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3326
  BlockEnd* end = last()->as_BlockEnd();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3327
  block()->set_end(end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3328
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3329
  _block = orig_block;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3330
  _state = orig_state;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3331
  _last = orig_last;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3332
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3333
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3334
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3335
bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3336
  assert(!callee->is_native(), "callee must not be native");
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3337
  if (count_backedges() && callee->has_loops()) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3338
    INLINE_BAILOUT("too complex for tiered");
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3339
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3340
  // first perform tests of things it's not possible to inline
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3341
  if (callee->has_exception_handlers() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3342
      !InlineMethodsWithExceptionHandlers) INLINE_BAILOUT("callee has exception handlers");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3343
  if (callee->is_synchronized() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3344
      !InlineSynchronizedMethods         ) INLINE_BAILOUT("callee is synchronized");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3345
  if (!callee->holder()->is_initialized()) INLINE_BAILOUT("callee's klass not initialized yet");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3346
  if (!callee->has_balanced_monitors())    INLINE_BAILOUT("callee's monitors do not match");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3347
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3348
  // Proper inlining of methods with jsrs requires a little more work.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3349
  if (callee->has_jsrs()                 ) INLINE_BAILOUT("jsrs not handled properly by inliner yet");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3350
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3351
  // now perform tests that are based on flag settings
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3352
  if (inline_level() > MaxInlineLevel                         ) INLINE_BAILOUT("too-deep inlining");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3353
  if (recursive_inline_level(callee) > MaxRecursiveInlineLevel) INLINE_BAILOUT("too-deep recursive inlining");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3354
  if (callee->code_size() > max_inline_size()                 ) INLINE_BAILOUT("callee is too large");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3355
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3356
  // don't inline throwable methods unless the inlining tree is rooted in a throwable class
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3357
  if (callee->name() == ciSymbol::object_initializer_name() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3358
      callee->holder()->is_subclass_of(ciEnv::current()->Throwable_klass())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3359
    // Throwable constructor call
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3360
    IRScope* top = scope();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3361
    while (top->caller() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3362
      top = top->caller();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3363
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3364
    if (!top->method()->holder()->is_subclass_of(ciEnv::current()->Throwable_klass())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3365
      INLINE_BAILOUT("don't inline Throwable constructors");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3366
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3367
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3368
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3369
  // When SSE2 is used on intel, then no special handling is needed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3370
  // for strictfp because the enum-constant is fixed at compile time,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3371
  // the check for UseSSE2 is needed here
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3372
  if (strict_fp_requires_explicit_rounding && UseSSE < 2 && method()->is_strict() != callee->is_strict()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3373
    INLINE_BAILOUT("caller and callee have different strict fp requirements");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3374
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3375
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3376
  if (compilation()->env()->num_inlined_bytecodes() > DesiredMethodLimit) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3377
    INLINE_BAILOUT("total inlining greater than DesiredMethodLimit");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3378
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3379
7432
f06f1253c317 7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents: 7427
diff changeset
  3380
  if (is_profiling() && !callee->ensure_method_data()) {
f06f1253c317 7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents: 7427
diff changeset
  3381
    INLINE_BAILOUT("mdo allocation failed");
f06f1253c317 7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents: 7427
diff changeset
  3382
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3383
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3384
      // printing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3385
  if (PrintInlining) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3386
    print_inline_result(callee, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3387
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3388
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3389
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3390
  // NOTE: Bailouts from this point on, which occur at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3391
  // GraphBuilder level, do not cause bailout just of the inlining but
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3392
  // in fact of the entire compilation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3393
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3394
  BlockBegin* orig_block = block();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3395
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3396
  const int args_base = state()->stack_size() - callee->arg_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3397
  assert(args_base >= 0, "stack underflow during inlining");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3398
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3399
  // Insert null check if necessary
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3400
  Value recv = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3401
  if (code() != Bytecodes::_invokestatic) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3402
    // note: null check must happen even if first instruction of callee does
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3403
    //       an implicit null check since the callee is in a different scope
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3404
    //       and we must make sure exception handling does the right thing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3405
    assert(!callee->is_static(), "callee must not be static");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3406
    assert(callee->arg_size() > 0, "must have at least a receiver");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3407
    recv = state()->stack_at(args_base);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3408
    null_check(recv);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3409
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3410
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3411
  if (is_profiling()) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3412
    // Note that we'd collect profile data in this method if we wanted it.
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3413
    // this may be redundant here...
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3414
    compilation()->set_would_profile(true);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3415
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3416
    if (profile_calls()) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3417
      profile_call(recv, holder_known ? callee->holder() : NULL);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3418
    }
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3419
    if (profile_inlined_calls()) {
6751
b399fd234e47 6988346: 6986046 breaks tiered
iveresov
parents: 6745
diff changeset
  3420
      profile_invocation(callee, copy_state_before());
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3421
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3422
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3423
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3424
  // Introduce a new callee continuation point - if the callee has
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3425
  // more than one return instruction or the return does not allow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3426
  // fall-through of control flow, all return instructions of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3427
  // callee will need to be replaced by Goto's pointing to this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3428
  // continuation point.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3429
  BlockBegin* cont = block_at(next_bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3430
  bool continuation_existed = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3431
  if (cont == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3432
    cont = new BlockBegin(next_bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3433
    // low number so that continuation gets parsed as early as possible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3434
    cont->set_depth_first_number(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3435
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3436
    if (PrintInitialBlockList) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3437
      tty->print_cr("CFG: created block %d (bci %d) as continuation for inline at bci %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3438
                    cont->block_id(), cont->bci(), bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3439
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3440
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3441
    continuation_existed = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3442
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3443
  // Record number of predecessors of continuation block before
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3444
  // inlining, to detect if inlined method has edges to its
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3445
  // continuation after inlining.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3446
  int continuation_preds = cont->number_of_preds();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3447
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3448
  // Push callee scope
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3449
  push_scope(callee, cont);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3450
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3451
  // the BlockListBuilder for the callee could have bailed out
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3452
  CHECK_BAILOUT_(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3453
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3454
  // Temporarily set up bytecode stream so we can append instructions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3455
  // (only using the bci of this stream)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3456
  scope_data()->set_stream(scope_data()->parent()->stream());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3457
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3458
  // Pass parameters into callee state: add assignments
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3459
  // note: this will also ensure that all arguments are computed before being passed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3460
  ValueStack* callee_state = state();
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3461
  ValueStack* caller_state = state()->caller_state();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3462
  { int i = args_base;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3463
    while (i < caller_state->stack_size()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3464
      const int par_no = i - args_base;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3465
      Value  arg = caller_state->stack_at_inc(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3466
      // NOTE: take base() of arg->type() to avoid problems storing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3467
      // constants
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3468
      store_local(callee_state, arg, arg->type()->base(), par_no);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3469
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3470
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3471
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3472
  // Remove args from stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3473
  // Note that we preserve locals state in case we can use it later
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3474
  // (see use of pop_scope() below)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3475
  caller_state->truncate_stack(args_base);
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3476
  assert(callee_state->stack_size() == 0, "callee stack must be empty");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3477
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3478
  Value lock;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3479
  BlockBegin* sync_handler;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3480
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3481
  // Inline the locking of the receiver if the callee is synchronized
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3482
  if (callee->is_synchronized()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3483
    lock = callee->is_static() ? append(new Constant(new InstanceConstant(callee->holder()->java_mirror())))
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3484
                               : state()->local_at(0);
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3485
    sync_handler = new BlockBegin(SynchronizationEntryBCI);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3486
    inline_sync_entry(lock, sync_handler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3487
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3488
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3489
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3490
  BlockBegin* callee_start_block = block_at(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3491
  if (callee_start_block != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3492
    assert(callee_start_block->is_set(BlockBegin::parser_loop_header_flag), "must be loop header");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3493
    Goto* goto_callee = new Goto(callee_start_block, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3494
    // The state for this goto is in the scope of the callee, so use
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3495
    // the entry bci for the callee instead of the call site bci.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3496
    append_with_bci(goto_callee, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3497
    _block->set_end(goto_callee);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3498
    callee_start_block->merge(callee_state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3499
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3500
    _last = _block = callee_start_block;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3501
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3502
    scope_data()->add_to_work_list(callee_start_block);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3503
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3504
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3505
  // Clear out bytecode stream
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3506
  scope_data()->set_stream(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3507
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3508
  // Ready to resume parsing in callee (either in the same block we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3509
  // were in before or in the callee's start block)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3510
  iterate_all_blocks(callee_start_block == NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3511
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3512
  // If we bailed out during parsing, return immediately (this is bad news)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3513
  if (bailed_out()) return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3514
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3515
  // iterate_all_blocks theoretically traverses in random order; in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3516
  // practice, we have only traversed the continuation if we are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3517
  // inlining into a subroutine
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3518
  assert(continuation_existed ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3519
         !continuation()->is_set(BlockBegin::was_visited_flag),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3520
         "continuation should not have been parsed yet if we created it");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3521
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3522
  // If we bailed out during parsing, return immediately (this is bad news)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3523
  CHECK_BAILOUT_(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3524
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3525
  // At this point we are almost ready to return and resume parsing of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3526
  // the caller back in the GraphBuilder. The only thing we want to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3527
  // first is an optimization: during parsing of the callee we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3528
  // generated at least one Goto to the continuation block. If we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3529
  // generated exactly one, and if the inlined method spanned exactly
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3530
  // one block (and we didn't have to Goto its entry), then we snip
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3531
  // off the Goto to the continuation, allowing control to fall
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3532
  // through back into the caller block and effectively performing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3533
  // block merging. This allows load elimination and CSE to take place
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3534
  // across multiple callee scopes if they are relatively simple, and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3535
  // is currently essential to making inlining profitable.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3536
  if (   num_returns() == 1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3537
      && block() == orig_block
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3538
      && block() == inline_cleanup_block()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3539
    _last = inline_cleanup_return_prev();
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3540
    _state = inline_cleanup_state();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3541
  } else if (continuation_preds == cont->number_of_preds()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3542
    // Inlining caused that the instructions after the invoke in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3543
    // caller are not reachable any more. So skip filling this block
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3544
    // with instructions!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3545
    assert (cont == continuation(), "");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3546
    assert(_last && _last->as_BlockEnd(), "");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3547
    _skip_block = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3548
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3549
    // Resume parsing in continuation block unless it was already parsed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3550
    // Note that if we don't change _last here, iteration in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3551
    // iterate_bytecodes_for_block will stop when we return.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3552
    if (!continuation()->is_set(BlockBegin::was_visited_flag)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3553
      // add continuation to work list instead of parsing it immediately
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3554
      assert(_last && _last->as_BlockEnd(), "");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3555
      scope_data()->parent()->add_to_work_list(continuation());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3556
      _skip_block = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3557
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3558
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3559
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3560
  // Fill the exception handler for synchronized methods with instructions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3561
  if (callee->is_synchronized() && sync_handler->state() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3562
    fill_sync_handler(lock, sync_handler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3563
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3564
    pop_scope();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3565
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3566
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3567
  compilation()->notice_inlined_method(callee);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3568
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3569
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3570
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3571
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3572
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3573
void GraphBuilder::inline_bailout(const char* msg) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3574
  assert(msg != NULL, "inline bailout msg must exist");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3575
  _inline_bailout_msg = msg;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3576
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3577
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3578
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3579
void GraphBuilder::clear_inline_bailout() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3580
  _inline_bailout_msg = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3581
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3582
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3583
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3584
void GraphBuilder::push_root_scope(IRScope* scope, BlockList* bci2block, BlockBegin* start) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3585
  ScopeData* data = new ScopeData(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3586
  data->set_scope(scope);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3587
  data->set_bci2block(bci2block);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3588
  _scope_data = data;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3589
  _block = start;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3590
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3591
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3592
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3593
void GraphBuilder::push_scope(ciMethod* callee, BlockBegin* continuation) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3594
  IRScope* callee_scope = new IRScope(compilation(), scope(), bci(), callee, -1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3595
  scope()->add_callee(callee_scope);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3596
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3597
  BlockListBuilder blb(compilation(), callee_scope, -1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3598
  CHECK_BAILOUT();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3599
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3600
  if (!blb.bci2block()->at(0)->is_set(BlockBegin::parser_loop_header_flag)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3601
    // this scope can be inlined directly into the caller so remove
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3602
    // the block at bci 0.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3603
    blb.bci2block()->at_put(0, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3604
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3605
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3606
  set_state(new ValueStack(callee_scope, state()->copy(ValueStack::CallerState, bci())));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3607
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3608
  ScopeData* data = new ScopeData(scope_data());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3609
  data->set_scope(callee_scope);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3610
  data->set_bci2block(blb.bci2block());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3611
  data->set_continuation(continuation);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3612
  _scope_data = data;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3613
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3614
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3615
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3616
void GraphBuilder::push_scope_for_jsr(BlockBegin* jsr_continuation, int jsr_dest_bci) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3617
  ScopeData* data = new ScopeData(scope_data());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3618
  data->set_parsing_jsr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3619
  data->set_jsr_entry_bci(jsr_dest_bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3620
  data->set_jsr_return_address_local(-1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3621
  // Must clone bci2block list as we will be mutating it in order to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3622
  // properly clone all blocks in jsr region as well as exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3623
  // handlers containing rets
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3624
  BlockList* new_bci2block = new BlockList(bci2block()->length());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3625
  new_bci2block->push_all(bci2block());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3626
  data->set_bci2block(new_bci2block);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3627
  data->set_scope(scope());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3628
  data->setup_jsr_xhandlers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3629
  data->set_continuation(continuation());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3630
  data->set_jsr_continuation(jsr_continuation);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3631
  _scope_data = data;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3632
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3633
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3634
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3635
void GraphBuilder::pop_scope() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3636
  int number_of_locks = scope()->number_of_locks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3637
  _scope_data = scope_data()->parent();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3638
  // accumulate minimum number of monitor slots to be reserved
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3639
  scope()->set_min_number_of_locks(number_of_locks);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3640
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3641
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3642
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3643
void GraphBuilder::pop_scope_for_jsr() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3644
  _scope_data = scope_data()->parent();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3645
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3646
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3647
bool GraphBuilder::append_unsafe_get_obj(ciMethod* callee, BasicType t, bool is_volatile) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3648
  if (InlineUnsafeOps) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3649
    Values* args = state()->pop_arguments(callee->arg_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3650
    null_check(args->at(0));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3651
    Instruction* offset = args->at(2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3652
#ifndef _LP64
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3653
    offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3654
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3655
    Instruction* op = append(new UnsafeGetObject(t, args->at(1), offset, is_volatile));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3656
    push(op->type(), op);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3657
    compilation()->set_has_unsafe_access(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3658
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3659
  return InlineUnsafeOps;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3660
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3661
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3662
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3663
bool GraphBuilder::append_unsafe_put_obj(ciMethod* callee, BasicType t, bool is_volatile) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3664
  if (InlineUnsafeOps) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3665
    Values* args = state()->pop_arguments(callee->arg_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3666
    null_check(args->at(0));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3667
    Instruction* offset = args->at(2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3668
#ifndef _LP64
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3669
    offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3670
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3671
    Instruction* op = append(new UnsafePutObject(t, args->at(1), offset, args->at(3), is_volatile));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3672
    compilation()->set_has_unsafe_access(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3673
    kill_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3674
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3675
  return InlineUnsafeOps;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3676
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3677
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3678
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3679
bool GraphBuilder::append_unsafe_get_raw(ciMethod* callee, BasicType t) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3680
  if (InlineUnsafeOps) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3681
    Values* args = state()->pop_arguments(callee->arg_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3682
    null_check(args->at(0));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3683
    Instruction* op = append(new UnsafeGetRaw(t, args->at(1), false));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3684
    push(op->type(), op);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3685
    compilation()->set_has_unsafe_access(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3686
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3687
  return InlineUnsafeOps;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3688
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3689
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3690
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3691
bool GraphBuilder::append_unsafe_put_raw(ciMethod* callee, BasicType t) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3692
  if (InlineUnsafeOps) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3693
    Values* args = state()->pop_arguments(callee->arg_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3694
    null_check(args->at(0));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3695
    Instruction* op = append(new UnsafePutRaw(t, args->at(1), args->at(2)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3696
    compilation()->set_has_unsafe_access(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3697
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3698
  return InlineUnsafeOps;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3699
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3700
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3701
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3702
bool GraphBuilder::append_unsafe_prefetch(ciMethod* callee, bool is_static, bool is_store) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3703
  if (InlineUnsafeOps) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3704
    Values* args = state()->pop_arguments(callee->arg_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3705
    int obj_arg_index = 1; // Assume non-static case
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3706
    if (is_static) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3707
      obj_arg_index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3708
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3709
      null_check(args->at(0));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3710
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3711
    Instruction* offset = args->at(obj_arg_index + 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3712
#ifndef _LP64
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3713
    offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3714
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3715
    Instruction* op = is_store ? append(new UnsafePrefetchWrite(args->at(obj_arg_index), offset))
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3716
                               : append(new UnsafePrefetchRead (args->at(obj_arg_index), offset));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3717
    compilation()->set_has_unsafe_access(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3718
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3719
  return InlineUnsafeOps;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3720
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3721
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3722
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3723
void GraphBuilder::append_unsafe_CAS(ciMethod* callee) {
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3724
  ValueStack* state_before = copy_state_for_exception();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3725
  ValueType* result_type = as_ValueType(callee->return_type());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3726
  assert(result_type->is_int(), "int result");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3727
  Values* args = state()->pop_arguments(callee->arg_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3728
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3729
  // Pop off some args to speically handle, then push back
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3730
  Value newval = args->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3731
  Value cmpval = args->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3732
  Value offset = args->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3733
  Value src = args->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3734
  Value unsafe_obj = args->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3735
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3736
  // Separately handle the unsafe arg. It is not needed for code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3737
  // generation, but must be null checked
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3738
  null_check(unsafe_obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3739
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3740
#ifndef _LP64
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3741
  offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3742
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3743
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3744
  args->push(src);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3745
  args->push(offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3746
  args->push(cmpval);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3747
  args->push(newval);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3748
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3749
  // An unsafe CAS can alias with other field accesses, but we don't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3750
  // know which ones so mark the state as no preserved.  This will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3751
  // cause CSE to invalidate memory across it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3752
  bool preserves_state = false;
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3753
  Intrinsic* result = new Intrinsic(result_type, callee->intrinsic_id(), args, false, state_before, preserves_state);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3754
  append_split(result);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3755
  push(result_type, result);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3756
  compilation()->set_has_unsafe_access(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3757
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3758
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3759
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3760
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3761
void GraphBuilder::print_inline_result(ciMethod* callee, bool res) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3762
  const char sync_char      = callee->is_synchronized()        ? 's' : ' ';
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3763
  const char exception_char = callee->has_exception_handlers() ? '!' : ' ';
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3764
  const char monitors_char  = callee->has_monitor_bytecodes()  ? 'm' : ' ';
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3765
  tty->print("     %c%c%c ", sync_char, exception_char, monitors_char);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3766
  for (int i = 0; i < scope()->level(); i++) tty->print("  ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3767
  if (res) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3768
    tty->print("  ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3769
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3770
    tty->print("- ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3771
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3772
  tty->print("@ %d  ", bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3773
  callee->print_short_name();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3774
  tty->print(" (%d bytes)", callee->code_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3775
  if (_inline_bailout_msg) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3776
    tty->print("  %s", _inline_bailout_msg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3777
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3778
  tty->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3779
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3780
  if (res && CIPrintMethodCodes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3781
    callee->print_codes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3782
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3783
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3784
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3785
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3786
void GraphBuilder::print_stats() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3787
  vmap()->print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3788
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3789
#endif // PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3790
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3791
void GraphBuilder::profile_call(Value recv, ciKlass* known_holder) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3792
  append(new ProfileCall(method(), bci(), recv, known_holder));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3793
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3794
6751
b399fd234e47 6988346: 6986046 breaks tiered
iveresov
parents: 6745
diff changeset
  3795
void GraphBuilder::profile_invocation(ciMethod* callee, ValueStack* state) {
b399fd234e47 6988346: 6986046 breaks tiered
iveresov
parents: 6745
diff changeset
  3796
  append(new ProfileInvoke(callee, state));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3797
}