1 /*
  2  * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #ifndef SHARE_RUNTIME_STACKVALUE_HPP
 26 #define SHARE_RUNTIME_STACKVALUE_HPP
 27 
 28 #include "code/location.hpp"
 29 #include "runtime/handles.hpp"
 30 
 31 class BasicLock;
 32 class frame;
 33 class RegisterMap;
 34 class ScopeValue;
 35 
 36 class StackValue : public ResourceObj {
 37  private:
 38   BasicType _type;
 39   intptr_t  _integer_value; // Blank java stack slot value
 40   Handle    _handle_value;  // Java stack slot value interpreted as a Handle
 41  public:
 42 
 43   StackValue(intptr_t value) {
 44     _type              = T_INT;
 45     _integer_value     = value;
 46   }
 47 
 48   StackValue(Handle value, intptr_t scalar_replaced = 0) {
 49     _type                = T_OBJECT;
 50     _integer_value       = scalar_replaced;
 51     _handle_value        = value;
 52     assert(_integer_value == 0 ||  _handle_value.is_null(), "not null object should not be marked as scalar replaced");
 53   }
 54 
 55   StackValue() {
 56     _type           = T_CONFLICT;
 57     _integer_value  = 0;
 58   }
 59 
 60   // Only used during deopt- preserve object type.
 61   StackValue(intptr_t o, BasicType t) {
 62     assert(t == T_OBJECT, "should not be used");
 63     _type          = t;
 64     _integer_value = o;
 65   }
 66 
 67   Handle get_obj() const {
 68     assert(type() == T_OBJECT, "type check");
 69     return _handle_value;
 70   }
 71 
 72   bool obj_is_scalar_replaced() const {
 73     assert(type() == T_OBJECT, "type check");
 74     return _integer_value != 0;
 75   }
 76 
 77   void set_obj(Handle value) {
 78     assert(type() == T_OBJECT, "type check");
 79     _handle_value = value;
 80   }
 81 
 82   intptr_t get_int() const {
 83     assert(type() == T_INT, "type check");
 84     return _integer_value;
 85   }
 86 
 87   // For special case in deopt.
 88   intptr_t get_int(BasicType t) const {
 89     assert(t == T_OBJECT && type() == T_OBJECT, "type check");
 90     return _integer_value;
 91   }
 92 
 93   void set_int(intptr_t value) {
 94     assert(type() == T_INT, "type check");
 95     _integer_value = value;
 96   }
 97 
 98   BasicType type() const { return  _type; }
 99 
100   bool equal(StackValue *value) {
101     if (_type != value->_type) return false;
102     if (_type == T_OBJECT)
103       return (_handle_value == value->_handle_value);
104     else {
105       assert(_type == T_INT, "sanity check");
106       // [phh] compare only low addressed portions of intptr_t slots
107       return (*(int *)&_integer_value == *(int *)&value->_integer_value);
108     }
109   }
110 
111   static BasicLock*  resolve_monitor_lock(const frame* fr, Location location);
112 
113   template<typename RegisterMapT>
114   static StackValue* create_stack_value(const frame* fr, const RegisterMapT* reg_map, ScopeValue* sv);
115 
116   template<typename RegisterMapT>
117   static address stack_value_address(const frame* fr, const RegisterMapT* reg_map, ScopeValue* sv);
118 
119 #ifndef PRODUCT
120  public:
121   // Printing
122   void print_on(outputStream* st) const;
123 #endif
124 
125  private:
126    template<typename RegisterMapT>
127    static StackValue* create_stack_value(ScopeValue* sv, address value_addr, const RegisterMapT* reg_map);
128 };
129 
130 #endif // SHARE_RUNTIME_STACKVALUE_HPP