1/*
2 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
3 * Copyright 2008, 2009 Red Hat, Inc.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
25
26#ifndef SHARE_VM_SHARK_SHARKINVARIANTS_HPP
27#define SHARE_VM_SHARK_SHARKINVARIANTS_HPP
28
29#include "ci/ciEnv.hpp"
30#include "ci/ciInstanceKlass.hpp"
31#include "ci/ciMethod.hpp"
32#include "ci/ciTypeFlow.hpp"
33#include "code/debugInfoRec.hpp"
34#include "code/dependencies.hpp"
35#include "memory/allocation.hpp"
36#include "shark/llvmHeaders.hpp"
37#include "shark/sharkBuilder.hpp"
38
39// Base classes used to track various values through the compilation.
40// SharkCompileInvariants is used to track values which remain the
41// same for the top-level method and any inlined methods it may have
42// (ie for the whole compilation).  SharkTargetInvariants is used to
43// track values which differ between methods.
44
45class SharkCompileInvariants : public ResourceObj {
46 protected:
47  SharkCompileInvariants(ciEnv* env, SharkBuilder* builder)
48    : _env(env),
49      _builder(builder),
50      _thread(NULL) {}
51
52  SharkCompileInvariants(const SharkCompileInvariants* parent)
53    : _env(parent->_env),
54      _builder(parent->_builder),
55      _thread(parent->_thread) {}
56
57 private:
58  ciEnv*        _env;
59  SharkBuilder* _builder;
60  llvm::Value*  _thread;
61
62  // Top-level broker for HotSpot's Compiler Interface.
63  //
64  // Its main purpose is to allow the various CI classes to access
65  // oops in the VM without having to worry about safepointing.  In
66  // addition to this it acts as a holder for various recorders and
67  // memory allocators.
68  //
69  // Accessing this directly is kind of ugly, so it's private.  Add
70  // new accessors below if you need something from it.
71 protected:
72  ciEnv* env() const {
73    assert(_env != NULL, "env not available");
74    return _env;
75  }
76
77  // The SharkBuilder that is used to build LLVM IR.
78 protected:
79  SharkBuilder* builder() const {
80    return _builder;
81  }
82
83  // Pointer to this thread's JavaThread object.  This is not
84  // available until a short way into SharkFunction creation
85  // so a setter is required.  Assertions are used to enforce
86  // invariance.
87 protected:
88  llvm::Value* thread() const {
89    assert(_thread != NULL, "thread not available");
90    return _thread;
91  }
92  void set_thread(llvm::Value* thread) {
93    assert(_thread == NULL, "thread already set");
94    _thread = thread;
95  }
96
97  // Objects that handle various aspects of the compilation.
98 protected:
99  DebugInformationRecorder* debug_info() const {
100    return env()->debug_info();
101  }
102  SharkCodeBuffer* code_buffer() const {
103    return builder()->code_buffer();
104  }
105
106 public:
107  Dependencies* dependencies() const {
108    return env()->dependencies();
109  }
110
111  // Commonly used classes
112 protected:
113  ciInstanceKlass* java_lang_Object_klass() const {
114    return env()->Object_klass();
115  }
116  ciInstanceKlass* java_lang_Throwable_klass() const {
117    return env()->Throwable_klass();
118  }
119};
120
121class SharkTargetInvariants : public SharkCompileInvariants {
122 protected:
123  SharkTargetInvariants(ciEnv* env, SharkBuilder* builder, ciTypeFlow* flow)
124    : SharkCompileInvariants(env, builder),
125      _target(flow->method()),
126      _flow(flow),
127      _max_monitors(count_monitors()) {}
128
129  SharkTargetInvariants(const SharkCompileInvariants* parent, ciMethod* target)
130    : SharkCompileInvariants(parent),
131      _target(target),
132      _flow(NULL),
133      _max_monitors(count_monitors()) {}
134
135  SharkTargetInvariants(const SharkTargetInvariants* parent)
136    : SharkCompileInvariants(parent),
137      _target(parent->_target),
138      _flow(parent->_flow),
139      _max_monitors(parent->_max_monitors) {}
140
141 private:
142  int count_monitors();
143
144 private:
145  ciMethod*   _target;
146  ciTypeFlow* _flow;
147  int         _max_monitors;
148
149  // The method being compiled.
150 protected:
151  ciMethod* target() const {
152    return _target;
153  }
154
155  // Typeflow analysis of the method being compiled.
156 protected:
157  ciTypeFlow* flow() const {
158    assert(_flow != NULL, "typeflow not available");
159    return _flow;
160  }
161
162  // Properties of the method.
163 protected:
164  int max_locals() const {
165    return target()->max_locals();
166  }
167  int max_stack() const {
168    return target()->max_stack();
169  }
170  int max_monitors() const {
171    return _max_monitors;
172  }
173  int arg_size() const {
174    return target()->arg_size();
175  }
176  bool is_static() const {
177    return target()->is_static();
178  }
179  bool is_synchronized() const {
180    return target()->is_synchronized();
181  }
182};
183
184#endif // SHARE_VM_SHARK_SHARKINVARIANTS_HPP
185