Path: blob/master/src/hotspot/share/ci/bcEscapeAnalyzer.hpp
40930 views
/*1* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#ifndef SHARE_CI_BCESCAPEANALYZER_HPP25#define SHARE_CI_BCESCAPEANALYZER_HPP2627#ifdef COMPILER228#include "ci/ciObject.hpp"29#include "ci/ciMethod.hpp"30#include "ci/ciMethodData.hpp"31#include "code/dependencies.hpp"32#include "libadt/vectset.hpp"33#include "memory/allocation.hpp"34#include "utilities/growableArray.hpp"35#endif3637// This class implements a fast, conservative analysis of effect of methods38// on the escape state of their arguments. The analysis is at the bytecode39// level.4041class ciMethodBlocks;42class ciBlock;4344class BCEscapeAnalyzer : public ResourceObj {45private:46Arena* _arena; // ciEnv arena4748bool _conservative; // If true, return maximally49// conservative results.50ciMethod* _method;51ciMethodData* _methodData;52int _arg_size;53VectorSet _arg_local;54VectorSet _arg_stack;55VectorSet _arg_returned;56enum{ ARG_OFFSET_MAX = 31};57uint *_arg_modified;5859bool _return_local;60bool _return_allocated;61bool _allocated_escapes;62bool _unknown_modified;6364GrowableArray<ciMetadata*> _dependencies;6566ciMethodBlocks *_methodBlocks;6768BCEscapeAnalyzer* _parent;69int _level;7071public:72class ArgumentMap;73class StateInfo;7475private:76// helper functions77bool is_argument(int i) { return i >= 0 && i < _arg_size; }78void set_returned(ArgumentMap vars);79bool is_argument(ArgumentMap vars);80bool is_arg_stack(ArgumentMap vars);81bool returns_all(ArgumentMap vars);82void clear_bits(ArgumentMap vars, VectorSet &bs);83void set_method_escape(ArgumentMap vars);84void set_global_escape(ArgumentMap vars, bool merge = false);85void set_modified(ArgumentMap vars, int offs, int size);8687bool is_recursive_call(ciMethod* callee);88void invoke(StateInfo &state, Bytecodes::Code code, ciMethod* target, ciKlass* holder);8990void iterate_one_block(ciBlock *blk, StateInfo &state, GrowableArray<ciBlock *> &successors);91void iterate_blocks(Arena *);92void merge_block_states(StateInfo *blockstates, ciBlock *dest, StateInfo *s_state);9394// analysis95void initialize();96void clear_escape_info();97void compute_escape_info();98vmIntrinsicID known_intrinsic();99void compute_escape_for_intrinsic(vmIntrinsicID iid);100void do_analysis();101102void read_escape_info();103104bool contains(uint arg_set1, uint arg_set2);105106public:107BCEscapeAnalyzer(ciMethod* method, BCEscapeAnalyzer* parent = NULL);108109// accessors110ciMethod* method() const { return _method; }111ciMethodData* methodData() const { return _methodData; }112BCEscapeAnalyzer* parent() const { return _parent; }113int level() const { return _level; }114GrowableArray<ciMetadata *>* dependencies() { return &_dependencies; }115bool has_dependencies() const { return !_dependencies.is_empty(); }116117// retrieval of interprocedural escape information118119// The given argument does not escape the callee.120bool is_arg_local(int i) const {121return !_conservative && _arg_local.test(i);122}123124// The given argument escapes the callee, but does not become globally125// reachable.126bool is_arg_stack(int i) const {127return !_conservative && _arg_stack.test(i);128}129130// The given argument does not escape globally, and may be returned.131bool is_arg_returned(int i) const {132return !_conservative && _arg_returned.test(i); }133134// True iff only input arguments are returned.135bool is_return_local() const {136return !_conservative && _return_local;137}138139// True iff only newly allocated non-escaped objects are returned.140bool is_return_allocated() const {141return !_conservative && _return_allocated && !_allocated_escapes;142}143144// Tracking of argument modification145146enum {OFFSET_ANY = -1};147bool is_arg_modified(int arg, int offset, int size_in_bytes);148void set_arg_modified(int arg, int offset, int size_in_bytes);149bool has_non_arg_side_affects() { return _unknown_modified; }150151// Copy dependencies from this analysis into "deps"152void copy_dependencies(Dependencies *deps);153154#ifndef PRODUCT155// dump escape information156void dump();157#endif158};159160#endif // SHARE_CI_BCESCAPEANALYZER_HPP161162163