41 #include "runtime/stubRoutines.hpp"
42 #include "runtime/vframeArray.hpp"
43 #include "runtime/vframe_hp.hpp"
44 #ifdef COMPILER2
45 #include "opto/matcher.hpp"
46 #endif
47
48
49 // ------------- compiledVFrame --------------
50
51 StackValueCollection* compiledVFrame::locals() const {
52 // Natives has no scope
53 if (scope() == NULL) return new StackValueCollection(0);
54 GrowableArray<ScopeValue*>* scv_list = scope()->locals();
55 if (scv_list == NULL) return new StackValueCollection(0);
56
57 // scv_list is the list of ScopeValues describing the JVM stack state.
58 // There is one scv_list entry for every JVM stack state in use.
59 int length = scv_list->length();
60 StackValueCollection* result = new StackValueCollection(length);
61 for (int i = 0; i < length; i++) {
62 result->add(create_stack_value(scv_list->at(i)));
63 }
64
65 // Replace the original values with any stores that have been
66 // performed through compiledVFrame::update_locals.
67 GrowableArray<jvmtiDeferredLocalVariableSet*>* list = thread()->deferred_locals();
68 if (list != NULL ) {
69 // In real life this never happens or is typically a single element search
70 for (int i = 0; i < list->length(); i++) {
71 if (list->at(i)->matches(this)) {
72 list->at(i)->update_locals(result);
73 break;
74 }
75 }
76 }
77
78 return result;
79 }
80
81
82 void compiledVFrame::set_locals(StackValueCollection* values) const {
121 thread()->set_deferred_locals(deferred);
122 }
123 if (locals == NULL) {
124 locals = new jvmtiDeferredLocalVariableSet(method(), bci(), fr().id(), vframe_id());
125 deferred->push(locals);
126 assert(locals->id() == fr().id(), "Huh? Must match");
127 }
128 locals->set_value_at(index, type, value);
129 }
130
131 StackValueCollection* compiledVFrame::expressions() const {
132 // Natives has no scope
133 if (scope() == NULL) return new StackValueCollection(0);
134 GrowableArray<ScopeValue*>* scv_list = scope()->expressions();
135 if (scv_list == NULL) return new StackValueCollection(0);
136
137 // scv_list is the list of ScopeValues describing the JVM stack state.
138 // There is one scv_list entry for every JVM stack state in use.
139 int length = scv_list->length();
140 StackValueCollection* result = new StackValueCollection(length);
141 for (int i = 0; i < length; i++) {
142 result->add(create_stack_value(scv_list->at(i)));
143 }
144
145 // Replace the original values with any stores that have been
146 // performed through compiledVFrame::update_stack.
147 GrowableArray<jvmtiDeferredLocalVariableSet*>* list = thread()->deferred_locals();
148 if (list != NULL ) {
149 // In real life this never happens or is typically a single element search
150 for (int i = 0; i < list->length(); i++) {
151 if (list->at(i)->matches(this)) {
152 list->at(i)->update_stack(result);
153 break;
154 }
155 }
156 }
157
158 return result;
159 }
160
161
162 // The implementation of the following two methods was factorized into the
163 // class StackValue because it is also used from within deoptimization.cpp for
164 // rematerialization and relocking of non-escaping objects.
165
166 StackValue *compiledVFrame::create_stack_value(ScopeValue *sv) const {
167 return StackValue::create_stack_value(&_fr, register_map(), sv);
168 }
169
170 BasicLock* compiledVFrame::resolve_monitor_lock(Location location) const {
171 return StackValue::resolve_monitor_lock(&_fr, location);
172 }
173
174
175 GrowableArray<MonitorInfo*>* compiledVFrame::monitors() const {
176 // Natives has no scope
177 if (scope() == NULL) {
178 CompiledMethod* nm = code();
179 Method* method = nm->method();
180 assert(method->is_native() || nm->is_aot(), "Expect a native method or precompiled method");
181 if (!method->is_synchronized()) {
182 return new GrowableArray<MonitorInfo*>(0);
183 }
184 // This monitor is really only needed for UseBiasedLocking, but
185 // return it in all cases for now as it might be useful for stack
186 // traces and tools as well
187 GrowableArray<MonitorInfo*> *monitors = new GrowableArray<MonitorInfo*>(1);
188 // Casting away const
189 frame& fr = (frame&) _fr;
190 MonitorInfo* info = new MonitorInfo(
191 fr.get_native_receiver(), fr.get_native_monitor(), false, false);
192 monitors->push(info);
193 return monitors;
|
41 #include "runtime/stubRoutines.hpp"
42 #include "runtime/vframeArray.hpp"
43 #include "runtime/vframe_hp.hpp"
44 #ifdef COMPILER2
45 #include "opto/matcher.hpp"
46 #endif
47
48
49 // ------------- compiledVFrame --------------
50
51 StackValueCollection* compiledVFrame::locals() const {
52 // Natives has no scope
53 if (scope() == NULL) return new StackValueCollection(0);
54 GrowableArray<ScopeValue*>* scv_list = scope()->locals();
55 if (scv_list == NULL) return new StackValueCollection(0);
56
57 // scv_list is the list of ScopeValues describing the JVM stack state.
58 // There is one scv_list entry for every JVM stack state in use.
59 int length = scv_list->length();
60 StackValueCollection* result = new StackValueCollection(length);
61 GrowableArray<ScopeValue*>* objects = scope()->objects();
62 for (int i = 0; i < length; i++) {
63 result->add(create_stack_value(get_scope_value(scv_list, i, objects)));
64 }
65
66 // Replace the original values with any stores that have been
67 // performed through compiledVFrame::update_locals.
68 GrowableArray<jvmtiDeferredLocalVariableSet*>* list = thread()->deferred_locals();
69 if (list != NULL ) {
70 // In real life this never happens or is typically a single element search
71 for (int i = 0; i < list->length(); i++) {
72 if (list->at(i)->matches(this)) {
73 list->at(i)->update_locals(result);
74 break;
75 }
76 }
77 }
78
79 return result;
80 }
81
82
83 void compiledVFrame::set_locals(StackValueCollection* values) const {
122 thread()->set_deferred_locals(deferred);
123 }
124 if (locals == NULL) {
125 locals = new jvmtiDeferredLocalVariableSet(method(), bci(), fr().id(), vframe_id());
126 deferred->push(locals);
127 assert(locals->id() == fr().id(), "Huh? Must match");
128 }
129 locals->set_value_at(index, type, value);
130 }
131
132 StackValueCollection* compiledVFrame::expressions() const {
133 // Natives has no scope
134 if (scope() == NULL) return new StackValueCollection(0);
135 GrowableArray<ScopeValue*>* scv_list = scope()->expressions();
136 if (scv_list == NULL) return new StackValueCollection(0);
137
138 // scv_list is the list of ScopeValues describing the JVM stack state.
139 // There is one scv_list entry for every JVM stack state in use.
140 int length = scv_list->length();
141 StackValueCollection* result = new StackValueCollection(length);
142 GrowableArray<ScopeValue*>* objects = scope()->objects();
143 for (int i = 0; i < length; i++) {
144 result->add(create_stack_value(get_scope_value(scv_list, i, objects)));
145 }
146
147 // Replace the original values with any stores that have been
148 // performed through compiledVFrame::update_stack.
149 GrowableArray<jvmtiDeferredLocalVariableSet*>* list = thread()->deferred_locals();
150 if (list != NULL ) {
151 // In real life this never happens or is typically a single element search
152 for (int i = 0; i < list->length(); i++) {
153 if (list->at(i)->matches(this)) {
154 list->at(i)->update_stack(result);
155 break;
156 }
157 }
158 }
159
160 return result;
161 }
162
163
164 // The implementation of the following two methods was factorized into the
165 // class StackValue because it is also used from within deoptimization.cpp for
166 // rematerialization and relocking of non-escaping objects.
167
168 StackValue *compiledVFrame::create_stack_value(ScopeValue *sv) const {
169 return StackValue::create_stack_value(&_fr, register_map(), sv);
170 }
171
172 BasicLock* compiledVFrame::resolve_monitor_lock(Location location) const {
173 return StackValue::resolve_monitor_lock(&_fr, location);
174 }
175
176 ScopeValue *compiledVFrame::match_object_to_stack_oop(intptr_t *oop_ptr, intptr_t *sp_base, GrowableArray<ScopeValue*>* objects) const {
177 if (objects == NULL) {
178 return NULL;
179 }
180 for (int j = 0; j < objects->length(); j++) {
181 ScopeValue* o_sv = objects->at(j);
182 if (o_sv->is_object()) {
183 if (o_sv->as_ObjectValue()->is_stack_object()) {
184 StackObjectValue *sov = (StackObjectValue *)o_sv;
185 Location o_loc = sov->get_stack_location();
186 int o_offset = o_loc.stack_offset();
187 int l_offset = (address)oop_ptr - (address)sp_base;
188 if (o_offset == l_offset) {
189 return o_sv;
190 }
191 }
192 }
193 }
194
195 return NULL;
196 }
197
198 ScopeValue *compiledVFrame::get_scope_value(GrowableArray<ScopeValue*>* scv_list, int index, GrowableArray<ScopeValue*>* objects) const {
199 ScopeValue* sv = scv_list->at(index);
200 if (sv->is_location()) {
201 if ((objects != NULL) && (objects->length() > 0)) {
202 //printf("Attempting to swap svs\n");
203 LocationValue* lv = (LocationValue *)sv;
204 Location loc = lv->location();
205 intptr_t *oop_ptr;
206 intptr_t *sp_base = _fr.unextended_sp();
207 intptr_t *sp_top = sp_base + _fr.cb()->frame_size();
208 if (loc.is_stack() && (loc.type() == Location::oop)) {
209 address value_addr = ((address)sp_base) + loc.stack_offset();
210 oop val = *(oop *)value_addr;
211 oop_ptr = cast_from_oop<intptr_t *>(val);
212 } else if (loc.is_register() && (loc.type() == Location::oop)) {
213 address value_addr = register_map()->location(VMRegImpl::as_VMReg(loc.register_number()));
214 oop val = *(oop *)value_addr;
215 oop_ptr = cast_from_oop<intptr_t *>(val);
216 } else {
217 assert(loc.type() != Location::oop, "Can not be an oop");
218 return sv;
219 }
220 if (sp_base <= oop_ptr && oop_ptr < sp_top) {
221 ScopeValue* o_sv = match_object_to_stack_oop(oop_ptr, sp_base, objects);
222 if (o_sv != NULL) {
223 scv_list->at_put(index, o_sv);
224 sv = o_sv;
225 } else {
226 assert(false, "did not find stack oop for object on stack");
227 }
228 }
229 }
230 } else if (sv->is_object()) {
231 oop o = sv->as_ObjectValue()->value()();
232 intptr_t *sp_base = _fr.unextended_sp();
233 intptr_t *sp_top = sp_base + _fr.cb()->frame_size();
234 intptr_t *oop_ptr = cast_from_oop<intptr_t *>(o);
235 if (sp_base <= oop_ptr && oop_ptr < sp_top) {
236 ScopeValue* o_sv = match_object_to_stack_oop(oop_ptr, sp_base, objects);
237 if (o_sv != NULL) {
238 assert(sv == o_sv, "Objects need to match");
239 sv = o_sv;
240 } else {
241 assert(false, "did not find stack oop for object on stack");
242 }
243 }
244 assert(oopDesc::is_oop_or_null(sv->as_ObjectValue()->value()()), "needs to be an oop");
245 }
246 return sv;
247 }
248
249
250 GrowableArray<MonitorInfo*>* compiledVFrame::monitors() const {
251 // Natives has no scope
252 if (scope() == NULL) {
253 CompiledMethod* nm = code();
254 Method* method = nm->method();
255 assert(method->is_native() || nm->is_aot(), "Expect a native method or precompiled method");
256 if (!method->is_synchronized()) {
257 return new GrowableArray<MonitorInfo*>(0);
258 }
259 // This monitor is really only needed for UseBiasedLocking, but
260 // return it in all cases for now as it might be useful for stack
261 // traces and tools as well
262 GrowableArray<MonitorInfo*> *monitors = new GrowableArray<MonitorInfo*>(1);
263 // Casting away const
264 frame& fr = (frame&) _fr;
265 MonitorInfo* info = new MonitorInfo(
266 fr.get_native_receiver(), fr.get_native_monitor(), false, false);
267 monitors->push(info);
268 return monitors;
|