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
--- EOF ---