hotspot/src/share/vm/c1/c1_GraphBuilder.cpp
author johnc
Thu, 07 Apr 2011 09:53:20 -0700
changeset 9176 42d9d1010f38
parent 8725 8c1e3dd5fe1b
child 9179 6db9c9dffe1f
permissions -rw-r--r--
7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error Summary: A referent object that is only weakly reachable at the start of concurrent marking but is re-attached to the strongly reachable object graph during marking may not be marked as live. This can cause the reference object to be processed prematurely and leave dangling pointers to the referent object. Implement a read barrier for the java.lang.ref.Reference::referent field by intrinsifying the Reference.get() method, and intercepting accesses though JNI, reflection, and Unsafe, so that when a non-null referent object is read it is also logged in an SATB buffer. Reviewed-by: kvn, iveresov, never, tonyp, dholmes
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
8065
7ca689ce3d32 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 7432
diff changeset
     2
 * Copyright (c) 1999, 2011, 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
7913
dd096a83bdbb 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 7432
diff changeset
   322
        Bytecode_tableswitch sw(&s);
dd096a83bdbb 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 7432
diff changeset
   323
        int l = sw.length();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
        for (int i = 0; i < l; i++) {
7913
dd096a83bdbb 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 7432
diff changeset
   325
          make_block_at(cur_bci + sw.dest_offset_at(i), current);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
        }
7913
dd096a83bdbb 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 7432
diff changeset
   327
        make_block_at(cur_bci + sw.default_offset(), current);
1
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
7913
dd096a83bdbb 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 7432
diff changeset
   334
        Bytecode_lookupswitch sw(&s);
dd096a83bdbb 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 7432
diff changeset
   335
        int l = sw.number_of_pairs();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
        for (int i = 0; i < l; i++) {
7913
dd096a83bdbb 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 7432
diff changeset
   337
          make_block_at(cur_bci + sw.pair_at(i).offset(), current);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
        }
7913
dd096a83bdbb 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 7432
diff changeset
   339
        make_block_at(cur_bci + sw.default_offset(), current);
1
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() {
7913
dd096a83bdbb 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 7432
diff changeset
  1278
  Bytecode_tableswitch sw(stream());
dd096a83bdbb 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 7432
diff changeset
  1279
  const int l = sw.length();
1
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.
7913
dd096a83bdbb 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 7432
diff changeset
  1284
    Value key = append(new Constant(new IntConstant(sw.low_key())));
dd096a83bdbb 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 7432
diff changeset
  1285
    BlockBegin* tsux = block_at(bci() + sw.dest_offset_at(0));
dd096a83bdbb 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 7432
diff changeset
  1286
    BlockBegin* fsux = block_at(bci() + sw.default_offset());
1
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++) {
7913
dd096a83bdbb 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 7432
diff changeset
  1296
      sux->at_put(i, block_at(bci() + sw.dest_offset_at(i)));
dd096a83bdbb 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 7432
diff changeset
  1297
      if (sw.dest_offset_at(i) < 0) has_bb = true;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1298
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1299
    // add default successor
7913
dd096a83bdbb 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 7432
diff changeset
  1300
    sux->at_put(i, block_at(bci() + sw.default_offset()));
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1301
    ValueStack* state_before = has_bb ? copy_state_before() : NULL;
7913
dd096a83bdbb 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 7432
diff changeset
  1302
    append(new TableSwitch(ipop(), sux, sw.low_key(), state_before, has_bb));
1
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() {
7913
dd096a83bdbb 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 7432
diff changeset
  1308
  Bytecode_lookupswitch sw(stream());
dd096a83bdbb 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 7432
diff changeset
  1309
  const int l = sw.number_of_pairs();
1
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
7913
dd096a83bdbb 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 7432
diff changeset
  1315
    LookupswitchPair pair = sw.pair_at(0);
dd096a83bdbb 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 7432
diff changeset
  1316
    Value key = append(new Constant(new IntConstant(pair.match())));
dd096a83bdbb 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 7432
diff changeset
  1317
    BlockBegin* tsux = block_at(bci() + pair.offset());
dd096a83bdbb 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 7432
diff changeset
  1318
    BlockBegin* fsux = block_at(bci() + sw.default_offset());
1
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++) {
7913
dd096a83bdbb 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 7432
diff changeset
  1329
      LookupswitchPair pair = sw.pair_at(i);
dd096a83bdbb 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 7432
diff changeset
  1330
      if (pair.offset() < 0) has_bb = true;
dd096a83bdbb 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 7432
diff changeset
  1331
      sux->at_put(i, block_at(bci() + pair.offset()));
dd096a83bdbb 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 7432
diff changeset
  1332
      keys->at_put(i, pair.match());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1333
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1334
    // add default successor
7913
dd096a83bdbb 4926272: methodOopDesc::method_from_bcp is unsafe
never
parents: 7432
diff changeset
  1335
    sux->at_put(i, block_at(bci() + sw.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
8065
7ca689ce3d32 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 7432
diff changeset
  1399
    if (compilation()->env()->dtrace_method_probes()) {
7ca689ce3d32 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 7432
diff changeset
  1400
      // Report exit from inline methods
7ca689ce3d32 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 7432
diff changeset
  1401
      Values* args = new Values(1);
7ca689ce3d32 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 7432
diff changeset
  1402
      args->push(append(new Constant(new ObjectConstant(method()))));
7ca689ce3d32 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 7432
diff changeset
  1403
      append(new RuntimeCall(voidType, "dtrace_method_exit", CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), args));
7ca689ce3d32 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 7432
diff changeset
  1404
    }
7ca689ce3d32 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 7432
diff changeset
  1405
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1406
    // If the inlined method is synchronized, the monitor must be
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1407
    // released before we jump to the continuation block.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1408
    if (method()->is_synchronized()) {
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1409
      assert(state()->locks_size() == 1, "receiver must be locked here");
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1410
      monitorexit(state()->lock_at(0), SynchronizationEntryBCI);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1411
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1412
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1413
    // State at end of inlined method is the state of the caller
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1414
    // without the method parameters on stack, including the
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1415
    // return value, if any, of the inlined method on operand stack.
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1416
    set_state(state()->caller_state()->copy_for_parsing());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1417
    if (x != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1418
      state()->push(x->type(), x);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1419
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1420
    Goto* goto_callee = new Goto(continuation(), false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1421
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1422
    // See whether this is the first return; if so, store off some
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1423
    // of the state for later examination
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1424
    if (num_returns() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1425
      set_inline_cleanup_info(_block, _last, state());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1426
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1427
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1428
    // The current bci() is in the wrong scope, so use the bci() of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1429
    // the continuation point.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1430
    append_with_bci(goto_callee, scope_data()->continuation()->bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1431
    incr_num_returns();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1432
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1433
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1434
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1435
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1436
  state()->truncate_stack(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1437
  if (method()->is_synchronized()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1438
    // perform the unlocking before exiting the method
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1439
    Value receiver;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1440
    if (!method()->is_static()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1441
      receiver = _initial_state->local_at(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1442
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1443
      receiver = append(new Constant(new ClassConstant(method()->holder())));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1444
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1445
    append_split(new MonitorExit(receiver, state()->unlock()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1446
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1447
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1448
  append(new Return(x));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1449
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1450
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1451
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1452
void GraphBuilder::access_field(Bytecodes::Code code) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1453
  bool will_link;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1454
  ciField* field = stream()->get_field(will_link);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1455
  ciInstanceKlass* holder = field->holder();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1456
  BasicType field_type = field->type()->basic_type();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1457
  ValueType* type = as_ValueType(field_type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1458
  // call will_link again to determine if the field is valid.
8671
13ffa40a2f0a 6965570: assert(!needs_patching && x->is_loaded(),"how do we know it's volatile if it's not loaded")
never
parents: 8492
diff changeset
  1459
  const bool needs_patching = !holder->is_loaded() ||
13ffa40a2f0a 6965570: assert(!needs_patching && x->is_loaded(),"how do we know it's volatile if it's not loaded")
never
parents: 8492
diff changeset
  1460
                              !field->will_link(method()->holder(), code) ||
13ffa40a2f0a 6965570: assert(!needs_patching && x->is_loaded(),"how do we know it's volatile if it's not loaded")
never
parents: 8492
diff changeset
  1461
                              PatchALot;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1462
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1463
  ValueStack* state_before = NULL;
8671
13ffa40a2f0a 6965570: assert(!needs_patching && x->is_loaded(),"how do we know it's volatile if it's not loaded")
never
parents: 8492
diff changeset
  1464
  if (!holder->is_initialized() || needs_patching) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1465
    // save state before instruction for debug info when
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1466
    // deoptimization happens during patching
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1467
    state_before = copy_state_before();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1468
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1469
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1470
  Value obj = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1471
  if (code == Bytecodes::_getstatic || code == Bytecodes::_putstatic) {
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1472
    if (state_before != NULL) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1473
      // build a patching constant
8725
8c1e3dd5fe1b 7017732: move static fields into Class to prepare for perm gen removal
never
parents: 8671
diff changeset
  1474
      obj = new Constant(new InstanceConstant(holder->java_mirror()), state_before);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1475
    } else {
8725
8c1e3dd5fe1b 7017732: move static fields into Class to prepare for perm gen removal
never
parents: 8671
diff changeset
  1476
      obj = new Constant(new InstanceConstant(holder->java_mirror()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1477
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1478
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1479
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1480
8671
13ffa40a2f0a 6965570: assert(!needs_patching && x->is_loaded(),"how do we know it's volatile if it's not loaded")
never
parents: 8492
diff changeset
  1481
  const int offset = !needs_patching ? field->offset() : -1;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1482
  switch (code) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1483
    case Bytecodes::_getstatic: {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1484
      // check for compile-time constants, i.e., initialized static final fields
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1485
      Instruction* constant = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1486
      if (field->is_constant() && !PatchALot) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1487
        ciConstant field_val = field->constant_value();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1488
        BasicType field_type = field_val.basic_type();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1489
        switch (field_type) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1490
        case T_ARRAY:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1491
        case T_OBJECT:
3908
24b55ad4c228 6863023: need non-perm oops in code cache for JSR 292
jrose
parents: 3261
diff changeset
  1492
          if (field_val.as_object()->should_be_constant()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1493
            constant =  new Constant(as_ValueType(field_val));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1494
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1495
          break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1496
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1497
        default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1498
          constant = new Constant(as_ValueType(field_val));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1499
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1500
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1501
      if (constant != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1502
        push(type, append(constant));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1503
      } else {
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1504
        if (state_before == NULL) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1505
          state_before = copy_state_for_exception();
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1506
        }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1507
        push(type, append(new LoadField(append(obj), offset, field, true,
8671
13ffa40a2f0a 6965570: assert(!needs_patching && x->is_loaded(),"how do we know it's volatile if it's not loaded")
never
parents: 8492
diff changeset
  1508
                                        state_before, needs_patching)));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1509
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1510
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1511
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1512
    case Bytecodes::_putstatic:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1513
      { Value val = pop(type);
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1514
        if (state_before == NULL) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1515
          state_before = copy_state_for_exception();
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1516
        }
8671
13ffa40a2f0a 6965570: assert(!needs_patching && x->is_loaded(),"how do we know it's volatile if it's not loaded")
never
parents: 8492
diff changeset
  1517
        append(new StoreField(append(obj), offset, field, val, true, state_before, needs_patching));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1518
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1519
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1520
    case Bytecodes::_getfield :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1521
      {
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1522
        if (state_before == NULL) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1523
          state_before = copy_state_for_exception();
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1524
        }
8671
13ffa40a2f0a 6965570: assert(!needs_patching && x->is_loaded(),"how do we know it's volatile if it's not loaded")
never
parents: 8492
diff changeset
  1525
        LoadField* load = new LoadField(apop(), offset, field, false, state_before, needs_patching);
13ffa40a2f0a 6965570: assert(!needs_patching && x->is_loaded(),"how do we know it's volatile if it's not loaded")
never
parents: 8492
diff changeset
  1526
        Value replacement = !needs_patching ? _memory->load(load) : load;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1527
        if (replacement != load) {
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1528
          assert(replacement->is_linked() || !replacement->can_be_linked(), "should already by linked");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1529
          push(type, replacement);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1530
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1531
          push(type, append(load));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1532
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1533
        break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1534
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1535
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1536
    case Bytecodes::_putfield :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1537
      { Value val = pop(type);
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1538
        if (state_before == NULL) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1539
          state_before = copy_state_for_exception();
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1540
        }
8671
13ffa40a2f0a 6965570: assert(!needs_patching && x->is_loaded(),"how do we know it's volatile if it's not loaded")
never
parents: 8492
diff changeset
  1541
        StoreField* store = new StoreField(apop(), offset, field, val, false, state_before, needs_patching);
13ffa40a2f0a 6965570: assert(!needs_patching && x->is_loaded(),"how do we know it's volatile if it's not loaded")
never
parents: 8492
diff changeset
  1542
        if (!needs_patching) store = _memory->store(store);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1543
        if (store != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1544
          append(store);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1545
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1546
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1547
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1548
    default                   :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1549
      ShouldNotReachHere();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1550
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1551
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1552
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1553
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1554
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1555
Dependencies* GraphBuilder::dependency_recorder() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1556
  assert(DeoptC1, "need debug information");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1557
  return compilation()->dependency_recorder();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1558
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1559
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1560
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1561
void GraphBuilder::invoke(Bytecodes::Code code) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1562
  bool will_link;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1563
  ciMethod* target = stream()->get_method(will_link);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1564
  // we have to make sure the argument size (incl. the receiver)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1565
  // is correct for compilation (the call would fail later during
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1566
  // linkage anyway) - was bug (gri 7/28/99)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1567
  if (target->is_loaded() && target->is_static() != (code == Bytecodes::_invokestatic)) BAILOUT("will cause link error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1568
  ciInstanceKlass* klass = target->holder();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1569
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1570
  // check if CHA possible: if so, change the code to invoke_special
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1571
  ciInstanceKlass* calling_klass = method()->holder();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1572
  ciKlass* holder = stream()->get_declared_method_holder();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1573
  ciInstanceKlass* callee_holder = ciEnv::get_instance_klass_for_declared_method_holder(holder);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1574
  ciInstanceKlass* actual_recv = callee_holder;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1575
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1576
  // some methods are obviously bindable without any type checks so
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1577
  // convert them directly to an invokespecial.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1578
  if (target->is_loaded() && !target->is_abstract() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1579
      target->can_be_statically_bound() && code == Bytecodes::_invokevirtual) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1580
    code = Bytecodes::_invokespecial;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1581
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1582
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1583
  // NEEDS_CLEANUP
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1584
  // I've added the target-is_loaded() test below but I don't really understand
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1585
  // how klass->is_loaded() can be true and yet target->is_loaded() is false.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1586
  // this happened while running the JCK invokevirtual tests under doit.  TKR
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1587
  ciMethod* cha_monomorphic_target = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1588
  ciMethod* exact_target = NULL;
5046
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4430
diff changeset
  1589
  if (UseCHA && DeoptC1 && klass->is_loaded() && target->is_loaded() &&
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4430
diff changeset
  1590
      !target->is_method_handle_invoke()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1591
    Value receiver = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1592
    ciInstanceKlass* receiver_klass = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1593
    bool type_is_exact = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1594
    // try to find a precise receiver type
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1595
    if (will_link && !target->is_static()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1596
      int index = state()->stack_size() - (target->arg_size_no_receiver() + 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1597
      receiver = state()->stack_at(index);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1598
      ciType* type = receiver->exact_type();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1599
      if (type != NULL && type->is_loaded() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1600
          type->is_instance_klass() && !type->as_instance_klass()->is_interface()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1601
        receiver_klass = (ciInstanceKlass*) type;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1602
        type_is_exact = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1603
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1604
      if (type == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1605
        type = receiver->declared_type();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1606
        if (type != NULL && type->is_loaded() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1607
            type->is_instance_klass() && !type->as_instance_klass()->is_interface()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1608
          receiver_klass = (ciInstanceKlass*) type;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1609
          if (receiver_klass->is_leaf_type() && !receiver_klass->is_final()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1610
            // Insert a dependency on this type since
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1611
            // find_monomorphic_target may assume it's already done.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1612
            dependency_recorder()->assert_leaf_type(receiver_klass);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1613
            type_is_exact = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1614
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1615
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1616
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1617
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1618
    if (receiver_klass != NULL && type_is_exact &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1619
        receiver_klass->is_loaded() && code != Bytecodes::_invokespecial) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1620
      // If we have the exact receiver type we can bind directly to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1621
      // the method to call.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1622
      exact_target = target->resolve_invoke(calling_klass, receiver_klass);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1623
      if (exact_target != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1624
        target = exact_target;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1625
        code = Bytecodes::_invokespecial;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1626
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1627
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1628
    if (receiver_klass != NULL &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1629
        receiver_klass->is_subtype_of(actual_recv) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1630
        actual_recv->is_initialized()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1631
      actual_recv = receiver_klass;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1632
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1633
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1634
    if ((code == Bytecodes::_invokevirtual && callee_holder->is_initialized()) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1635
        (code == Bytecodes::_invokeinterface && callee_holder->is_initialized() && !actual_recv->is_interface())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1636
      // Use CHA on the receiver to select a more precise method.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1637
      cha_monomorphic_target = target->find_monomorphic_target(calling_klass, callee_holder, actual_recv);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1638
    } else if (code == Bytecodes::_invokeinterface && callee_holder->is_loaded() && receiver != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1639
      // if there is only one implementor of this interface then we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1640
      // may be able bind this invoke directly to the implementing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1641
      // klass but we need both a dependence on the single interface
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1642
      // and on the method we bind to.  Additionally since all we know
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1643
      // about the receiver type is the it's supposed to implement the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1644
      // interface we have to insert a check that it's the class we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1645
      // expect.  Interface types are not checked by the verifier so
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1646
      // they are roughly equivalent to Object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1647
      ciInstanceKlass* singleton = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1648
      if (target->holder()->nof_implementors() == 1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1649
        singleton = target->holder()->implementor(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1650
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1651
      if (singleton) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1652
        cha_monomorphic_target = target->find_monomorphic_target(calling_klass, target->holder(), singleton);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1653
        if (cha_monomorphic_target != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1654
          // If CHA is able to bind this invoke then update the class
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1655
          // to match that class, otherwise klass will refer to the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1656
          // interface.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1657
          klass = cha_monomorphic_target->holder();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1658
          actual_recv = target->holder();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1659
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1660
          // insert a check it's really the expected class.
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1661
          CheckCast* c = new CheckCast(klass, receiver, copy_state_for_exception());
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1662
          c->set_incompatible_class_change_check();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1663
          c->set_direct_compare(klass->is_final());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1664
          append_split(c);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1665
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1666
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1667
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1668
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1669
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1670
  if (cha_monomorphic_target != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1671
    if (cha_monomorphic_target->is_abstract()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1672
      // Do not optimize for abstract methods
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1673
      cha_monomorphic_target = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1674
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1675
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1676
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1677
  if (cha_monomorphic_target != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1678
    if (!(target->is_final_method())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1679
      // If we inlined because CHA revealed only a single target method,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1680
      // then we are dependent on that target method not getting overridden
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1681
      // by dynamic class loading.  Be sure to test the "static" receiver
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1682
      // dest_method here, as opposed to the actual receiver, which may
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1683
      // falsely lead us to believe that the receiver is final or private.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1684
      dependency_recorder()->assert_unique_concrete_method(actual_recv, cha_monomorphic_target);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1685
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1686
    code = Bytecodes::_invokespecial;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1687
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1688
  // check if we could do inlining
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1689
  if (!PatchALot && Inline && klass->is_loaded() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1690
      (klass->is_initialized() || klass->is_interface() && target->holder()->is_initialized())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1691
      && target->will_link(klass, callee_holder, code)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1692
    // callee is known => check if we have static binding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1693
    assert(target->is_loaded(), "callee must be known");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1694
    if (code == Bytecodes::_invokestatic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1695
     || code == Bytecodes::_invokespecial
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1696
     || code == Bytecodes::_invokevirtual && target->is_final_method()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1697
    ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1698
      // static binding => check if callee is ok
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1699
      ciMethod* inline_target = (cha_monomorphic_target != NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1700
                                  ? cha_monomorphic_target
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1701
                                  : target;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1702
      bool res = try_inline(inline_target, (cha_monomorphic_target != NULL) || (exact_target != NULL));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1703
      CHECK_BAILOUT();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1704
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1705
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1706
      // printing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1707
      if (PrintInlining && !res) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1708
        // if it was successfully inlined, then it was already printed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1709
        print_inline_result(inline_target, res);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1710
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1711
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1712
      clear_inline_bailout();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1713
      if (res) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1714
        // Register dependence if JVMTI has either breakpoint
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1715
        // setting or hotswapping of methods capabilities since they may
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1716
        // 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
  1717
        if (compilation()->env()->jvmti_can_hotswap_or_post_breakpoint()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1718
          dependency_recorder()->assert_evol_method(inline_target);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1719
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1720
        return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1721
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1722
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1723
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1724
  // If we attempted an inline which did not succeed because of a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1725
  // bailout during construction of the callee graph, the entire
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1726
  // compilation has to be aborted. This is fairly rare and currently
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1727
  // seems to only occur for jasm-generated classes which contain
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1728
  // jsr/ret pairs which are not associated with finally clauses and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1729
  // do not have exception handlers in the containing method, and are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1730
  // therefore not caught early enough to abort the inlining without
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1731
  // corrupting the graph. (We currently bail out with a non-empty
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1732
  // stack at a ret in these situations.)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1733
  CHECK_BAILOUT();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1734
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1735
  // inlining not successful => standard invoke
5046
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4430
diff changeset
  1736
  bool is_loaded = target->is_loaded();
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4430
diff changeset
  1737
  bool has_receiver =
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4430
diff changeset
  1738
    code == Bytecodes::_invokespecial   ||
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4430
diff changeset
  1739
    code == Bytecodes::_invokevirtual   ||
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4430
diff changeset
  1740
    code == Bytecodes::_invokeinterface;
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4430
diff changeset
  1741
  bool is_invokedynamic = code == Bytecodes::_invokedynamic;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1742
  ValueType* result_type = as_ValueType(target->return_type());
5046
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4430
diff changeset
  1743
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4430
diff changeset
  1744
  // 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
  1745
  // invokedynamics may deoptimize.
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1746
  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
  1747
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1748
  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
  1749
  Value recv = has_receiver ? apop() : NULL;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1750
  int vtable_index = methodOopDesc::invalid_vtable_index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1751
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1752
#ifdef SPARC
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1753
  // Currently only supported on Sparc.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1754
  // The UseInlineCaches only controls dispatch to invokevirtuals for
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1755
  // loaded classes which we weren't able to statically bind.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1756
  if (!UseInlineCaches && is_loaded && code == Bytecodes::_invokevirtual
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1757
      && !target->can_be_statically_bound()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1758
    // Find a vtable index if one is available
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1759
    vtable_index = target->resolve_vtable_index(calling_klass, callee_holder);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1760
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1761
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1762
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1763
  if (recv != NULL &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1764
      (code == Bytecodes::_invokespecial ||
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1765
       !is_loaded || target->is_final())) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1766
    // invokespecial always needs a NULL check.  invokevirtual where
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1767
    // the target is final or where it's not known that whether the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1768
    // target is final requires a NULL check.  Otherwise normal
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1769
    // invokevirtual will perform the null check during the lookup
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1770
    // logic or the unverified entry point.  Profiling of calls
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1771
    // requires that the null check is performed in all cases.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1772
    null_check(recv);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1773
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1774
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1775
  if (is_profiling()) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1776
    if (recv != NULL && profile_calls()) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1777
      null_check(recv);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1778
    }
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1779
    // Note that we'd collect profile data in this method if we wanted it.
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1780
    compilation()->set_would_profile(true);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1781
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1782
    if (profile_calls()) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1783
      assert(cha_monomorphic_target == NULL || exact_target == NULL, "both can not be set");
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1784
      ciKlass* target_klass = NULL;
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1785
      if (cha_monomorphic_target != NULL) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1786
        target_klass = cha_monomorphic_target->holder();
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1787
      } else if (exact_target != NULL) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1788
        target_klass = exact_target->holder();
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1789
      }
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1790
      profile_call(recv, target_klass);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1791
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1792
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1793
5046
27e801a857cb 6919934: JSR 292 needs to support x86 C1
twisti
parents: 4430
diff changeset
  1794
  Invoke* result = new Invoke(code, result_type, recv, args, vtable_index, target, state_before);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1795
  // push result
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1796
  append_split(result);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1797
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1798
  if (result_type != voidType) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1799
    if (method()->is_strict()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1800
      push(result_type, round_fp(result));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1801
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1802
      push(result_type, result);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1803
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1804
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1805
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1806
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1807
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1808
void GraphBuilder::new_instance(int klass_index) {
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1809
  ValueStack* state_before = copy_state_exhandling();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1810
  bool will_link;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1811
  ciKlass* klass = stream()->get_klass(will_link);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1812
  assert(klass->is_instance_klass(), "must be an instance klass");
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1813
  NewInstance* new_instance = new NewInstance(klass->as_instance_klass(), state_before);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1814
  _memory->new_instance(new_instance);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1815
  apush(append_split(new_instance));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1816
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1817
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1818
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1819
void GraphBuilder::new_type_array() {
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1820
  ValueStack* state_before = copy_state_exhandling();
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1821
  apush(append_split(new NewTypeArray(ipop(), (BasicType)stream()->get_index(), state_before)));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1822
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1823
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1824
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1825
void GraphBuilder::new_object_array() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1826
  bool will_link;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1827
  ciKlass* klass = stream()->get_klass(will_link);
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1828
  ValueStack* state_before = !klass->is_loaded() || PatchALot ? copy_state_before() : copy_state_exhandling();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1829
  NewArray* n = new NewObjectArray(klass, ipop(), state_before);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1830
  apush(append_split(n));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1831
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1832
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1833
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1834
bool GraphBuilder::direct_compare(ciKlass* k) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1835
  if (k->is_loaded() && k->is_instance_klass() && !UseSlowPath) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1836
    ciInstanceKlass* ik = k->as_instance_klass();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1837
    if (ik->is_final()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1838
      return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1839
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1840
      if (DeoptC1 && UseCHA && !(ik->has_subklass() || ik->is_interface())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1841
        // test class is leaf class
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1842
        dependency_recorder()->assert_leaf_type(ik);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1843
        return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1844
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1845
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1846
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1847
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1848
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1849
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1850
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1851
void GraphBuilder::check_cast(int klass_index) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1852
  bool will_link;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1853
  ciKlass* klass = stream()->get_klass(will_link);
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1854
  ValueStack* state_before = !klass->is_loaded() || PatchALot ? copy_state_before() : copy_state_for_exception();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1855
  CheckCast* c = new CheckCast(klass, apop(), state_before);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1856
  apush(append_split(c));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1857
  c->set_direct_compare(direct_compare(klass));
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1858
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1859
  if (is_profiling()) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1860
    // Note that we'd collect profile data in this method if we wanted it.
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1861
    compilation()->set_would_profile(true);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1862
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1863
    if (profile_checkcasts()) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1864
      c->set_profiled_method(method());
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1865
      c->set_profiled_bci(bci());
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1866
      c->set_should_profile(true);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1867
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1868
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1869
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1870
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1871
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1872
void GraphBuilder::instance_of(int klass_index) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1873
  bool will_link;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1874
  ciKlass* klass = stream()->get_klass(will_link);
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1875
  ValueStack* state_before = !klass->is_loaded() || PatchALot ? copy_state_before() : copy_state_exhandling();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1876
  InstanceOf* i = new InstanceOf(klass, apop(), state_before);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1877
  ipush(append_split(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1878
  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
  1879
cfc616b49f58 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 6453
diff changeset
  1880
  if (is_profiling()) {
cfc616b49f58 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 6453
diff changeset
  1881
    // 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
  1882
    compilation()->set_would_profile(true);
cfc616b49f58 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 6453
diff changeset
  1883
cfc616b49f58 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 6453
diff changeset
  1884
    if (profile_checkcasts()) {
cfc616b49f58 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 6453
diff changeset
  1885
      i->set_profiled_method(method());
cfc616b49f58 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 6453
diff changeset
  1886
      i->set_profiled_bci(bci());
cfc616b49f58 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 6453
diff changeset
  1887
      i->set_should_profile(true);
cfc616b49f58 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 6453
diff changeset
  1888
    }
cfc616b49f58 6919069: client compiler needs to capture more profile information for tiered work
iveresov
parents: 6453
diff changeset
  1889
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1890
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1891
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1892
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1893
void GraphBuilder::monitorenter(Value x, int bci) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1894
  // save state before locking in case of deoptimization after a NullPointerException
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1895
  ValueStack* state_before = copy_state_for_exception_with_bci(bci);
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1896
  append_with_bci(new MonitorEnter(x, state()->lock(x), state_before), bci);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1897
  kill_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1898
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1899
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1900
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1901
void GraphBuilder::monitorexit(Value x, int bci) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1902
  append_with_bci(new MonitorExit(x, state()->unlock()), bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1903
  kill_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1904
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1905
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1906
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1907
void GraphBuilder::new_multi_array(int dimensions) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1908
  bool will_link;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1909
  ciKlass* klass = stream()->get_klass(will_link);
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1910
  ValueStack* state_before = !klass->is_loaded() || PatchALot ? copy_state_before() : copy_state_exhandling();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1911
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1912
  Values* dims = new Values(dimensions, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1913
  // fill in all dimensions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1914
  int i = dimensions;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1915
  while (i-- > 0) dims->at_put(i, ipop());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1916
  // create array
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1917
  NewArray* n = new NewMultiArray(klass, dims, state_before);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1918
  apush(append_split(n));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1919
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1920
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1921
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1922
void GraphBuilder::throw_op(int bci) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1923
  // We require that the debug info for a Throw be the "state before"
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1924
  // the Throw (i.e., exception oop is still on TOS)
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1925
  ValueStack* state_before = copy_state_before_with_bci(bci);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1926
  Throw* t = new Throw(apop(), state_before);
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1927
  // operand stack not needed after a throw
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1928
  state()->truncate_stack(0);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1929
  append_with_bci(t, bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1930
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1931
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1932
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1933
Value GraphBuilder::round_fp(Value fp_value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1934
  // no rounding needed if SSE2 is used
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1935
  if (RoundFPResults && UseSSE < 2) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1936
    // Must currently insert rounding node for doubleword values that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1937
    // are results of expressions (i.e., not loads from memory or
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1938
    // constants)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1939
    if (fp_value->type()->tag() == doubleTag &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1940
        fp_value->as_Constant() == NULL &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1941
        fp_value->as_Local() == NULL &&       // method parameters need no rounding
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1942
        fp_value->as_RoundFP() == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1943
      return append(new RoundFP(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
  return fp_value;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1947
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1948
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1949
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1950
Instruction* GraphBuilder::append_with_bci(Instruction* instr, int bci) {
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  1951
  Canonicalizer canon(compilation(), instr, bci);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1952
  Instruction* i1 = canon.canonical();
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1953
  if (i1->is_linked() || !i1->can_be_linked()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1954
    // Canonicalizer returned an instruction which was already
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1955
    // appended so simply return it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1956
    return i1;
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1957
  }
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1958
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1959
  if (UseLocalValueNumbering) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1960
    // Lookup the instruction in the ValueMap and add it to the map if
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1961
    // it's not found.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1962
    Instruction* i2 = vmap()->find_insert(i1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1963
    if (i2 != i1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1964
      // found an entry in the value map, so just return it.
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1965
      assert(i2->is_linked(), "should already be linked");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1966
      return i2;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1967
    }
1612
2488b45ded37 6756768: C1 generates invalid code
never
parents: 1
diff changeset
  1968
    ValueNumberingEffects vne(vmap());
2488b45ded37 6756768: C1 generates invalid code
never
parents: 1
diff changeset
  1969
    i1->visit(&vne);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1970
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1971
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1972
  // i1 was not eliminated => append it
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1973
  assert(i1->next() == NULL, "shouldn't already be linked");
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1974
  _last = _last->set_next(i1, canon.bci());
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1975
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1976
  if (++_instruction_count >= InstructionCountCutoff && !bailed_out()) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1977
    // set the bailout state but complete normal processing.  We
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1978
    // might do a little more work before noticing the bailout so we
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1979
    // want processing to continue normally until it's noticed.
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1980
    bailout("Method and/or inlining is too large");
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1981
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1982
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1983
#ifndef PRODUCT
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1984
  if (PrintIRDuringConstruction) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1985
    InstructionPrinter ip;
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1986
    ip.print_line(i1);
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1987
    if (Verbose) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1988
      state()->print();
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1989
    }
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1990
  }
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1991
#endif
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1992
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1993
  // save state after modification of operand stack for StateSplit instructions
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1994
  StateSplit* s = i1->as_StateSplit();
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1995
  if (s != NULL) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1996
    if (EliminateFieldAccess) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1997
      Intrinsic* intrinsic = s->as_Intrinsic();
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1998
      if (s->as_Invoke() != NULL || (intrinsic && !intrinsic->preserves_state())) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  1999
        _memory->kill();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2000
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2001
    }
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2002
    s->set_state(state()->copy(ValueStack::StateAfter, canon.bci()));
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2003
  }
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2004
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2005
  // set up exception handlers for this instruction if necessary
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2006
  if (i1->can_trap()) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2007
    i1->set_exception_handlers(handle_exception(i1));
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2008
    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
  2009
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2010
  return i1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2011
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2012
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2013
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2014
Instruction* GraphBuilder::append(Instruction* instr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2015
  assert(instr->as_StateSplit() == NULL || instr->as_BlockEnd() != NULL, "wrong append used");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2016
  return append_with_bci(instr, bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2017
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2018
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2019
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2020
Instruction* GraphBuilder::append_split(StateSplit* instr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2021
  return append_with_bci(instr, bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2022
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2023
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2024
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2025
void GraphBuilder::null_check(Value value) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2026
  if (value->as_NewArray() != NULL || value->as_NewInstance() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2027
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2028
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2029
    Constant* con = value->as_Constant();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2030
    if (con) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2031
      ObjectType* c = con->type()->as_ObjectType();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2032
      if (c && c->is_loaded()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2033
        ObjectConstant* oc = c->as_ObjectConstant();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2034
        if (!oc || !oc->value()->is_null_object()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2035
          return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2036
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2037
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2038
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2039
  }
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2040
  append(new NullCheck(value, copy_state_for_exception()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2041
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2042
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2043
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2044
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2045
XHandlers* GraphBuilder::handle_exception(Instruction* instruction) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2046
  if (!has_handler() && (!instruction->needs_exception_state() || instruction->exception_state() != NULL)) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2047
    assert(instruction->exception_state() == NULL
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2048
           || instruction->exception_state()->kind() == ValueStack::EmptyExceptionState
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2049
           || (instruction->exception_state()->kind() == ValueStack::ExceptionState && _compilation->env()->jvmti_can_access_local_variables()),
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2050
           "exception_state should be of exception kind");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2051
    return new XHandlers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2052
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2053
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2054
  XHandlers*  exception_handlers = new XHandlers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2055
  ScopeData*  cur_scope_data = scope_data();
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2056
  ValueStack* cur_state = instruction->state_before();
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2057
  ValueStack* prev_state = NULL;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2058
  int scope_count = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2059
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2060
  assert(cur_state != NULL, "state_before must be set");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2061
  do {
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2062
    int cur_bci = cur_state->bci();
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2063
    assert(cur_scope_data->scope() == cur_state->scope(), "scopes do not match");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2064
    assert(cur_bci == SynchronizationEntryBCI || cur_bci == cur_scope_data->stream()->cur_bci(), "invalid bci");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2065
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2066
    // join with all potential exception handlers
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2067
    XHandlers* list = cur_scope_data->xhandlers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2068
    const int n = list->length();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2069
    for (int i = 0; i < n; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2070
      XHandler* h = list->handler_at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2071
      if (h->covers(cur_bci)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2072
        // h is a potential exception handler => join it
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2073
        compilation()->set_has_exception_handlers(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2074
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2075
        BlockBegin* entry = h->entry_block();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2076
        if (entry == block()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2077
          // It's acceptable for an exception handler to cover itself
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2078
          // but we don't handle that in the parser currently.  It's
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2079
          // very rare so we bailout instead of trying to handle it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2080
          BAILOUT_("exception handler covers itself", exception_handlers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2081
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2082
        assert(entry->bci() == h->handler_bci(), "must match");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2083
        assert(entry->bci() == -1 || entry == cur_scope_data->block_at(entry->bci()), "blocks must correspond");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2084
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2085
        // previously this was a BAILOUT, but this is not necessary
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2086
        // now because asynchronous exceptions are not handled this way.
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2087
        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
  2088
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2089
        // xhandler start with an empty expression stack
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2090
        if (cur_state->stack_size() != 0) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2091
          cur_state = cur_state->copy(ValueStack::ExceptionState, cur_state->bci());
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2092
        }
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2093
        if (instruction->exception_state() == NULL) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2094
          instruction->set_exception_state(cur_state);
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2095
        }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2096
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2097
        // Note: Usually this join must work. However, very
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2098
        // complicated jsr-ret structures where we don't ret from
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2099
        // the subroutine can cause the objects on the monitor
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2100
        // stacks to not match because blocks can be parsed twice.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2101
        // The only test case we've seen so far which exhibits this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2102
        // problem is caught by the infinite recursion test in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2103
        // GraphBuilder::jsr() if the join doesn't work.
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2104
        if (!entry->try_merge(cur_state)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2105
          BAILOUT_("error while joining with exception handler, prob. due to complicated jsr/rets", exception_handlers);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2106
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2107
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2108
        // add current state for correct handling of phi functions at begin of xhandler
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2109
        int phi_operand = entry->add_exception_state(cur_state);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2110
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2111
        // add entry to the list of xhandlers of this block
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2112
        _block->add_exception_handler(entry);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2113
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2114
        // add back-edge from xhandler entry to this block
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2115
        if (!entry->is_predecessor(_block)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2116
          entry->add_predecessor(_block);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2117
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2118
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2119
        // clone XHandler because phi_operand and scope_count can not be shared
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2120
        XHandler* new_xhandler = new XHandler(h);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2121
        new_xhandler->set_phi_operand(phi_operand);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2122
        new_xhandler->set_scope_count(scope_count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2123
        exception_handlers->append(new_xhandler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2124
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2125
        // fill in exception handler subgraph lazily
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2126
        assert(!entry->is_set(BlockBegin::was_visited_flag), "entry must not be visited yet");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2127
        cur_scope_data->add_to_work_list(entry);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2128
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2129
        // stop when reaching catchall
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2130
        if (h->catch_type() == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2131
          return exception_handlers;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2132
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2133
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2134
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2135
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2136
    if (exception_handlers->length() == 0) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2137
      // This scope and all callees do not handle exceptions, so the local
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2138
      // variables of this scope are not needed. However, the scope itself is
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2139
      // required for a correct exception stack trace -> clear out the locals.
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2140
      if (_compilation->env()->jvmti_can_access_local_variables()) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2141
        cur_state = cur_state->copy(ValueStack::ExceptionState, cur_state->bci());
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2142
      } else {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2143
        cur_state = cur_state->copy(ValueStack::EmptyExceptionState, cur_state->bci());
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2144
      }
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2145
      if (prev_state != NULL) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2146
        prev_state->set_caller_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
      if (instruction->exception_state() == NULL) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2149
        instruction->set_exception_state(cur_state);
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2150
      }
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2151
    }
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2152
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2153
    // Set up iteration for next time.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2154
    // If parsing a jsr, do not grab exception handlers from the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2155
    // parent scopes for this method (already got them, and they
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2156
    // needed to be cloned)
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2157
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2158
    while (cur_scope_data->parsing_jsr()) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2159
      cur_scope_data = cur_scope_data->parent();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2160
    }
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2161
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2162
    assert(cur_scope_data->scope() == cur_state->scope(), "scopes do not match");
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2163
    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
  2164
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2165
    prev_state = cur_state;
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2166
    cur_state = cur_state->caller_state();
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2167
    cur_scope_data = cur_scope_data->parent();
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2168
    scope_count++;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2169
  } while (cur_scope_data != NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2170
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2171
  return exception_handlers;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2172
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2173
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2174
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2175
// Helper class for simplifying Phis.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2176
class PhiSimplifier : public BlockClosure {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2177
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2178
  bool _has_substitutions;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2179
  Value simplify(Value v);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2180
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2181
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2182
  PhiSimplifier(BlockBegin* start) : _has_substitutions(false) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2183
    start->iterate_preorder(this);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2184
    if (_has_substitutions) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2185
      SubstitutionResolver sr(start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2186
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2187
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2188
  void block_do(BlockBegin* b);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2189
  bool has_substitutions() const { return _has_substitutions; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2190
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2191
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2192
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2193
Value PhiSimplifier::simplify(Value v) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2194
  Phi* phi = v->as_Phi();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2195
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2196
  if (phi == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2197
    // no phi function
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2198
    return v;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2199
  } else if (v->has_subst()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2200
    // already substituted; subst can be phi itself -> simplify
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2201
    return simplify(v->subst());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2202
  } else if (phi->is_set(Phi::cannot_simplify)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2203
    // already tried to simplify phi before
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2204
    return phi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2205
  } else if (phi->is_set(Phi::visited)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2206
    // break cycles in phi functions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2207
    return phi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2208
  } else if (phi->type()->is_illegal()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2209
    // illegal phi functions are ignored anyway
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2210
    return phi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2211
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2212
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2213
    // mark phi function as processed to break cycles in phi functions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2214
    phi->set(Phi::visited);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2215
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2216
    // simplify x = [y, x] and x = [y, y] to y
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2217
    Value subst = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2218
    int opd_count = phi->operand_count();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2219
    for (int i = 0; i < opd_count; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2220
      Value opd = phi->operand_at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2221
      assert(opd != NULL, "Operand must exist!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2222
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2223
      if (opd->type()->is_illegal()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2224
        // if one operand is illegal, the entire phi function is illegal
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2225
        phi->make_illegal();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2226
        phi->clear(Phi::visited);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2227
        return phi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2228
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2229
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2230
      Value new_opd = simplify(opd);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2231
      assert(new_opd != NULL, "Simplified operand must exist!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2232
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2233
      if (new_opd != phi && new_opd != subst) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2234
        if (subst == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2235
          subst = new_opd;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2236
        } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2237
          // no simplification possible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2238
          phi->set(Phi::cannot_simplify);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2239
          phi->clear(Phi::visited);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2240
          return phi;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2241
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2242
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2243
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2244
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2245
    // sucessfully simplified phi function
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2246
    assert(subst != NULL, "illegal phi function");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2247
    _has_substitutions = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2248
    phi->clear(Phi::visited);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2249
    phi->set_subst(subst);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2250
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2251
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2252
    if (PrintPhiFunctions) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2253
      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
  2254
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2255
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2256
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2257
    return subst;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2258
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2259
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2260
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2261
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2262
void PhiSimplifier::block_do(BlockBegin* b) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2263
  for_each_phi_fun(b, phi,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2264
    simplify(phi);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2265
  );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2266
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2267
#ifdef ASSERT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2268
  for_each_phi_fun(b, phi,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2269
                   assert(phi->operand_count() != 1 || phi->subst() != phi, "missed trivial simplification");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2270
  );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2271
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2272
  ValueStack* state = b->state()->caller_state();
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2273
  for_each_state_value(state, value,
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2274
    Phi* phi = value->as_Phi();
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2275
    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
  2276
  );
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2277
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2278
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2279
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2280
// This method is called after all blocks are filled with HIR instructions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2281
// It eliminates all Phi functions of the form x = [y, y] and x = [y, x]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2282
void GraphBuilder::eliminate_redundant_phis(BlockBegin* start) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2283
  PhiSimplifier simplifier(start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2284
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2285
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2286
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2287
void GraphBuilder::connect_to_end(BlockBegin* beg) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2288
  // setup iteration
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2289
  kill_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2290
  _block = beg;
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2291
  _state = beg->state()->copy_for_parsing();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2292
  _last  = beg;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2293
  iterate_bytecodes_for_block(beg->bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2294
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2295
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2296
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2297
BlockEnd* GraphBuilder::iterate_bytecodes_for_block(int bci) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2298
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2299
  if (PrintIRDuringConstruction) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2300
    tty->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2301
    InstructionPrinter ip;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2302
    ip.print_instr(_block); tty->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2303
    ip.print_stack(_block->state()); tty->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2304
    ip.print_inline_level(_block);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2305
    ip.print_head();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2306
    tty->print_cr("locals size: %d stack size: %d", state()->locals_size(), state()->stack_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2307
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2308
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2309
  _skip_block = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2310
  assert(state() != NULL, "ValueStack missing!");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2311
  ciBytecodeStream s(method());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2312
  s.reset_to_bci(bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2313
  int prev_bci = bci;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2314
  scope_data()->set_stream(&s);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2315
  // iterate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2316
  Bytecodes::Code code = Bytecodes::_illegal;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2317
  bool push_exception = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2318
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2319
  if (block()->is_set(BlockBegin::exception_entry_flag) && block()->next() == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2320
    // first thing in the exception entry block should be the exception object.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2321
    push_exception = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2322
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2323
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2324
  while (!bailed_out() && last()->as_BlockEnd() == NULL &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2325
         (code = stream()->next()) != ciBytecodeStream::EOBC() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2326
         (block_at(s.cur_bci()) == NULL || block_at(s.cur_bci()) == block())) {
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2327
    assert(state()->kind() == ValueStack::Parsing, "invalid state kind");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2328
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2329
    // Check for active jsr during OSR compilation
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2330
    if (compilation()->is_osr_compile()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2331
        && scope()->is_top_scope()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2332
        && parsing_jsr()
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2333
        && s.cur_bci() == compilation()->osr_bci()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2334
      bailout("OSR not supported while a jsr is active");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2335
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2336
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2337
    if (push_exception) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2338
      apush(append(new ExceptionObject()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2339
      push_exception = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2340
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2341
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2342
    // handle bytecode
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2343
    switch (code) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2344
      case Bytecodes::_nop            : /* nothing to do */ break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2345
      case Bytecodes::_aconst_null    : apush(append(new Constant(objectNull            ))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2346
      case Bytecodes::_iconst_m1      : ipush(append(new Constant(new IntConstant   (-1)))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2347
      case Bytecodes::_iconst_0       : ipush(append(new Constant(intZero               ))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2348
      case Bytecodes::_iconst_1       : ipush(append(new Constant(intOne                ))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2349
      case Bytecodes::_iconst_2       : ipush(append(new Constant(new IntConstant   ( 2)))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2350
      case Bytecodes::_iconst_3       : ipush(append(new Constant(new IntConstant   ( 3)))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2351
      case Bytecodes::_iconst_4       : ipush(append(new Constant(new IntConstant   ( 4)))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2352
      case Bytecodes::_iconst_5       : ipush(append(new Constant(new IntConstant   ( 5)))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2353
      case Bytecodes::_lconst_0       : lpush(append(new Constant(new LongConstant  ( 0)))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2354
      case Bytecodes::_lconst_1       : lpush(append(new Constant(new LongConstant  ( 1)))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2355
      case Bytecodes::_fconst_0       : fpush(append(new Constant(new FloatConstant ( 0)))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2356
      case Bytecodes::_fconst_1       : fpush(append(new Constant(new FloatConstant ( 1)))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2357
      case Bytecodes::_fconst_2       : fpush(append(new Constant(new FloatConstant ( 2)))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2358
      case Bytecodes::_dconst_0       : dpush(append(new Constant(new DoubleConstant( 0)))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2359
      case Bytecodes::_dconst_1       : dpush(append(new Constant(new DoubleConstant( 1)))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2360
      case Bytecodes::_bipush         : ipush(append(new Constant(new IntConstant(((signed char*)s.cur_bcp())[1])))); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2361
      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
  2362
      case Bytecodes::_ldc            : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2363
      case Bytecodes::_ldc_w          : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2364
      case Bytecodes::_ldc2_w         : load_constant(); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2365
      case Bytecodes::_iload          : load_local(intType     , s.get_index()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2366
      case Bytecodes::_lload          : load_local(longType    , s.get_index()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2367
      case Bytecodes::_fload          : load_local(floatType   , s.get_index()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2368
      case Bytecodes::_dload          : load_local(doubleType  , s.get_index()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2369
      case Bytecodes::_aload          : load_local(instanceType, s.get_index()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2370
      case Bytecodes::_iload_0        : load_local(intType   , 0); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2371
      case Bytecodes::_iload_1        : load_local(intType   , 1); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2372
      case Bytecodes::_iload_2        : load_local(intType   , 2); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2373
      case Bytecodes::_iload_3        : load_local(intType   , 3); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2374
      case Bytecodes::_lload_0        : load_local(longType  , 0); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2375
      case Bytecodes::_lload_1        : load_local(longType  , 1); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2376
      case Bytecodes::_lload_2        : load_local(longType  , 2); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2377
      case Bytecodes::_lload_3        : load_local(longType  , 3); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2378
      case Bytecodes::_fload_0        : load_local(floatType , 0); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2379
      case Bytecodes::_fload_1        : load_local(floatType , 1); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2380
      case Bytecodes::_fload_2        : load_local(floatType , 2); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2381
      case Bytecodes::_fload_3        : load_local(floatType , 3); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2382
      case Bytecodes::_dload_0        : load_local(doubleType, 0); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2383
      case Bytecodes::_dload_1        : load_local(doubleType, 1); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2384
      case Bytecodes::_dload_2        : load_local(doubleType, 2); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2385
      case Bytecodes::_dload_3        : load_local(doubleType, 3); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2386
      case Bytecodes::_aload_0        : load_local(objectType, 0); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2387
      case Bytecodes::_aload_1        : load_local(objectType, 1); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2388
      case Bytecodes::_aload_2        : load_local(objectType, 2); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2389
      case Bytecodes::_aload_3        : load_local(objectType, 3); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2390
      case Bytecodes::_iaload         : load_indexed(T_INT   ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2391
      case Bytecodes::_laload         : load_indexed(T_LONG  ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2392
      case Bytecodes::_faload         : load_indexed(T_FLOAT ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2393
      case Bytecodes::_daload         : load_indexed(T_DOUBLE); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2394
      case Bytecodes::_aaload         : load_indexed(T_OBJECT); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2395
      case Bytecodes::_baload         : load_indexed(T_BYTE  ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2396
      case Bytecodes::_caload         : load_indexed(T_CHAR  ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2397
      case Bytecodes::_saload         : load_indexed(T_SHORT ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2398
      case Bytecodes::_istore         : store_local(intType   , s.get_index()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2399
      case Bytecodes::_lstore         : store_local(longType  , s.get_index()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2400
      case Bytecodes::_fstore         : store_local(floatType , s.get_index()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2401
      case Bytecodes::_dstore         : store_local(doubleType, s.get_index()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2402
      case Bytecodes::_astore         : store_local(objectType, s.get_index()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2403
      case Bytecodes::_istore_0       : store_local(intType   , 0); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2404
      case Bytecodes::_istore_1       : store_local(intType   , 1); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2405
      case Bytecodes::_istore_2       : store_local(intType   , 2); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2406
      case Bytecodes::_istore_3       : store_local(intType   , 3); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2407
      case Bytecodes::_lstore_0       : store_local(longType  , 0); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2408
      case Bytecodes::_lstore_1       : store_local(longType  , 1); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2409
      case Bytecodes::_lstore_2       : store_local(longType  , 2); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2410
      case Bytecodes::_lstore_3       : store_local(longType  , 3); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2411
      case Bytecodes::_fstore_0       : store_local(floatType , 0); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2412
      case Bytecodes::_fstore_1       : store_local(floatType , 1); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2413
      case Bytecodes::_fstore_2       : store_local(floatType , 2); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2414
      case Bytecodes::_fstore_3       : store_local(floatType , 3); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2415
      case Bytecodes::_dstore_0       : store_local(doubleType, 0); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2416
      case Bytecodes::_dstore_1       : store_local(doubleType, 1); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2417
      case Bytecodes::_dstore_2       : store_local(doubleType, 2); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2418
      case Bytecodes::_dstore_3       : store_local(doubleType, 3); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2419
      case Bytecodes::_astore_0       : store_local(objectType, 0); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2420
      case Bytecodes::_astore_1       : store_local(objectType, 1); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2421
      case Bytecodes::_astore_2       : store_local(objectType, 2); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2422
      case Bytecodes::_astore_3       : store_local(objectType, 3); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2423
      case Bytecodes::_iastore        : store_indexed(T_INT   ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2424
      case Bytecodes::_lastore        : store_indexed(T_LONG  ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2425
      case Bytecodes::_fastore        : store_indexed(T_FLOAT ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2426
      case Bytecodes::_dastore        : store_indexed(T_DOUBLE); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2427
      case Bytecodes::_aastore        : store_indexed(T_OBJECT); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2428
      case Bytecodes::_bastore        : store_indexed(T_BYTE  ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2429
      case Bytecodes::_castore        : store_indexed(T_CHAR  ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2430
      case Bytecodes::_sastore        : store_indexed(T_SHORT ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2431
      case Bytecodes::_pop            : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2432
      case Bytecodes::_pop2           : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2433
      case Bytecodes::_dup            : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2434
      case Bytecodes::_dup_x1         : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2435
      case Bytecodes::_dup_x2         : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2436
      case Bytecodes::_dup2           : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2437
      case Bytecodes::_dup2_x1        : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2438
      case Bytecodes::_dup2_x2        : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2439
      case Bytecodes::_swap           : stack_op(code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2440
      case Bytecodes::_iadd           : arithmetic_op(intType   , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2441
      case Bytecodes::_ladd           : arithmetic_op(longType  , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2442
      case Bytecodes::_fadd           : arithmetic_op(floatType , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2443
      case Bytecodes::_dadd           : arithmetic_op(doubleType, code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2444
      case Bytecodes::_isub           : arithmetic_op(intType   , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2445
      case Bytecodes::_lsub           : arithmetic_op(longType  , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2446
      case Bytecodes::_fsub           : arithmetic_op(floatType , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2447
      case Bytecodes::_dsub           : arithmetic_op(doubleType, code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2448
      case Bytecodes::_imul           : arithmetic_op(intType   , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2449
      case Bytecodes::_lmul           : arithmetic_op(longType  , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2450
      case Bytecodes::_fmul           : arithmetic_op(floatType , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2451
      case Bytecodes::_dmul           : arithmetic_op(doubleType, code); break;
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2452
      case Bytecodes::_idiv           : arithmetic_op(intType   , code, copy_state_for_exception()); break;
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2453
      case Bytecodes::_ldiv           : arithmetic_op(longType  , code, copy_state_for_exception()); break;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2454
      case Bytecodes::_fdiv           : arithmetic_op(floatType , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2455
      case Bytecodes::_ddiv           : arithmetic_op(doubleType, code); break;
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2456
      case Bytecodes::_irem           : arithmetic_op(intType   , code, copy_state_for_exception()); break;
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2457
      case Bytecodes::_lrem           : arithmetic_op(longType  , code, copy_state_for_exception()); break;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2458
      case Bytecodes::_frem           : arithmetic_op(floatType , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2459
      case Bytecodes::_drem           : arithmetic_op(doubleType, code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2460
      case Bytecodes::_ineg           : negate_op(intType   ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2461
      case Bytecodes::_lneg           : negate_op(longType  ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2462
      case Bytecodes::_fneg           : negate_op(floatType ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2463
      case Bytecodes::_dneg           : negate_op(doubleType); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2464
      case Bytecodes::_ishl           : shift_op(intType , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2465
      case Bytecodes::_lshl           : shift_op(longType, code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2466
      case Bytecodes::_ishr           : shift_op(intType , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2467
      case Bytecodes::_lshr           : shift_op(longType, code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2468
      case Bytecodes::_iushr          : shift_op(intType , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2469
      case Bytecodes::_lushr          : shift_op(longType, code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2470
      case Bytecodes::_iand           : logic_op(intType , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2471
      case Bytecodes::_land           : logic_op(longType, code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2472
      case Bytecodes::_ior            : logic_op(intType , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2473
      case Bytecodes::_lor            : logic_op(longType, code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2474
      case Bytecodes::_ixor           : logic_op(intType , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2475
      case Bytecodes::_lxor           : logic_op(longType, code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2476
      case Bytecodes::_iinc           : increment(); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2477
      case Bytecodes::_i2l            : convert(code, T_INT   , T_LONG  ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2478
      case Bytecodes::_i2f            : convert(code, T_INT   , T_FLOAT ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2479
      case Bytecodes::_i2d            : convert(code, T_INT   , T_DOUBLE); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2480
      case Bytecodes::_l2i            : convert(code, T_LONG  , T_INT   ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2481
      case Bytecodes::_l2f            : convert(code, T_LONG  , T_FLOAT ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2482
      case Bytecodes::_l2d            : convert(code, T_LONG  , T_DOUBLE); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2483
      case Bytecodes::_f2i            : convert(code, T_FLOAT , T_INT   ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2484
      case Bytecodes::_f2l            : convert(code, T_FLOAT , T_LONG  ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2485
      case Bytecodes::_f2d            : convert(code, T_FLOAT , T_DOUBLE); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2486
      case Bytecodes::_d2i            : convert(code, T_DOUBLE, T_INT   ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2487
      case Bytecodes::_d2l            : convert(code, T_DOUBLE, T_LONG  ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2488
      case Bytecodes::_d2f            : convert(code, T_DOUBLE, T_FLOAT ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2489
      case Bytecodes::_i2b            : convert(code, T_INT   , T_BYTE  ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2490
      case Bytecodes::_i2c            : convert(code, T_INT   , T_CHAR  ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2491
      case Bytecodes::_i2s            : convert(code, T_INT   , T_SHORT ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2492
      case Bytecodes::_lcmp           : compare_op(longType  , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2493
      case Bytecodes::_fcmpl          : compare_op(floatType , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2494
      case Bytecodes::_fcmpg          : compare_op(floatType , code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2495
      case Bytecodes::_dcmpl          : compare_op(doubleType, code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2496
      case Bytecodes::_dcmpg          : compare_op(doubleType, code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2497
      case Bytecodes::_ifeq           : if_zero(intType   , If::eql); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2498
      case Bytecodes::_ifne           : if_zero(intType   , If::neq); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2499
      case Bytecodes::_iflt           : if_zero(intType   , If::lss); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2500
      case Bytecodes::_ifge           : if_zero(intType   , If::geq); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2501
      case Bytecodes::_ifgt           : if_zero(intType   , If::gtr); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2502
      case Bytecodes::_ifle           : if_zero(intType   , If::leq); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2503
      case Bytecodes::_if_icmpeq      : if_same(intType   , If::eql); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2504
      case Bytecodes::_if_icmpne      : if_same(intType   , If::neq); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2505
      case Bytecodes::_if_icmplt      : if_same(intType   , If::lss); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2506
      case Bytecodes::_if_icmpge      : if_same(intType   , If::geq); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2507
      case Bytecodes::_if_icmpgt      : if_same(intType   , If::gtr); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2508
      case Bytecodes::_if_icmple      : if_same(intType   , If::leq); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2509
      case Bytecodes::_if_acmpeq      : if_same(objectType, If::eql); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2510
      case Bytecodes::_if_acmpne      : if_same(objectType, If::neq); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2511
      case Bytecodes::_goto           : _goto(s.cur_bci(), s.get_dest()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2512
      case Bytecodes::_jsr            : jsr(s.get_dest()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2513
      case Bytecodes::_ret            : ret(s.get_index()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2514
      case Bytecodes::_tableswitch    : table_switch(); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2515
      case Bytecodes::_lookupswitch   : lookup_switch(); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2516
      case Bytecodes::_ireturn        : method_return(ipop()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2517
      case Bytecodes::_lreturn        : method_return(lpop()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2518
      case Bytecodes::_freturn        : method_return(fpop()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2519
      case Bytecodes::_dreturn        : method_return(dpop()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2520
      case Bytecodes::_areturn        : method_return(apop()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2521
      case Bytecodes::_return         : method_return(NULL  ); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2522
      case Bytecodes::_getstatic      : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2523
      case Bytecodes::_putstatic      : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2524
      case Bytecodes::_getfield       : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2525
      case Bytecodes::_putfield       : access_field(code); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2526
      case Bytecodes::_invokevirtual  : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2527
      case Bytecodes::_invokespecial  : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2528
      case Bytecodes::_invokestatic   : // fall through
2570
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 1623
diff changeset
  2529
      case Bytecodes::_invokedynamic  : // fall through
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2530
      case Bytecodes::_invokeinterface: invoke(code); break;
5688
9052dc91ea67 6939207: refactor constant pool index processing
jrose
parents: 5535
diff changeset
  2531
      case Bytecodes::_new            : new_instance(s.get_index_u2()); break;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2532
      case Bytecodes::_newarray       : new_type_array(); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2533
      case Bytecodes::_anewarray      : new_object_array(); break;
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2534
      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
  2535
      case Bytecodes::_athrow         : throw_op(s.cur_bci()); break;
5688
9052dc91ea67 6939207: refactor constant pool index processing
jrose
parents: 5535
diff changeset
  2536
      case Bytecodes::_checkcast      : check_cast(s.get_index_u2()); break;
9052dc91ea67 6939207: refactor constant pool index processing
jrose
parents: 5535
diff changeset
  2537
      case Bytecodes::_instanceof     : instance_of(s.get_index_u2()); break;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2538
      case Bytecodes::_monitorenter   : monitorenter(apop(), s.cur_bci()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2539
      case Bytecodes::_monitorexit    : monitorexit (apop(), s.cur_bci()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2540
      case Bytecodes::_wide           : ShouldNotReachHere(); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2541
      case Bytecodes::_multianewarray : new_multi_array(s.cur_bcp()[3]); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2542
      case Bytecodes::_ifnull         : if_null(objectType, If::eql); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2543
      case Bytecodes::_ifnonnull      : if_null(objectType, If::neq); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2544
      case Bytecodes::_goto_w         : _goto(s.cur_bci(), s.get_far_dest()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2545
      case Bytecodes::_jsr_w          : jsr(s.get_far_dest()); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2546
      case Bytecodes::_breakpoint     : BAILOUT_("concurrent setting of breakpoint", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2547
      default                         : ShouldNotReachHere(); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2548
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2549
    // save current bci to setup Goto at the end
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2550
    prev_bci = s.cur_bci();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2551
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2552
  CHECK_BAILOUT_(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2553
  // stop processing of this block (see try_inline_full)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2554
  if (_skip_block) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2555
    _skip_block = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2556
    assert(_last && _last->as_BlockEnd(), "");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2557
    return _last->as_BlockEnd();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2558
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2559
  // if there are any, check if last instruction is a BlockEnd instruction
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2560
  BlockEnd* end = last()->as_BlockEnd();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2561
  if (end == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2562
    // all blocks must end with a BlockEnd instruction => add a Goto
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2563
    end = new Goto(block_at(s.cur_bci()), false);
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2564
    append(end);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2565
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2566
  assert(end == last()->as_BlockEnd(), "inconsistency");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2567
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2568
  assert(end->state() != NULL, "state must already be present");
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2569
  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
  2570
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2571
  // connect to begin & set state
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2572
  // NOTE that inlining may have changed the block we are parsing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2573
  block()->set_end(end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2574
  // propagate state
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2575
  for (int i = end->number_of_sux() - 1; i >= 0; i--) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2576
    BlockBegin* sux = end->sux_at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2577
    assert(sux->is_predecessor(block()), "predecessor missing");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2578
    // be careful, bailout if bytecodes are strange
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2579
    if (!sux->try_merge(end->state())) BAILOUT_("block join failed", NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2580
    scope_data()->add_to_work_list(end->sux_at(i));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2581
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2582
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2583
  scope_data()->set_stream(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2584
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2585
  // done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2586
  return end;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2587
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2588
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2589
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2590
void GraphBuilder::iterate_all_blocks(bool start_in_current_block_for_inlining) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2591
  do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2592
    if (start_in_current_block_for_inlining && !bailed_out()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2593
      iterate_bytecodes_for_block(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2594
      start_in_current_block_for_inlining = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2595
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2596
      BlockBegin* b;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2597
      while ((b = scope_data()->remove_from_work_list()) != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2598
        if (!b->is_set(BlockBegin::was_visited_flag)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2599
          if (b->is_set(BlockBegin::osr_entry_flag)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2600
            // we're about to parse the osr entry block, so make sure
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2601
            // we setup the OSR edge leading into this block so that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2602
            // Phis get setup correctly.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2603
            setup_osr_entry_block();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2604
            // this is no longer the osr entry block, so clear it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2605
            b->clear(BlockBegin::osr_entry_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2606
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2607
          b->set(BlockBegin::was_visited_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2608
          connect_to_end(b);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2609
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2610
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2611
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2612
  } while (!bailed_out() && !scope_data()->is_work_list_empty());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2613
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2614
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2615
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2616
bool GraphBuilder::_can_trap      [Bytecodes::number_of_java_codes];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2617
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2618
void GraphBuilder::initialize() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2619
  // the following bytecodes are assumed to potentially
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2620
  // throw exceptions in compiled code - note that e.g.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2621
  // monitorexit & the return bytecodes do not throw
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2622
  // exceptions since monitor pairing proved that they
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2623
  // succeed (if monitor pairing succeeded)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2624
  Bytecodes::Code can_trap_list[] =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2625
    { Bytecodes::_ldc
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2626
    , Bytecodes::_ldc_w
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2627
    , Bytecodes::_ldc2_w
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2628
    , Bytecodes::_iaload
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2629
    , Bytecodes::_laload
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2630
    , Bytecodes::_faload
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2631
    , Bytecodes::_daload
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2632
    , Bytecodes::_aaload
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2633
    , Bytecodes::_baload
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2634
    , Bytecodes::_caload
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2635
    , Bytecodes::_saload
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2636
    , Bytecodes::_iastore
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2637
    , Bytecodes::_lastore
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2638
    , Bytecodes::_fastore
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2639
    , Bytecodes::_dastore
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2640
    , Bytecodes::_aastore
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2641
    , Bytecodes::_bastore
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2642
    , Bytecodes::_castore
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2643
    , Bytecodes::_sastore
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2644
    , Bytecodes::_idiv
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2645
    , Bytecodes::_ldiv
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2646
    , Bytecodes::_irem
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2647
    , Bytecodes::_lrem
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2648
    , Bytecodes::_getstatic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2649
    , Bytecodes::_putstatic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2650
    , Bytecodes::_getfield
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2651
    , Bytecodes::_putfield
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2652
    , Bytecodes::_invokevirtual
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2653
    , Bytecodes::_invokespecial
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2654
    , Bytecodes::_invokestatic
2570
ecc7862946d4 6655646: dynamic languages need dynamically linked call sites
jrose
parents: 1623
diff changeset
  2655
    , Bytecodes::_invokedynamic
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2656
    , Bytecodes::_invokeinterface
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2657
    , Bytecodes::_new
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2658
    , Bytecodes::_newarray
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2659
    , Bytecodes::_anewarray
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2660
    , Bytecodes::_arraylength
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2661
    , Bytecodes::_athrow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2662
    , Bytecodes::_checkcast
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2663
    , Bytecodes::_instanceof
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2664
    , Bytecodes::_monitorenter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2665
    , Bytecodes::_multianewarray
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2666
    };
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2667
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2668
  // inititialize trap tables
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2669
  for (int i = 0; i < Bytecodes::number_of_java_codes; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2670
    _can_trap[i] = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2671
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2672
  // set standard trap info
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2673
  for (uint j = 0; j < ARRAY_SIZE(can_trap_list); j++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2674
    _can_trap[can_trap_list[j]] = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2675
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2676
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2677
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2678
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2679
BlockBegin* GraphBuilder::header_block(BlockBegin* entry, BlockBegin::Flag f, ValueStack* state) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2680
  assert(entry->is_set(f), "entry/flag mismatch");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2681
  // create header block
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2682
  BlockBegin* h = new BlockBegin(entry->bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2683
  h->set_depth_first_number(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2684
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2685
  Value l = h;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2686
  BlockEnd* g = new Goto(entry, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2687
  l->set_next(g, entry->bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2688
  h->set_end(g);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2689
  h->set(f);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2690
  // setup header block end state
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2691
  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
  2692
  assert(s->stack_is_empty(), "must have empty stack at entry point");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2693
  g->set_state(s);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2694
  return h;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2695
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2696
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2697
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2698
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2699
BlockBegin* GraphBuilder::setup_start_block(int osr_bci, BlockBegin* std_entry, BlockBegin* osr_entry, ValueStack* state) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2700
  BlockBegin* start = new BlockBegin(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2701
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2702
  // This code eliminates the empty start block at the beginning of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2703
  // each method.  Previously, each method started with the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2704
  // start-block created below, and this block was followed by the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2705
  // header block that was always empty.  This header block is only
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2706
  // necesary if std_entry is also a backward branch target because
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2707
  // then phi functions may be necessary in the header block.  It's
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2708
  // also necessary when profiling so that there's a single block that
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2709
  // can increment the interpreter_invocation_count.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2710
  BlockBegin* new_header_block;
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  2711
  if (std_entry->number_of_preds() > 0 || count_invocations() || count_backedges()) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  2712
    new_header_block = header_block(std_entry, BlockBegin::std_entry_flag, state);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  2713
  } else {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2714
    new_header_block = std_entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2715
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2716
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2717
  // setup start block (root for the IR graph)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2718
  Base* base =
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2719
    new Base(
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2720
      new_header_block,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2721
      osr_entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2722
    );
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2723
  start->set_next(base, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2724
  start->set_end(base);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2725
  // create & setup state for start block
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2726
  start->set_state(state->copy(ValueStack::StateAfter, std_entry->bci()));
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2727
  base->set_state(state->copy(ValueStack::StateAfter, std_entry->bci()));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2728
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2729
  if (base->std_entry()->state() == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2730
    // setup states for header blocks
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2731
    base->std_entry()->merge(state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2732
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2733
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2734
  assert(base->std_entry()->state() != NULL, "");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2735
  return start;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2736
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2737
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2738
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2739
void GraphBuilder::setup_osr_entry_block() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2740
  assert(compilation()->is_osr_compile(), "only for osrs");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2741
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2742
  int osr_bci = compilation()->osr_bci();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2743
  ciBytecodeStream s(method());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2744
  s.reset_to_bci(osr_bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2745
  s.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2746
  scope_data()->set_stream(&s);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2747
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2748
  // create a new block to be the osr setup code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2749
  _osr_entry = new BlockBegin(osr_bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2750
  _osr_entry->set(BlockBegin::osr_entry_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2751
  _osr_entry->set_depth_first_number(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2752
  BlockBegin* target = bci2block()->at(osr_bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2753
  assert(target != NULL && target->is_set(BlockBegin::osr_entry_flag), "must be there");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2754
  // the osr entry has no values for locals
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2755
  ValueStack* state = target->state()->copy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2756
  _osr_entry->set_state(state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2757
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2758
  kill_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2759
  _block = _osr_entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2760
  _state = _osr_entry->state()->copy();
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2761
  assert(_state->bci() == osr_bci, "mismatch");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2762
  _last  = _osr_entry;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2763
  Value e = append(new OsrEntry());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2764
  e->set_needs_null_check(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2765
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2766
  // OSR buffer is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2767
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2768
  // locals[nlocals-1..0]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2769
  // monitors[number_of_locks-1..0]
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2770
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2771
  // locals is a direct copy of the interpreter frame so in the osr buffer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2772
  // so first slot in the local array is the last local from the interpreter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2773
  // and last slot is local[0] (receiver) from the interpreter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2774
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2775
  // Similarly with locks. The first lock slot in the osr buffer is the nth lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2776
  // from the interpreter frame, the nth lock slot in the osr buffer is 0th lock
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2777
  // in the interpreter frame (the method lock if a sync method)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2778
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2779
  // Initialize monitors in the compiled activation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2780
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2781
  int index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2782
  Value local;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2783
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2784
  // find all the locals that the interpreter thinks contain live oops
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2785
  const BitMap live_oops = method()->live_local_oops_at_bci(osr_bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2786
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2787
  // compute the offset into the locals so that we can treat the buffer
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2788
  // as if the locals were still in the interpreter frame
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2789
  int locals_offset = BytesPerWord * (method()->max_locals() - 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2790
  for_each_local_value(state, index, local) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2791
    int offset = locals_offset - (index + local->type()->size() - 1) * BytesPerWord;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2792
    Value get;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2793
    if (local->type()->is_object_kind() && !live_oops.at(index)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2794
      // The interpreter thinks this local is dead but the compiler
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2795
      // doesn't so pretend that the interpreter passed in null.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2796
      get = append(new Constant(objectNull));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2797
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2798
      get = append(new UnsafeGetRaw(as_BasicType(local->type()), e,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2799
                                    append(new Constant(new IntConstant(offset))),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2800
                                    0,
7427
d7b79a367474 6985015: C1 needs to support compressed oops
iveresov
parents: 7397
diff changeset
  2801
                                    true /*unaligned*/, true /*wide*/));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2802
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2803
    _state->store_local(index, get);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2804
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2805
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2806
  // the storage for the OSR buffer is freed manually in the LIRGenerator.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2807
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2808
  assert(state->caller_state() == NULL, "should be top scope");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2809
  state->clear_locals();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2810
  Goto* g = new Goto(target, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2811
  append(g);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2812
  _osr_entry->set_end(g);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2813
  target->merge(_osr_entry->end()->state());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2814
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2815
  scope_data()->set_stream(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2816
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2817
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2818
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2819
ValueStack* GraphBuilder::state_at_entry() {
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2820
  ValueStack* state = new ValueStack(scope(), NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2821
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2822
  // Set up locals for receiver
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2823
  int idx = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2824
  if (!method()->is_static()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2825
    // we should always see the receiver
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2826
    state->store_local(idx, new Local(objectType, idx));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2827
    idx = 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2828
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2829
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2830
  // Set up locals for incoming arguments
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2831
  ciSignature* sig = method()->signature();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2832
  for (int i = 0; i < sig->count(); i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2833
    ciType* type = sig->type_at(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2834
    BasicType basic_type = type->basic_type();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2835
    // don't allow T_ARRAY to propagate into locals types
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2836
    if (basic_type == T_ARRAY) basic_type = T_OBJECT;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2837
    ValueType* vt = as_ValueType(basic_type);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2838
    state->store_local(idx, new Local(vt, idx));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2839
    idx += type->size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2840
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2841
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2842
  // lock synchronized method
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2843
  if (method()->is_synchronized()) {
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2844
    state->lock(NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2845
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2846
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2847
  return state;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2848
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2849
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2850
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2851
GraphBuilder::GraphBuilder(Compilation* compilation, IRScope* scope)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2852
  : _scope_data(NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2853
  , _instruction_count(0)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2854
  , _osr_entry(NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2855
  , _memory(new MemoryBuffer())
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2856
  , _compilation(compilation)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2857
  , _inline_bailout_msg(NULL)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2858
{
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2859
  int osr_bci = compilation->osr_bci();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2860
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2861
  // determine entry points and bci2block mapping
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2862
  BlockListBuilder blm(compilation, scope, osr_bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2863
  CHECK_BAILOUT();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2864
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2865
  BlockList* bci2block = blm.bci2block();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2866
  BlockBegin* start_block = bci2block->at(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2867
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2868
  push_root_scope(scope, bci2block, start_block);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2869
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2870
  // setup state for std entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2871
  _initial_state = state_at_entry();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2872
  start_block->merge(_initial_state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2873
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2874
  // complete graph
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2875
  _vmap        = new ValueMap();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2876
  switch (scope->method()->intrinsic_id()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2877
  case vmIntrinsics::_dabs          : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2878
  case vmIntrinsics::_dsqrt         : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2879
  case vmIntrinsics::_dsin          : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2880
  case vmIntrinsics::_dcos          : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2881
  case vmIntrinsics::_dtan          : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2882
  case vmIntrinsics::_dlog          : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2883
  case vmIntrinsics::_dlog10        : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2884
    {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2885
      // Compiles where the root method is an intrinsic need a special
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2886
      // compilation environment because the bytecodes for the method
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2887
      // shouldn't be parsed during the compilation, only the special
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2888
      // Intrinsic node should be emitted.  If this isn't done the the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2889
      // code for the inlined version will be different than the root
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2890
      // compiled version which could lead to monotonicity problems on
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2891
      // intel.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2892
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2893
      // Set up a stream so that appending instructions works properly.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2894
      ciBytecodeStream s(scope->method());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2895
      s.reset_to_bci(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2896
      scope_data()->set_stream(&s);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2897
      s.next();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2898
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2899
      // setup the initial block state
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2900
      _block = start_block;
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2901
      _state = start_block->state()->copy_for_parsing();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2902
      _last  = start_block;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2903
      load_local(doubleType, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2904
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2905
      // Emit the intrinsic node.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2906
      bool result = try_inline_intrinsics(scope->method());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2907
      if (!result) BAILOUT("failed to inline intrinsic");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2908
      method_return(dpop());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2909
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2910
      // connect the begin and end blocks and we're all done.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2911
      BlockEnd* end = last()->as_BlockEnd();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2912
      block()->set_end(end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2913
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2914
    }
9176
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2915
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2916
  case vmIntrinsics::_Reference_get:
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2917
    {
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2918
      if (UseG1GC) {
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2919
        // With java.lang.ref.reference.get() we must go through the
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2920
        // intrinsic - when G1 is enabled - even when get() is the root
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2921
        // method of the compile so that, if necessary, the value in
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2922
        // the referent field of the reference object gets recorded by
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2923
        // the pre-barrier code.
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2924
        // Specifically, if G1 is enabled, the value in the referent
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2925
        // field is recorded by the G1 SATB pre barrier. This will
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2926
        // result in the referent being marked live and the reference
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2927
        // object removed from the list of discovered references during
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2928
        // reference processing.
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2929
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2930
        // Set up a stream so that appending instructions works properly.
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2931
        ciBytecodeStream s(scope->method());
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2932
        s.reset_to_bci(0);
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2933
        scope_data()->set_stream(&s);
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2934
        s.next();
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2935
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2936
        // setup the initial block state
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2937
        _block = start_block;
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2938
        _state = start_block->state()->copy_for_parsing();
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2939
        _last  = start_block;
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2940
        load_local(objectType, 0);
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2941
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2942
        // Emit the intrinsic node.
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2943
        bool result = try_inline_intrinsics(scope->method());
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2944
        if (!result) BAILOUT("failed to inline intrinsic");
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2945
        method_return(apop());
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2946
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2947
        // connect the begin and end blocks and we're all done.
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2948
        BlockEnd* end = last()->as_BlockEnd();
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2949
        block()->set_end(end);
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2950
        break;
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2951
      }
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2952
      // Otherwise, fall thru
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2953
    }
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  2954
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2955
  default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2956
    scope_data()->add_to_work_list(start_block);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2957
    iterate_all_blocks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2958
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2959
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2960
  CHECK_BAILOUT();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2961
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2962
  _start = setup_start_block(osr_bci, start_block, _osr_entry, _initial_state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2963
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2964
  eliminate_redundant_phis(_start);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2965
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2966
  NOT_PRODUCT(if (PrintValueNumbering && Verbose) print_stats());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2967
  // for osr compile, bailout if some requirements are not fulfilled
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2968
  if (osr_bci != -1) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2969
    BlockBegin* osr_block = blm.bci2block()->at(osr_bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2970
    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
  2971
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2972
    // 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
  2973
    if (!osr_block->state()->stack_is_empty()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2974
      BAILOUT("stack not empty at OSR entry point");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2975
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2976
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2977
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2978
  if (PrintCompilation && Verbose) tty->print_cr("Created %d Instructions", _instruction_count);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2979
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2980
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2981
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2982
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2983
ValueStack* GraphBuilder::copy_state_before() {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2984
  return copy_state_before_with_bci(bci());
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2985
}
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2986
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2987
ValueStack* GraphBuilder::copy_state_exhandling() {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2988
  return copy_state_exhandling_with_bci(bci());
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2989
}
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2990
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2991
ValueStack* GraphBuilder::copy_state_for_exception() {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2992
  return copy_state_for_exception_with_bci(bci());
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2993
}
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2994
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2995
ValueStack* GraphBuilder::copy_state_before_with_bci(int bci) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2996
  return state()->copy(ValueStack::StateBefore, bci);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2997
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  2998
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  2999
ValueStack* GraphBuilder::copy_state_exhandling_with_bci(int bci) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3000
  if (!has_handler()) return NULL;
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3001
  return state()->copy(ValueStack::StateBefore, bci);
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3002
}
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3003
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3004
ValueStack* GraphBuilder::copy_state_for_exception_with_bci(int bci) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3005
  ValueStack* s = copy_state_exhandling_with_bci(bci);
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3006
  if (s == NULL) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3007
    if (_compilation->env()->jvmti_can_access_local_variables()) {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3008
      s = state()->copy(ValueStack::ExceptionState, bci);
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3009
    } else {
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3010
      s = state()->copy(ValueStack::EmptyExceptionState, bci);
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3011
    }
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3012
  }
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3013
  return s;
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3014
}
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3015
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3016
int GraphBuilder::recursive_inline_level(ciMethod* cur_callee) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3017
  int recur_level = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3018
  for (IRScope* s = scope(); s != NULL; s = s->caller()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3019
    if (s->method() == cur_callee) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3020
      ++recur_level;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3021
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3022
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3023
  return recur_level;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3024
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3025
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3026
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3027
bool GraphBuilder::try_inline(ciMethod* callee, bool holder_known) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3028
  // Clear out any existing inline bailout condition
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3029
  clear_inline_bailout();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3030
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3031
  if (callee->should_exclude()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3032
    // callee is excluded
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3033
    INLINE_BAILOUT("excluded by CompilerOracle")
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3034
  } else if (!callee->can_be_compiled()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3035
    // callee is not compilable (prob. has breakpoints)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3036
    INLINE_BAILOUT("not compilable")
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3037
  } else if (callee->intrinsic_id() != vmIntrinsics::_none && try_inline_intrinsics(callee)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3038
    // intrinsics can be native or not
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3039
    return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3040
  } else if (callee->is_native()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3041
    // non-intrinsic natives cannot be inlined
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3042
    INLINE_BAILOUT("non-intrinsic native")
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3043
  } else if (callee->is_abstract()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3044
    INLINE_BAILOUT("abstract")
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3045
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3046
    return try_inline_full(callee, holder_known);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3047
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3048
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3049
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3050
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3051
bool GraphBuilder::try_inline_intrinsics(ciMethod* callee) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3052
  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
  3053
  if (callee->is_synchronized()) {
a747f18b3d7e 6953539: after 6892658 c1 reports that it doesn't inline StringBuffer.append
never
parents: 5353
diff changeset
  3054
    // 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
  3055
    return false;
a747f18b3d7e 6953539: after 6892658 c1 reports that it doesn't inline StringBuffer.append
never
parents: 5353
diff changeset
  3056
  }
a747f18b3d7e 6953539: after 6892658 c1 reports that it doesn't inline StringBuffer.append
never
parents: 5353
diff changeset
  3057
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3058
  // callee seems like a good candidate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3059
  // determine id
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3060
  bool preserves_state = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3061
  bool cantrap = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3062
  vmIntrinsics::ID id = callee->intrinsic_id();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3063
  switch (id) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3064
    case vmIntrinsics::_arraycopy     :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3065
      if (!InlineArrayCopy) return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3066
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3067
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3068
    case vmIntrinsics::_currentTimeMillis:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3069
    case vmIntrinsics::_nanoTime:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3070
      preserves_state = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3071
      cantrap = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3072
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3073
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3074
    case vmIntrinsics::_floatToRawIntBits   :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3075
    case vmIntrinsics::_intBitsToFloat      :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3076
    case vmIntrinsics::_doubleToRawLongBits :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3077
    case vmIntrinsics::_longBitsToDouble    :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3078
      if (!InlineMathNatives) return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3079
      preserves_state = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3080
      cantrap = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3081
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3082
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3083
    case vmIntrinsics::_getClass      :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3084
      if (!InlineClassNatives) return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3085
      preserves_state = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3086
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3087
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3088
    case vmIntrinsics::_currentThread :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3089
      if (!InlineThreadNatives) return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3090
      preserves_state = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3091
      cantrap = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3092
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3093
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3094
    case vmIntrinsics::_dabs          : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3095
    case vmIntrinsics::_dsqrt         : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3096
    case vmIntrinsics::_dsin          : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3097
    case vmIntrinsics::_dcos          : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3098
    case vmIntrinsics::_dtan          : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3099
    case vmIntrinsics::_dlog          : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3100
    case vmIntrinsics::_dlog10        : // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3101
      if (!InlineMathNatives) return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3102
      cantrap = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3103
      preserves_state = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3104
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3105
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3106
    // sun/misc/AtomicLong.attemptUpdate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3107
    case vmIntrinsics::_attemptUpdate :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3108
      if (!VM_Version::supports_cx8()) return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3109
      if (!InlineAtomicLong) return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3110
      preserves_state = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3111
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3112
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3113
    // Use special nodes for Unsafe instructions so we can more easily
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3114
    // perform an address-mode optimization on the raw variants
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3115
    case vmIntrinsics::_getObject : return append_unsafe_get_obj(callee, T_OBJECT,  false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3116
    case vmIntrinsics::_getBoolean: return append_unsafe_get_obj(callee, T_BOOLEAN, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3117
    case vmIntrinsics::_getByte   : return append_unsafe_get_obj(callee, T_BYTE,    false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3118
    case vmIntrinsics::_getShort  : return append_unsafe_get_obj(callee, T_SHORT,   false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3119
    case vmIntrinsics::_getChar   : return append_unsafe_get_obj(callee, T_CHAR,    false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3120
    case vmIntrinsics::_getInt    : return append_unsafe_get_obj(callee, T_INT,     false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3121
    case vmIntrinsics::_getLong   : return append_unsafe_get_obj(callee, T_LONG,    false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3122
    case vmIntrinsics::_getFloat  : return append_unsafe_get_obj(callee, T_FLOAT,   false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3123
    case vmIntrinsics::_getDouble : return append_unsafe_get_obj(callee, T_DOUBLE,  false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3124
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3125
    case vmIntrinsics::_putObject : return append_unsafe_put_obj(callee, T_OBJECT,  false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3126
    case vmIntrinsics::_putBoolean: return append_unsafe_put_obj(callee, T_BOOLEAN, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3127
    case vmIntrinsics::_putByte   : return append_unsafe_put_obj(callee, T_BYTE,    false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3128
    case vmIntrinsics::_putShort  : return append_unsafe_put_obj(callee, T_SHORT,   false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3129
    case vmIntrinsics::_putChar   : return append_unsafe_put_obj(callee, T_CHAR,    false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3130
    case vmIntrinsics::_putInt    : return append_unsafe_put_obj(callee, T_INT,     false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3131
    case vmIntrinsics::_putLong   : return append_unsafe_put_obj(callee, T_LONG,    false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3132
    case vmIntrinsics::_putFloat  : return append_unsafe_put_obj(callee, T_FLOAT,   false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3133
    case vmIntrinsics::_putDouble : return append_unsafe_put_obj(callee, T_DOUBLE,  false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3134
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3135
    case vmIntrinsics::_getObjectVolatile : return append_unsafe_get_obj(callee, T_OBJECT,  true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3136
    case vmIntrinsics::_getBooleanVolatile: return append_unsafe_get_obj(callee, T_BOOLEAN, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3137
    case vmIntrinsics::_getByteVolatile   : return append_unsafe_get_obj(callee, T_BYTE,    true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3138
    case vmIntrinsics::_getShortVolatile  : return append_unsafe_get_obj(callee, T_SHORT,   true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3139
    case vmIntrinsics::_getCharVolatile   : return append_unsafe_get_obj(callee, T_CHAR,    true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3140
    case vmIntrinsics::_getIntVolatile    : return append_unsafe_get_obj(callee, T_INT,     true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3141
    case vmIntrinsics::_getLongVolatile   : return append_unsafe_get_obj(callee, T_LONG,    true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3142
    case vmIntrinsics::_getFloatVolatile  : return append_unsafe_get_obj(callee, T_FLOAT,   true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3143
    case vmIntrinsics::_getDoubleVolatile : return append_unsafe_get_obj(callee, T_DOUBLE,  true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3144
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3145
    case vmIntrinsics::_putObjectVolatile : return append_unsafe_put_obj(callee, T_OBJECT,  true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3146
    case vmIntrinsics::_putBooleanVolatile: return append_unsafe_put_obj(callee, T_BOOLEAN, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3147
    case vmIntrinsics::_putByteVolatile   : return append_unsafe_put_obj(callee, T_BYTE,    true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3148
    case vmIntrinsics::_putShortVolatile  : return append_unsafe_put_obj(callee, T_SHORT,   true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3149
    case vmIntrinsics::_putCharVolatile   : return append_unsafe_put_obj(callee, T_CHAR,    true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3150
    case vmIntrinsics::_putIntVolatile    : return append_unsafe_put_obj(callee, T_INT,     true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3151
    case vmIntrinsics::_putLongVolatile   : return append_unsafe_put_obj(callee, T_LONG,    true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3152
    case vmIntrinsics::_putFloatVolatile  : return append_unsafe_put_obj(callee, T_FLOAT,   true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3153
    case vmIntrinsics::_putDoubleVolatile : return append_unsafe_put_obj(callee, T_DOUBLE,  true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3154
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3155
    case vmIntrinsics::_getByte_raw   : return append_unsafe_get_raw(callee, T_BYTE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3156
    case vmIntrinsics::_getShort_raw  : return append_unsafe_get_raw(callee, T_SHORT);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3157
    case vmIntrinsics::_getChar_raw   : return append_unsafe_get_raw(callee, T_CHAR);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3158
    case vmIntrinsics::_getInt_raw    : return append_unsafe_get_raw(callee, T_INT);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3159
    case vmIntrinsics::_getLong_raw   : return append_unsafe_get_raw(callee, T_LONG);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3160
    case vmIntrinsics::_getFloat_raw  : return append_unsafe_get_raw(callee, T_FLOAT);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3161
    case vmIntrinsics::_getDouble_raw : return append_unsafe_get_raw(callee, T_DOUBLE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3162
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3163
    case vmIntrinsics::_putByte_raw   : return append_unsafe_put_raw(callee, T_BYTE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3164
    case vmIntrinsics::_putShort_raw  : return append_unsafe_put_raw(callee, T_SHORT);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3165
    case vmIntrinsics::_putChar_raw   : return append_unsafe_put_raw(callee, T_CHAR);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3166
    case vmIntrinsics::_putInt_raw    : return append_unsafe_put_raw(callee, T_INT);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3167
    case vmIntrinsics::_putLong_raw   : return append_unsafe_put_raw(callee, T_LONG);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3168
    case vmIntrinsics::_putFloat_raw  : return append_unsafe_put_raw(callee, T_FLOAT);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3169
    case vmIntrinsics::_putDouble_raw : return append_unsafe_put_raw(callee, T_DOUBLE);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3170
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3171
    case vmIntrinsics::_prefetchRead        : return append_unsafe_prefetch(callee, false, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3172
    case vmIntrinsics::_prefetchWrite       : return append_unsafe_prefetch(callee, false, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3173
    case vmIntrinsics::_prefetchReadStatic  : return append_unsafe_prefetch(callee, true,  false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3174
    case vmIntrinsics::_prefetchWriteStatic : return append_unsafe_prefetch(callee, true,  true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3175
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3176
    case vmIntrinsics::_checkIndex    :
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3177
      if (!InlineNIOCheckIndex) return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3178
      preserves_state = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3179
      break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3180
    case vmIntrinsics::_putOrderedObject : return append_unsafe_put_obj(callee, T_OBJECT,  true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3181
    case vmIntrinsics::_putOrderedInt    : return append_unsafe_put_obj(callee, T_INT,     true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3182
    case vmIntrinsics::_putOrderedLong   : return append_unsafe_put_obj(callee, T_LONG,    true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3183
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3184
    case vmIntrinsics::_compareAndSwapLong:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3185
      if (!VM_Version::supports_cx8()) return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3186
      // fall through
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3187
    case vmIntrinsics::_compareAndSwapInt:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3188
    case vmIntrinsics::_compareAndSwapObject:
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3189
      append_unsafe_CAS(callee);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3190
      return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3191
9176
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  3192
    case vmIntrinsics::_Reference_get:
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  3193
      // It is only when G1 is enabled that we absolutely
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  3194
      // need to use the intrinsic version of Reference.get()
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  3195
      // so that the value in the referent field, if necessary,
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  3196
      // can be registered by the pre-barrier code.
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  3197
      if (!UseG1GC) return false;
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  3198
      preserves_state = true;
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  3199
      break;
42d9d1010f38 7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
johnc
parents: 8725
diff changeset
  3200
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3201
    default                       : return false; // do not inline
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3202
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3203
  // create intrinsic node
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3204
  const bool has_receiver = !callee->is_static();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3205
  ValueType* result_type = as_ValueType(callee->return_type());
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3206
  ValueStack* state_before = copy_state_for_exception();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3207
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3208
  Values* args = state()->pop_arguments(callee->arg_size());
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3209
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3210
  if (is_profiling()) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3211
    // Don't profile in the special case where the root method
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3212
    // is the intrinsic
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3213
    if (callee != method()) {
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3214
      // Note that we'd collect profile data in this method if we wanted it.
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3215
      compilation()->set_would_profile(true);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3216
      if (profile_calls()) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3217
        Value recv = NULL;
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3218
        if (has_receiver) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3219
          recv = args->at(0);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3220
          null_check(recv);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3221
        }
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3222
        profile_call(recv, NULL);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3223
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3224
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3225
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3226
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3227
  Intrinsic* result = new Intrinsic(result_type, id, args, has_receiver, state_before,
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3228
                                    preserves_state, cantrap);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3229
  // append instruction & push result
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3230
  Value value = append_split(result);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3231
  if (result_type != voidType) push(result_type, value);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3232
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3233
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3234
  // printing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3235
  if (PrintInlining) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3236
    print_inline_result(callee, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3237
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3238
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3239
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3240
  // done
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3241
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3242
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3243
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3244
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3245
bool GraphBuilder::try_inline_jsr(int jsr_dest_bci) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3246
  // Introduce a new callee continuation point - all Ret instructions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3247
  // will be replaced with Gotos to this point.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3248
  BlockBegin* cont = block_at(next_bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3249
  assert(cont != NULL, "continuation must exist (BlockListBuilder starts a new block after a jsr");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3250
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3251
  // Note: can not assign state to continuation yet, as we have to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3252
  // pick up the state from the Ret instructions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3253
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3254
  // Push callee scope
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3255
  push_scope_for_jsr(cont, jsr_dest_bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3256
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3257
  // Temporarily set up bytecode stream so we can append instructions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3258
  // (only using the bci of this stream)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3259
  scope_data()->set_stream(scope_data()->parent()->stream());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3260
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3261
  BlockBegin* jsr_start_block = block_at(jsr_dest_bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3262
  assert(jsr_start_block != NULL, "jsr start block must exist");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3263
  assert(!jsr_start_block->is_set(BlockBegin::was_visited_flag), "should not have visited jsr yet");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3264
  Goto* goto_sub = new Goto(jsr_start_block, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3265
  // Must copy state to avoid wrong sharing when parsing bytecodes
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3266
  assert(jsr_start_block->state() == NULL, "should have fresh jsr starting block");
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3267
  jsr_start_block->set_state(copy_state_before_with_bci(jsr_dest_bci));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3268
  append(goto_sub);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3269
  _block->set_end(goto_sub);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3270
  _last = _block = jsr_start_block;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3271
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3272
  // Clear out bytecode stream
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3273
  scope_data()->set_stream(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3274
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3275
  scope_data()->add_to_work_list(jsr_start_block);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3276
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3277
  // Ready to resume parsing in subroutine
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3278
  iterate_all_blocks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3279
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3280
  // If we bailed out during parsing, return immediately (this is bad news)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3281
  CHECK_BAILOUT_(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3282
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3283
  // Detect whether the continuation can actually be reached. If not,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3284
  // it has not had state set by the join() operations in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3285
  // iterate_bytecodes_for_block()/ret() and we should not touch the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3286
  // iteration state. The calling activation of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3287
  // iterate_bytecodes_for_block will then complete normally.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3288
  if (cont->state() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3289
    if (!cont->is_set(BlockBegin::was_visited_flag)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3290
      // add continuation to work list instead of parsing it immediately
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3291
      scope_data()->parent()->add_to_work_list(cont);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3292
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3293
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3294
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3295
  assert(jsr_continuation() == cont, "continuation must not have changed");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3296
  assert(!jsr_continuation()->is_set(BlockBegin::was_visited_flag) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3297
         jsr_continuation()->is_set(BlockBegin::parser_loop_header_flag),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3298
         "continuation can only be visited in case of backward branches");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3299
  assert(_last && _last->as_BlockEnd(), "block must have end");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3300
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3301
  // continuation is in work list, so end iteration of current block
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3302
  _skip_block = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3303
  pop_scope_for_jsr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3304
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3305
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3306
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3307
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3308
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3309
// Inline the entry of a synchronized method as a monitor enter and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3310
// register the exception handler which releases the monitor if an
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3311
// exception is thrown within the callee. Note that the monitor enter
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3312
// cannot throw an exception itself, because the receiver is
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3313
// guaranteed to be non-null by the explicit null check at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3314
// beginning of inlining.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3315
void GraphBuilder::inline_sync_entry(Value lock, BlockBegin* sync_handler) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3316
  assert(lock != NULL && sync_handler != NULL, "lock or handler missing");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3317
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3318
  monitorenter(lock, SynchronizationEntryBCI);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3319
  assert(_last->as_MonitorEnter() != NULL, "monitor enter expected");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3320
  _last->set_needs_null_check(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3321
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3322
  sync_handler->set(BlockBegin::exception_entry_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3323
  sync_handler->set(BlockBegin::is_on_work_list_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3324
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3325
  ciExceptionHandler* desc = new ciExceptionHandler(method()->holder(), 0, method()->code_size(), -1, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3326
  XHandler* h = new XHandler(desc);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3327
  h->set_entry_block(sync_handler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3328
  scope_data()->xhandlers()->append(h);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3329
  scope_data()->set_has_handler();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3330
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3331
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3332
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3333
// If an exception is thrown and not handled within an inlined
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3334
// synchronized method, the monitor must be released before the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3335
// exception is rethrown in the outer scope. Generate the appropriate
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3336
// instructions here.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3337
void GraphBuilder::fill_sync_handler(Value lock, BlockBegin* sync_handler, bool default_handler) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3338
  BlockBegin* orig_block = _block;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3339
  ValueStack* orig_state = _state;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3340
  Instruction* orig_last = _last;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3341
  _last = _block = sync_handler;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3342
  _state = sync_handler->state()->copy();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3343
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3344
  assert(sync_handler != NULL, "handler missing");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3345
  assert(!sync_handler->is_set(BlockBegin::was_visited_flag), "is visited here");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3346
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3347
  assert(lock != NULL || default_handler, "lock or handler missing");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3348
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3349
  XHandler* h = scope_data()->xhandlers()->remove_last();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3350
  assert(h->entry_block() == sync_handler, "corrupt list of handlers");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3351
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3352
  block()->set(BlockBegin::was_visited_flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3353
  Value exception = append_with_bci(new ExceptionObject(), SynchronizationEntryBCI);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3354
  assert(exception->is_pinned(), "must be");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3355
8492
e93bfdd91c63 7021603: crash in fill_sync_handler with ExtendedDTrace probes
never
parents: 8066
diff changeset
  3356
  int bci = SynchronizationEntryBCI;
8065
7ca689ce3d32 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 7432
diff changeset
  3357
  if (compilation()->env()->dtrace_method_probes()) {
8492
e93bfdd91c63 7021603: crash in fill_sync_handler with ExtendedDTrace probes
never
parents: 8066
diff changeset
  3358
    // Report exit from inline methods.  We don't have a stream here
e93bfdd91c63 7021603: crash in fill_sync_handler with ExtendedDTrace probes
never
parents: 8066
diff changeset
  3359
    // so pass an explicit bci of SynchronizationEntryBCI.
8065
7ca689ce3d32 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 7432
diff changeset
  3360
    Values* args = new Values(1);
8492
e93bfdd91c63 7021603: crash in fill_sync_handler with ExtendedDTrace probes
never
parents: 8066
diff changeset
  3361
    args->push(append_with_bci(new Constant(new ObjectConstant(method())), bci));
e93bfdd91c63 7021603: crash in fill_sync_handler with ExtendedDTrace probes
never
parents: 8066
diff changeset
  3362
    append_with_bci(new RuntimeCall(voidType, "dtrace_method_exit", CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), args), bci);
8065
7ca689ce3d32 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 7432
diff changeset
  3363
  }
7ca689ce3d32 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 7432
diff changeset
  3364
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3365
  if (lock) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3366
    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
  3367
    if (!lock->is_linked()) {
8492
e93bfdd91c63 7021603: crash in fill_sync_handler with ExtendedDTrace probes
never
parents: 8066
diff changeset
  3368
      lock = append_with_bci(lock, bci);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3369
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3370
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3371
    // exit the monitor in the context of the synchronized method
8492
e93bfdd91c63 7021603: crash in fill_sync_handler with ExtendedDTrace probes
never
parents: 8066
diff changeset
  3372
    monitorexit(lock, bci);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3373
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3374
    // exit the context of the synchronized method
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3375
    if (!default_handler) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3376
      pop_scope();
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3377
      bci = _state->caller_state()->bci();
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3378
      _state = _state->caller_state()->copy_for_parsing();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3379
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3380
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3381
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3382
  // perform the throw as if at the the call site
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3383
  apush(exception);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3384
  throw_op(bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3385
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3386
  BlockEnd* end = last()->as_BlockEnd();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3387
  block()->set_end(end);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3388
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3389
  _block = orig_block;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3390
  _state = orig_state;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3391
  _last = orig_last;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3392
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3393
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3394
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3395
bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3396
  assert(!callee->is_native(), "callee must not be native");
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3397
  if (count_backedges() && callee->has_loops()) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3398
    INLINE_BAILOUT("too complex for tiered");
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3399
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3400
  // first perform tests of things it's not possible to inline
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3401
  if (callee->has_exception_handlers() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3402
      !InlineMethodsWithExceptionHandlers) INLINE_BAILOUT("callee has exception handlers");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3403
  if (callee->is_synchronized() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3404
      !InlineSynchronizedMethods         ) INLINE_BAILOUT("callee is synchronized");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3405
  if (!callee->holder()->is_initialized()) INLINE_BAILOUT("callee's klass not initialized yet");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3406
  if (!callee->has_balanced_monitors())    INLINE_BAILOUT("callee's monitors do not match");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3407
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3408
  // Proper inlining of methods with jsrs requires a little more work.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3409
  if (callee->has_jsrs()                 ) INLINE_BAILOUT("jsrs not handled properly by inliner yet");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3410
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3411
  // now perform tests that are based on flag settings
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3412
  if (inline_level() > MaxInlineLevel                         ) INLINE_BAILOUT("too-deep inlining");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3413
  if (recursive_inline_level(callee) > MaxRecursiveInlineLevel) INLINE_BAILOUT("too-deep recursive inlining");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3414
  if (callee->code_size() > max_inline_size()                 ) INLINE_BAILOUT("callee is too large");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3415
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3416
  // don't inline throwable methods unless the inlining tree is rooted in a throwable class
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3417
  if (callee->name() == ciSymbol::object_initializer_name() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3418
      callee->holder()->is_subclass_of(ciEnv::current()->Throwable_klass())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3419
    // Throwable constructor call
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3420
    IRScope* top = scope();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3421
    while (top->caller() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3422
      top = top->caller();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3423
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3424
    if (!top->method()->holder()->is_subclass_of(ciEnv::current()->Throwable_klass())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3425
      INLINE_BAILOUT("don't inline Throwable constructors");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3426
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3427
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3428
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3429
  // When SSE2 is used on intel, then no special handling is needed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3430
  // for strictfp because the enum-constant is fixed at compile time,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3431
  // the check for UseSSE2 is needed here
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3432
  if (strict_fp_requires_explicit_rounding && UseSSE < 2 && method()->is_strict() != callee->is_strict()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3433
    INLINE_BAILOUT("caller and callee have different strict fp requirements");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3434
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3435
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3436
  if (compilation()->env()->num_inlined_bytecodes() > DesiredMethodLimit) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3437
    INLINE_BAILOUT("total inlining greater than DesiredMethodLimit");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3438
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3439
7432
f06f1253c317 7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents: 7427
diff changeset
  3440
  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
  3441
    INLINE_BAILOUT("mdo allocation failed");
f06f1253c317 7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
iveresov
parents: 7427
diff changeset
  3442
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3443
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3444
      // printing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3445
  if (PrintInlining) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3446
    print_inline_result(callee, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3447
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3448
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3449
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3450
  // NOTE: Bailouts from this point on, which occur at the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3451
  // GraphBuilder level, do not cause bailout just of the inlining but
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3452
  // in fact of the entire compilation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3453
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3454
  BlockBegin* orig_block = block();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3455
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3456
  const int args_base = state()->stack_size() - callee->arg_size();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3457
  assert(args_base >= 0, "stack underflow during inlining");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3458
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3459
  // Insert null check if necessary
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3460
  Value recv = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3461
  if (code() != Bytecodes::_invokestatic) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3462
    // note: null check must happen even if first instruction of callee does
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3463
    //       an implicit null check since the callee is in a different scope
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3464
    //       and we must make sure exception handling does the right thing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3465
    assert(!callee->is_static(), "callee must not be static");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3466
    assert(callee->arg_size() > 0, "must have at least a receiver");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3467
    recv = state()->stack_at(args_base);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3468
    null_check(recv);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3469
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3470
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3471
  if (is_profiling()) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3472
    // Note that we'd collect profile data in this method if we wanted it.
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3473
    // this may be redundant here...
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3474
    compilation()->set_would_profile(true);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3475
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3476
    if (profile_calls()) {
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3477
      profile_call(recv, holder_known ? callee->holder() : NULL);
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3478
    }
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3479
    if (profile_inlined_calls()) {
6751
b399fd234e47 6988346: 6986046 breaks tiered
iveresov
parents: 6745
diff changeset
  3480
      profile_invocation(callee, copy_state_before());
6453
970dc585ab63 6953144: Tiered compilation
iveresov
parents: 5882
diff changeset
  3481
    }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3482
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3483
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3484
  // Introduce a new callee continuation point - if the callee has
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3485
  // more than one return instruction or the return does not allow
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3486
  // fall-through of control flow, all return instructions of the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3487
  // callee will need to be replaced by Goto's pointing to this
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3488
  // continuation point.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3489
  BlockBegin* cont = block_at(next_bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3490
  bool continuation_existed = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3491
  if (cont == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3492
    cont = new BlockBegin(next_bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3493
    // low number so that continuation gets parsed as early as possible
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3494
    cont->set_depth_first_number(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3495
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3496
    if (PrintInitialBlockList) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3497
      tty->print_cr("CFG: created block %d (bci %d) as continuation for inline at bci %d",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3498
                    cont->block_id(), cont->bci(), bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3499
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3500
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3501
    continuation_existed = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3502
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3503
  // Record number of predecessors of continuation block before
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3504
  // inlining, to detect if inlined method has edges to its
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3505
  // continuation after inlining.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3506
  int continuation_preds = cont->number_of_preds();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3507
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3508
  // Push callee scope
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3509
  push_scope(callee, cont);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3510
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3511
  // the BlockListBuilder for the callee could have bailed out
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3512
  CHECK_BAILOUT_(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3513
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3514
  // Temporarily set up bytecode stream so we can append instructions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3515
  // (only using the bci of this stream)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3516
  scope_data()->set_stream(scope_data()->parent()->stream());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3517
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3518
  // Pass parameters into callee state: add assignments
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3519
  // note: this will also ensure that all arguments are computed before being passed
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3520
  ValueStack* callee_state = state();
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3521
  ValueStack* caller_state = state()->caller_state();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3522
  { int i = args_base;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3523
    while (i < caller_state->stack_size()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3524
      const int par_no = i - args_base;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3525
      Value  arg = caller_state->stack_at_inc(i);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3526
      // NOTE: take base() of arg->type() to avoid problems storing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3527
      // constants
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3528
      store_local(callee_state, arg, arg->type()->base(), par_no);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3529
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3530
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3531
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3532
  // Remove args from stack.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3533
  // Note that we preserve locals state in case we can use it later
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3534
  // (see use of pop_scope() below)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3535
  caller_state->truncate_stack(args_base);
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3536
  assert(callee_state->stack_size() == 0, "callee stack must be empty");
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3537
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3538
  Value lock;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3539
  BlockBegin* sync_handler;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3540
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3541
  // Inline the locking of the receiver if the callee is synchronized
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3542
  if (callee->is_synchronized()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3543
    lock = callee->is_static() ? append(new Constant(new InstanceConstant(callee->holder()->java_mirror())))
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3544
                               : state()->local_at(0);
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3545
    sync_handler = new BlockBegin(SynchronizationEntryBCI);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3546
    inline_sync_entry(lock, sync_handler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3547
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3548
8065
7ca689ce3d32 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 7432
diff changeset
  3549
  if (compilation()->env()->dtrace_method_probes()) {
7ca689ce3d32 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 7432
diff changeset
  3550
    Values* args = new Values(1);
7ca689ce3d32 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 7432
diff changeset
  3551
    args->push(append(new Constant(new ObjectConstant(method()))));
7ca689ce3d32 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 7432
diff changeset
  3552
    append(new RuntimeCall(voidType, "dtrace_method_entry", CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry), args));
7ca689ce3d32 6809483: hotspot:::method_entry are not correctly generated for "method()V"
never
parents: 7432
diff changeset
  3553
  }
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3554
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3555
  BlockBegin* callee_start_block = block_at(0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3556
  if (callee_start_block != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3557
    assert(callee_start_block->is_set(BlockBegin::parser_loop_header_flag), "must be loop header");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3558
    Goto* goto_callee = new Goto(callee_start_block, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3559
    // The state for this goto is in the scope of the callee, so use
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3560
    // the entry bci for the callee instead of the call site bci.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3561
    append_with_bci(goto_callee, 0);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3562
    _block->set_end(goto_callee);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3563
    callee_start_block->merge(callee_state);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3564
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3565
    _last = _block = callee_start_block;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3566
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3567
    scope_data()->add_to_work_list(callee_start_block);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3568
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3569
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3570
  // Clear out bytecode stream
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3571
  scope_data()->set_stream(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3572
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3573
  // Ready to resume parsing in callee (either in the same block we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3574
  // were in before or in the callee's start block)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3575
  iterate_all_blocks(callee_start_block == NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3576
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3577
  // If we bailed out during parsing, return immediately (this is bad news)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3578
  if (bailed_out()) return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3579
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3580
  // iterate_all_blocks theoretically traverses in random order; in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3581
  // practice, we have only traversed the continuation if we are
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3582
  // inlining into a subroutine
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3583
  assert(continuation_existed ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3584
         !continuation()->is_set(BlockBegin::was_visited_flag),
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3585
         "continuation should not have been parsed yet if we created it");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3586
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3587
  // If we bailed out during parsing, return immediately (this is bad news)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3588
  CHECK_BAILOUT_(false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3589
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3590
  // At this point we are almost ready to return and resume parsing of
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3591
  // the caller back in the GraphBuilder. The only thing we want to do
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3592
  // first is an optimization: during parsing of the callee we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3593
  // generated at least one Goto to the continuation block. If we
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3594
  // generated exactly one, and if the inlined method spanned exactly
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3595
  // one block (and we didn't have to Goto its entry), then we snip
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3596
  // off the Goto to the continuation, allowing control to fall
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3597
  // through back into the caller block and effectively performing
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3598
  // block merging. This allows load elimination and CSE to take place
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3599
  // across multiple callee scopes if they are relatively simple, and
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3600
  // is currently essential to making inlining profitable.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3601
  if (   num_returns() == 1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3602
      && block() == orig_block
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3603
      && block() == inline_cleanup_block()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3604
    _last = inline_cleanup_return_prev();
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3605
    _state = inline_cleanup_state();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3606
  } else if (continuation_preds == cont->number_of_preds()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3607
    // Inlining caused that the instructions after the invoke in the
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3608
    // caller are not reachable any more. So skip filling this block
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3609
    // with instructions!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3610
    assert (cont == continuation(), "");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3611
    assert(_last && _last->as_BlockEnd(), "");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3612
    _skip_block = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3613
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3614
    // Resume parsing in continuation block unless it was already parsed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3615
    // Note that if we don't change _last here, iteration in
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3616
    // iterate_bytecodes_for_block will stop when we return.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3617
    if (!continuation()->is_set(BlockBegin::was_visited_flag)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3618
      // add continuation to work list instead of parsing it immediately
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3619
      assert(_last && _last->as_BlockEnd(), "");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3620
      scope_data()->parent()->add_to_work_list(continuation());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3621
      _skip_block = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3622
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3623
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3624
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3625
  // Fill the exception handler for synchronized methods with instructions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3626
  if (callee->is_synchronized() && sync_handler->state() != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3627
    fill_sync_handler(lock, sync_handler);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3628
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3629
    pop_scope();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3630
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3631
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3632
  compilation()->notice_inlined_method(callee);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3633
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3634
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3635
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3636
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3637
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3638
void GraphBuilder::inline_bailout(const char* msg) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3639
  assert(msg != NULL, "inline bailout msg must exist");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3640
  _inline_bailout_msg = msg;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3641
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3642
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3643
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3644
void GraphBuilder::clear_inline_bailout() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3645
  _inline_bailout_msg = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3646
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3647
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3648
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3649
void GraphBuilder::push_root_scope(IRScope* scope, BlockList* bci2block, BlockBegin* start) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3650
  ScopeData* data = new ScopeData(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3651
  data->set_scope(scope);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3652
  data->set_bci2block(bci2block);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3653
  _scope_data = data;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3654
  _block = start;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3655
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3656
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3657
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3658
void GraphBuilder::push_scope(ciMethod* callee, BlockBegin* continuation) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3659
  IRScope* callee_scope = new IRScope(compilation(), scope(), bci(), callee, -1, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3660
  scope()->add_callee(callee_scope);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3661
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3662
  BlockListBuilder blb(compilation(), callee_scope, -1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3663
  CHECK_BAILOUT();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3664
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3665
  if (!blb.bci2block()->at(0)->is_set(BlockBegin::parser_loop_header_flag)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3666
    // this scope can be inlined directly into the caller so remove
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3667
    // the block at bci 0.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3668
    blb.bci2block()->at_put(0, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3669
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3670
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3671
  set_state(new ValueStack(callee_scope, state()->copy(ValueStack::CallerState, bci())));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3672
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3673
  ScopeData* data = new ScopeData(scope_data());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3674
  data->set_scope(callee_scope);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3675
  data->set_bci2block(blb.bci2block());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3676
  data->set_continuation(continuation);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3677
  _scope_data = data;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3678
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3679
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3680
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3681
void GraphBuilder::push_scope_for_jsr(BlockBegin* jsr_continuation, int jsr_dest_bci) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3682
  ScopeData* data = new ScopeData(scope_data());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3683
  data->set_parsing_jsr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3684
  data->set_jsr_entry_bci(jsr_dest_bci);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3685
  data->set_jsr_return_address_local(-1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3686
  // Must clone bci2block list as we will be mutating it in order to
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3687
  // properly clone all blocks in jsr region as well as exception
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3688
  // handlers containing rets
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3689
  BlockList* new_bci2block = new BlockList(bci2block()->length());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3690
  new_bci2block->push_all(bci2block());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3691
  data->set_bci2block(new_bci2block);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3692
  data->set_scope(scope());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3693
  data->setup_jsr_xhandlers();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3694
  data->set_continuation(continuation());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3695
  data->set_jsr_continuation(jsr_continuation);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3696
  _scope_data = data;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3697
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3698
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3699
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3700
void GraphBuilder::pop_scope() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3701
  int number_of_locks = scope()->number_of_locks();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3702
  _scope_data = scope_data()->parent();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3703
  // accumulate minimum number of monitor slots to be reserved
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3704
  scope()->set_min_number_of_locks(number_of_locks);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3705
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3706
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3707
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3708
void GraphBuilder::pop_scope_for_jsr() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3709
  _scope_data = scope_data()->parent();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3710
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3711
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3712
bool GraphBuilder::append_unsafe_get_obj(ciMethod* callee, BasicType t, bool is_volatile) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3713
  if (InlineUnsafeOps) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3714
    Values* args = state()->pop_arguments(callee->arg_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3715
    null_check(args->at(0));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3716
    Instruction* offset = args->at(2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3717
#ifndef _LP64
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3718
    offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3719
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3720
    Instruction* op = append(new UnsafeGetObject(t, args->at(1), offset, is_volatile));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3721
    push(op->type(), op);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3722
    compilation()->set_has_unsafe_access(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3723
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3724
  return InlineUnsafeOps;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3725
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3726
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3727
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3728
bool GraphBuilder::append_unsafe_put_obj(ciMethod* callee, BasicType t, bool is_volatile) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3729
  if (InlineUnsafeOps) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3730
    Values* args = state()->pop_arguments(callee->arg_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3731
    null_check(args->at(0));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3732
    Instruction* offset = args->at(2);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3733
#ifndef _LP64
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3734
    offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3735
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3736
    Instruction* op = append(new UnsafePutObject(t, args->at(1), offset, args->at(3), is_volatile));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3737
    compilation()->set_has_unsafe_access(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3738
    kill_all();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3739
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3740
  return InlineUnsafeOps;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3741
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3742
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3743
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3744
bool GraphBuilder::append_unsafe_get_raw(ciMethod* callee, BasicType t) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3745
  if (InlineUnsafeOps) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3746
    Values* args = state()->pop_arguments(callee->arg_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3747
    null_check(args->at(0));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3748
    Instruction* op = append(new UnsafeGetRaw(t, args->at(1), false));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3749
    push(op->type(), op);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3750
    compilation()->set_has_unsafe_access(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3751
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3752
  return InlineUnsafeOps;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3753
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3754
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3755
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3756
bool GraphBuilder::append_unsafe_put_raw(ciMethod* callee, BasicType t) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3757
  if (InlineUnsafeOps) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3758
    Values* args = state()->pop_arguments(callee->arg_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3759
    null_check(args->at(0));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3760
    Instruction* op = append(new UnsafePutRaw(t, args->at(1), args->at(2)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3761
    compilation()->set_has_unsafe_access(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3762
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3763
  return InlineUnsafeOps;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3764
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3765
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3766
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3767
bool GraphBuilder::append_unsafe_prefetch(ciMethod* callee, bool is_static, bool is_store) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3768
  if (InlineUnsafeOps) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3769
    Values* args = state()->pop_arguments(callee->arg_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3770
    int obj_arg_index = 1; // Assume non-static case
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3771
    if (is_static) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3772
      obj_arg_index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3773
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3774
      null_check(args->at(0));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3775
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3776
    Instruction* offset = args->at(obj_arg_index + 1);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3777
#ifndef _LP64
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3778
    offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3779
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3780
    Instruction* op = is_store ? append(new UnsafePrefetchWrite(args->at(obj_arg_index), offset))
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3781
                               : append(new UnsafePrefetchRead (args->at(obj_arg_index), offset));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3782
    compilation()->set_has_unsafe_access(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3783
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3784
  return InlineUnsafeOps;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3785
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3786
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3787
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3788
void GraphBuilder::append_unsafe_CAS(ciMethod* callee) {
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3789
  ValueStack* state_before = copy_state_for_exception();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3790
  ValueType* result_type = as_ValueType(callee->return_type());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3791
  assert(result_type->is_int(), "int result");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3792
  Values* args = state()->pop_arguments(callee->arg_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3793
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3794
  // Pop off some args to speically handle, then push back
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3795
  Value newval = args->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3796
  Value cmpval = args->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3797
  Value offset = args->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3798
  Value src = args->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3799
  Value unsafe_obj = args->pop();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3800
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3801
  // Separately handle the unsafe arg. It is not needed for code
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3802
  // generation, but must be null checked
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3803
  null_check(unsafe_obj);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3804
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3805
#ifndef _LP64
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3806
  offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT)));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3807
#endif
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3808
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3809
  args->push(src);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3810
  args->push(offset);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3811
  args->push(cmpval);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3812
  args->push(newval);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3813
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3814
  // An unsafe CAS can alias with other field accesses, but we don't
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3815
  // know which ones so mark the state as no preserved.  This will
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3816
  // cause CSE to invalidate memory across it.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3817
  bool preserves_state = false;
6745
a34ef8968a84 6986046: C1 valuestack cleanup
roland
parents: 6461
diff changeset
  3818
  Intrinsic* result = new Intrinsic(result_type, callee->intrinsic_id(), args, false, state_before, preserves_state);
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3819
  append_split(result);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3820
  push(result_type, result);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3821
  compilation()->set_has_unsafe_access(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3822
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3823
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3824
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3825
#ifndef PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3826
void GraphBuilder::print_inline_result(ciMethod* callee, bool res) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3827
  const char sync_char      = callee->is_synchronized()        ? 's' : ' ';
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3828
  const char exception_char = callee->has_exception_handlers() ? '!' : ' ';
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3829
  const char monitors_char  = callee->has_monitor_bytecodes()  ? 'm' : ' ';
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3830
  tty->print("     %c%c%c ", sync_char, exception_char, monitors_char);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3831
  for (int i = 0; i < scope()->level(); i++) tty->print("  ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3832
  if (res) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3833
    tty->print("  ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3834
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3835
    tty->print("- ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3836
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3837
  tty->print("@ %d  ", bci());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3838
  callee->print_short_name();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3839
  tty->print(" (%d bytes)", callee->code_size());
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3840
  if (_inline_bailout_msg) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3841
    tty->print("  %s", _inline_bailout_msg);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3842
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3843
  tty->cr();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3844
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3845
  if (res && CIPrintMethodCodes) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3846
    callee->print_codes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3847
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3848
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3849
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3850
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3851
void GraphBuilder::print_stats() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3852
  vmap()->print();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3853
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3854
#endif // PRODUCT
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3855
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3856
void GraphBuilder::profile_call(Value recv, ciKlass* known_holder) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3857
  append(new ProfileCall(method(), bci(), recv, known_holder));
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3858
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3859
6751
b399fd234e47 6988346: 6986046 breaks tiered
iveresov
parents: 6745
diff changeset
  3860
void GraphBuilder::profile_invocation(ciMethod* callee, ValueStack* state) {
b399fd234e47 6988346: 6986046 breaks tiered
iveresov
parents: 6745
diff changeset
  3861
  append(new ProfileInvoke(callee, state));
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  3862
}