aboutsummaryrefslogtreecommitdiff
path: root/src/share/vm/shark/sharkBlock.hpp
blob: 1b43264f1ae4a59c0307013a401fbc5976016b79 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
/*
 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
 * Copyright 2008, 2009 Red Hat, Inc.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#ifndef SHARE_VM_SHARK_SHARKBLOCK_HPP
#define SHARE_VM_SHARK_SHARKBLOCK_HPP

#include "ci/ciMethod.hpp"
#include "ci/ciStreams.hpp"
#include "memory/allocation.hpp"
#include "shark/llvmHeaders.hpp"
#include "shark/sharkBuilder.hpp"
#include "shark/sharkConstant.hpp"
#include "shark/sharkInvariants.hpp"
#include "shark/sharkState.hpp"
#include "shark/sharkValue.hpp"
#include "utilities/debug.hpp"

class SharkState;

class SharkBlock : public SharkTargetInvariants {
 protected:
  SharkBlock(const SharkTargetInvariants* parent)
    : SharkTargetInvariants(parent),
      _iter(target()),
      _current_state(NULL) {}

  SharkBlock(const SharkCompileInvariants* parent, ciMethod* target)
    : SharkTargetInvariants(parent, target),
      _iter(target),
      _current_state(NULL) {}

 private:
  ciBytecodeStream _iter;
  SharkState*      _current_state;

 public:
  ciBytecodeStream* iter() {
    return &_iter;
  }
  Bytecodes::Code bc() {
    return iter()->cur_bc();
  }
  int bci() {
    return iter()->cur_bci();
  }

  // Entry state
 protected:
  virtual SharkState* entry_state();

  // Current state
 private:
  SharkState* initial_current_state();

 public:
  SharkState* current_state() {
    if (_current_state == NULL)
      set_current_state(initial_current_state());
    return _current_state;
  }

 protected:
  void set_current_state(SharkState* current_state) {
    _current_state = current_state;
  }

  // Local variables
 protected:
  SharkValue* local(int index) {
    SharkValue *value = current_state()->local(index);
    assert(value != NULL, "shouldn't be");
    assert(value->is_one_word() ||
           (index + 1 < max_locals() &&
            current_state()->local(index + 1) == NULL), "should be");
    return value;
  }
  void set_local(int index, SharkValue* value) {
    assert(value != NULL, "shouldn't be");
    current_state()->set_local(index, value);
    if (value->is_two_word())
      current_state()->set_local(index + 1, NULL);
  }

  // Expression stack (raw)
 protected:
  void xpush(SharkValue* value) {
    current_state()->push(value);
  }
  SharkValue* xpop() {
    return current_state()->pop();
  }
  SharkValue* xstack(int slot) {
    SharkValue *value = current_state()->stack(slot);
    assert(value != NULL, "shouldn't be");
    assert(value->is_one_word() ||
           (slot > 0 &&
            current_state()->stack(slot - 1) == NULL), "should be");
    return value;
  }
  int xstack_depth() {
    return current_state()->stack_depth();
  }

  // Expression stack (cooked)
 protected:
  void push(SharkValue* value) {
    assert(value != NULL, "shouldn't be");
    xpush(value);
    if (value->is_two_word())
      xpush(NULL);
  }
  SharkValue* pop() {
    int size = current_state()->stack(0) == NULL ? 2 : 1;
    if (size == 2)
      xpop();
    SharkValue *value = xpop();
    assert(value && value->size() == size, "should be");
    return value;
  }
  SharkValue* pop_result(BasicType type) {
    SharkValue *result = pop();

#ifdef ASSERT
    switch (result->basic_type()) {
    case T_BOOLEAN:
    case T_BYTE:
    case T_CHAR:
    case T_SHORT:
      assert(type == T_INT, "type mismatch");
      break;

    case T_ARRAY:
      assert(type == T_OBJECT, "type mismatch");
      break;

    default:
      assert(result->basic_type() == type, "type mismatch");
    }
#endif // ASSERT

    return result;
  }

  // Code generation
 public:
  virtual void emit_IR();

 protected:
  void parse_bytecode(int start, int limit);

  // Helpers
 protected:
  virtual void do_zero_check(SharkValue* value);

  // Zero checking
 protected:
  void check_null(SharkValue* object) {
    zero_check(object);
  }
  void check_divide_by_zero(SharkValue* value) {
    zero_check(value);
  }
 private:
  void zero_check(SharkValue* value) {
    if (!value->zero_checked())
      do_zero_check(value);
  }

  // Safepoints
 protected:
  virtual void maybe_add_backedge_safepoint();

  // Traps
 protected:
  virtual bool has_trap();
  virtual int  trap_request();
  virtual int  trap_bci();
  virtual void do_trap(int trap_request);

  // arraylength
 protected:
  virtual void do_arraylength();

  // *aload and *astore
 protected:
  virtual void do_aload(BasicType basic_type);
  virtual void do_astore(BasicType basic_type);

  // *div and *rem
 private:
  void do_idiv() {
    do_div_or_rem(false, false);
  }
  void do_irem() {
    do_div_or_rem(false, true);
  }
  void do_ldiv() {
    do_div_or_rem(true, false);
  }
  void do_lrem() {
    do_div_or_rem(true, true);
  }
  void do_div_or_rem(bool is_long, bool is_rem);

  // get* and put*
 private:
  void do_getstatic() {
    do_field_access(true, false);
  }
  void do_getfield() {
    do_field_access(true, true);
  }
  void do_putstatic() {
    do_field_access(false, false);
  }
  void do_putfield() {
    do_field_access(false, true);
  }
  void do_field_access(bool is_get, bool is_field);

  // lcmp and [fd]cmp[lg]
 private:
  void do_lcmp();
  void do_fcmp(bool is_double, bool unordered_is_greater);

  // *return and athrow
 protected:
  virtual void do_return(BasicType type);
  virtual void do_athrow();

  // goto*
 protected:
  virtual void do_goto();

  // jsr* and ret
 protected:
  virtual void do_jsr();
  virtual void do_ret();

  // if*
 protected:
  virtual void do_if(llvm::ICmpInst::Predicate p, SharkValue* b, SharkValue* a);

  // *switch
 protected:
  int switch_default_dest();
  int switch_table_length();
  int switch_key(int i);
  int switch_dest(int i);

  virtual void do_switch();

  // invoke*
 protected:
  virtual void do_call();

  // checkcast and instanceof
 protected:
  virtual void do_instance_check();
  virtual bool maybe_do_instanceof_if();

  // new and *newarray
 protected:
  virtual void do_new();
  virtual void do_newarray();
  virtual void do_anewarray();
  virtual void do_multianewarray();

  // monitorenter and monitorexit
 protected:
  virtual void do_monitorenter();
  virtual void do_monitorexit();
};

#endif // SHARE_VM_SHARK_SHARKBLOCK_HPP