twisti@2047: /* stefank@2314: * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. twisti@2047: * Copyright 2008, 2009 Red Hat, Inc. twisti@2047: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. twisti@2047: * twisti@2047: * This code is free software; you can redistribute it and/or modify it twisti@2047: * under the terms of the GNU General Public License version 2 only, as twisti@2047: * published by the Free Software Foundation. twisti@2047: * twisti@2047: * This code is distributed in the hope that it will be useful, but WITHOUT twisti@2047: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or twisti@2047: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License twisti@2047: * version 2 for more details (a copy is included in the LICENSE file that twisti@2047: * accompanied this code). twisti@2047: * twisti@2047: * You should have received a copy of the GNU General Public License version twisti@2047: * 2 along with this work; if not, write to the Free Software Foundation, twisti@2047: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. twisti@2047: * twisti@2047: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA twisti@2047: * or visit www.oracle.com if you need additional information or have any twisti@2047: * questions. twisti@2047: * twisti@2047: */ twisti@2047: stefank@2314: #ifndef SHARE_VM_SHARK_SHARKINVARIANTS_HPP stefank@2314: #define SHARE_VM_SHARK_SHARKINVARIANTS_HPP stefank@2314: stefank@2314: #include "ci/ciEnv.hpp" stefank@2314: #include "ci/ciInstanceKlass.hpp" stefank@2314: #include "ci/ciMethod.hpp" stefank@2314: #include "ci/ciTypeFlow.hpp" stefank@2314: #include "code/debugInfoRec.hpp" stefank@2314: #include "code/dependencies.hpp" stefank@2314: #include "memory/allocation.hpp" stefank@2314: #include "shark/llvmHeaders.hpp" stefank@2314: #include "shark/sharkBuilder.hpp" stefank@2314: twisti@2047: // Base classes used to track various values through the compilation. twisti@2047: // SharkCompileInvariants is used to track values which remain the twisti@2047: // same for the top-level method and any inlined methods it may have twisti@2047: // (ie for the whole compilation). SharkTargetInvariants is used to twisti@2047: // track values which differ between methods. twisti@2047: twisti@2047: class SharkCompileInvariants : public ResourceObj { twisti@2047: protected: twisti@2047: SharkCompileInvariants(ciEnv* env, SharkBuilder* builder) twisti@2047: : _env(env), twisti@2047: _builder(builder), twisti@2047: _thread(NULL) {} twisti@2047: twisti@2047: SharkCompileInvariants(const SharkCompileInvariants* parent) twisti@2047: : _env(parent->_env), twisti@2047: _builder(parent->_builder), twisti@2047: _thread(parent->_thread) {} twisti@2047: twisti@2047: private: twisti@2047: ciEnv* _env; twisti@2047: SharkBuilder* _builder; twisti@2047: llvm::Value* _thread; twisti@2047: twisti@2047: // Top-level broker for HotSpot's Compiler Interface. twisti@2047: // twisti@2047: // Its main purpose is to allow the various CI classes to access twisti@2047: // oops in the VM without having to worry about safepointing. In twisti@2047: // addition to this it acts as a holder for various recorders and twisti@2047: // memory allocators. twisti@2047: // twisti@2047: // Accessing this directly is kind of ugly, so it's private. Add twisti@2047: // new accessors below if you need something from it. twisti@4443: protected: twisti@2047: ciEnv* env() const { twisti@2047: assert(_env != NULL, "env not available"); twisti@2047: return _env; twisti@2047: } twisti@2047: twisti@2047: // The SharkBuilder that is used to build LLVM IR. twisti@2047: protected: twisti@2047: SharkBuilder* builder() const { twisti@2047: return _builder; twisti@2047: } twisti@2047: twisti@2047: // Pointer to this thread's JavaThread object. This is not twisti@2047: // available until a short way into SharkFunction creation twisti@2047: // so a setter is required. Assertions are used to enforce twisti@2047: // invariance. twisti@2047: protected: twisti@2047: llvm::Value* thread() const { twisti@2047: assert(_thread != NULL, "thread not available"); twisti@2047: return _thread; twisti@2047: } twisti@2047: void set_thread(llvm::Value* thread) { twisti@2047: assert(_thread == NULL, "thread already set"); twisti@2047: _thread = thread; twisti@2047: } twisti@2047: twisti@2047: // Objects that handle various aspects of the compilation. twisti@2047: protected: twisti@2047: DebugInformationRecorder* debug_info() const { twisti@2047: return env()->debug_info(); twisti@2047: } twisti@4442: SharkCodeBuffer* code_buffer() const { twisti@4442: return builder()->code_buffer(); twisti@4442: } twisti@4442: twisti@4442: public: twisti@2047: Dependencies* dependencies() const { twisti@2047: return env()->dependencies(); twisti@2047: } twisti@2047: twisti@2047: // Commonly used classes twisti@2047: protected: twisti@2047: ciInstanceKlass* java_lang_Object_klass() const { twisti@2047: return env()->Object_klass(); twisti@2047: } twisti@2047: ciInstanceKlass* java_lang_Throwable_klass() const { twisti@2047: return env()->Throwable_klass(); twisti@2047: } twisti@2047: }; twisti@2047: twisti@2047: class SharkTargetInvariants : public SharkCompileInvariants { twisti@2047: protected: twisti@2047: SharkTargetInvariants(ciEnv* env, SharkBuilder* builder, ciTypeFlow* flow) twisti@2047: : SharkCompileInvariants(env, builder), twisti@2047: _target(flow->method()), twisti@2047: _flow(flow), twisti@2047: _max_monitors(count_monitors()) {} twisti@2047: twisti@2047: SharkTargetInvariants(const SharkCompileInvariants* parent, ciMethod* target) twisti@2047: : SharkCompileInvariants(parent), twisti@2047: _target(target), twisti@2047: _flow(NULL), twisti@2047: _max_monitors(count_monitors()) {} twisti@2047: twisti@2047: SharkTargetInvariants(const SharkTargetInvariants* parent) twisti@2047: : SharkCompileInvariants(parent), twisti@2047: _target(parent->_target), twisti@2047: _flow(parent->_flow), twisti@2047: _max_monitors(parent->_max_monitors) {} twisti@2047: twisti@2047: private: twisti@2047: int count_monitors(); twisti@2047: twisti@2047: private: twisti@2047: ciMethod* _target; twisti@2047: ciTypeFlow* _flow; twisti@2047: int _max_monitors; twisti@2047: twisti@2047: // The method being compiled. twisti@2047: protected: twisti@2047: ciMethod* target() const { twisti@2047: return _target; twisti@2047: } twisti@2047: twisti@2047: // Typeflow analysis of the method being compiled. twisti@2047: protected: twisti@2047: ciTypeFlow* flow() const { twisti@2047: assert(_flow != NULL, "typeflow not available"); twisti@2047: return _flow; twisti@2047: } twisti@2047: twisti@2047: // Properties of the method. twisti@2047: protected: twisti@2047: int max_locals() const { twisti@2047: return target()->max_locals(); twisti@2047: } twisti@2047: int max_stack() const { twisti@2047: return target()->max_stack(); twisti@2047: } twisti@2047: int max_monitors() const { twisti@2047: return _max_monitors; twisti@2047: } twisti@2047: int arg_size() const { twisti@2047: return target()->arg_size(); twisti@2047: } twisti@2047: bool is_static() const { twisti@2047: return target()->is_static(); twisti@2047: } twisti@2047: bool is_synchronized() const { twisti@2047: return target()->is_synchronized(); twisti@2047: } twisti@2047: }; stefank@2314: stefank@2314: #endif // SHARE_VM_SHARK_SHARKINVARIANTS_HPP