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_intptr() const {
 83     assert(type() == T_INT, "type check");
 84     return _integer_value;
 85   }
 86 
 87   // For special case in deopt.
 88   intptr_t get_intptr(BasicType t) const {
 89     assert(t == T_OBJECT && type() == T_OBJECT, "type check");
 90     return _integer_value;
 91   }
 92 
 93   void set_intptr(intptr_t value) {
 94     assert(type() == T_INT, "type check");
 95     _integer_value = value;
 96   }
 97 
 98   // The jint value is always at offset 0 of the stack slot. On big endian platforms
 99   // this is the location of the high word therefore we cannot just cast to jint.
100   jint get_jint() const {
101     assert(type() == T_INT, "type check");
102     return *(jint*)&_integer_value;
103   }
104 
105   void set_jint(jint value) {
106     assert(type() == T_INT, "type check");
107     *(jint*)&_integer_value = value;
108   }
109 
110   BasicType type() const { return  _type; }
111 
112   bool equal(StackValue *value) {
113     if (_type != value->_type) return false;
114     if (_type == T_OBJECT)
115       return (_handle_value == value->_handle_value);
116     else {
117       assert(_type == T_INT, "sanity check");
118       // [phh] compare only low addressed portions of intptr_t slots
119       return (*(int *)&_integer_value == *(int *)&value->_integer_value);
120     }
121   }
122 
123   static StackValue* create_stack_value_from_oop_location(stackChunkOop chunk, void* addr);
124   static StackValue* create_stack_value_from_narrowOop_location(stackChunkOop chunk, void* addr, bool is_register);
125 
126   static BasicLock*  resolve_monitor_lock(const frame* fr, Location location);
127 
128   template<typename RegisterMapT>
129   static StackValue* create_stack_value(const frame* fr, const RegisterMapT* reg_map, ScopeValue* sv);
130 
131   template<typename RegisterMapT>
132   static address stack_value_address(const frame* fr, const RegisterMapT* reg_map, ScopeValue* sv);
133 
134 #ifndef PRODUCT
135  public:
136   // Printing
137   void print_on(outputStream* st) const;
138 #endif
139 
140  private:
141    template<typename RegisterMapT>
142    static StackValue* create_stack_value(ScopeValue* sv, address value_addr, const RegisterMapT* reg_map);
143 };
144 
145 #endif // SHARE_RUNTIME_STACKVALUE_HPP