< prev index next >

src/hotspot/share/runtime/vframe_hp.cpp

Print this page

 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 #include "precompiled.hpp"
 26 #include "classfile/javaClasses.inline.hpp"
 27 #include "code/codeCache.hpp"
 28 #include "code/debugInfoRec.hpp"
 29 #include "code/nmethod.hpp"
 30 #include "code/pcDesc.hpp"
 31 #include "code/scopeDesc.hpp"
 32 #include "interpreter/interpreter.hpp"
 33 #include "interpreter/oopMapCache.hpp"
 34 #include "oops/instanceKlass.hpp"
 35 #include "oops/oop.inline.hpp"
 36 #include "prims/jvmtiDeferredUpdates.hpp"
 37 #include "runtime/basicLock.hpp"

 38 #include "runtime/frame.inline.hpp"
 39 #include "runtime/handles.inline.hpp"
 40 #include "runtime/monitorChunk.hpp"

 41 #include "runtime/signature.hpp"
 42 #include "runtime/stubRoutines.hpp"
 43 #include "runtime/vframeArray.hpp"
 44 #include "runtime/vframe_hp.hpp"
 45 #ifdef COMPILER2
 46 #include "opto/matcher.hpp"
 47 #endif
 48 
 49 
 50 // ------------- compiledVFrame --------------
 51 
 52 StackValueCollection* compiledVFrame::locals() const {
 53   // Natives has no scope
 54   if (scope() == NULL) return new StackValueCollection(0);
 55   GrowableArray<ScopeValue*>*  scv_list = scope()->locals();
 56   if (scv_list == NULL) return new StackValueCollection(0);
 57 
 58   // scv_list is the list of ScopeValues describing the JVM stack state.
 59   // There is one scv_list entry for every JVM stack state in use.
 60   int length = scv_list->length();
 61   StackValueCollection* result = new StackValueCollection(length);
 62   for (int i = 0; i < length; i++) {
 63     result->add(create_stack_value(scv_list->at(i)));
 64   }
 65 
 66   // Replace the original values with any stores that have been
 67   // performed through compiledVFrame::update_locals.
 68   GrowableArray<jvmtiDeferredLocalVariableSet*>* list = JvmtiDeferredUpdates::deferred_locals(thread());
 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 {
 84 
 85   fatal("Should use update_local for each local update");
 86 }
 87 
 88 void compiledVFrame::update_local(BasicType type, int index, jvalue value) {
 89   assert(index >= 0 && index < method()->max_locals(), "out of bounds");
 90   update_deferred_value(type, index, value);
 91 }
 92 
 93 void compiledVFrame::update_stack(BasicType type, int index, jvalue value) {
 94   assert(index >= 0 && index < method()->max_stack(), "out of bounds");
 95   update_deferred_value(type, index + method()->max_locals(), value);
 96 }
 97 
 98 void compiledVFrame::update_monitor(int index, MonitorInfo* val) {
 99   assert(index >= 0, "out of bounds");
100   jvalue value;
101   value.l = cast_from_oop<jobject>(val->owner());
102   update_deferred_value(T_OBJECT, index + method()->max_locals() + method()->max_stack(), value);
103 }
104 
105 void compiledVFrame::update_deferred_value(BasicType type, int index, jvalue value) {
106   assert(fr().is_deoptimized_frame(), "frame must be scheduled for deoptimization");

107   GrowableArray<jvmtiDeferredLocalVariableSet*>* deferred = JvmtiDeferredUpdates::deferred_locals(thread());
108   jvmtiDeferredLocalVariableSet* locals = NULL;
109   if (deferred != NULL ) {
110     // See if this vframe has already had locals with deferred writes
111     for (int f = 0; f < deferred->length(); f++ ) {
112       if (deferred->at(f)->matches(this)) {
113         locals = deferred->at(f);
114         break;
115       }
116     }
117     // No matching vframe must push a new vframe
118   } else {
119     // No deferred updates pending for this thread.
120     // allocate in C heap
121     JvmtiDeferredUpdates::create_for(thread());
122     deferred = JvmtiDeferredUpdates::deferred_locals(thread());
123   }
124   if (locals == NULL) {
125     locals = new jvmtiDeferredLocalVariableSet(method(), bci(), fr().id(), vframe_id());
126     deferred->push(locals);

176         update_monitor(i2, mtrs->at(i2));
177       }
178     }
179   }
180 }
181 
182 StackValueCollection* compiledVFrame::expressions() const {
183   // Natives has no scope
184   if (scope() == NULL) return new StackValueCollection(0);
185   GrowableArray<ScopeValue*>*  scv_list = scope()->expressions();
186   if (scv_list == NULL) return new StackValueCollection(0);
187 
188   // scv_list is the list of ScopeValues describing the JVM stack state.
189   // There is one scv_list entry for every JVM stack state in use.
190   int length = scv_list->length();
191   StackValueCollection* result = new StackValueCollection(length);
192   for (int i = 0; i < length; i++) {
193     result->add(create_stack_value(scv_list->at(i)));
194   }
195 
196   // Replace the original values with any stores that have been
197   // performed through compiledVFrame::update_stack.
198   GrowableArray<jvmtiDeferredLocalVariableSet*>* list = JvmtiDeferredUpdates::deferred_locals(thread());
199   if (list != NULL ) {
200     // In real life this never happens or is typically a single element search
201     for (int i = 0; i < list->length(); i++) {
202       if (list->at(i)->matches(this)) {
203         list->at(i)->update_stack(result);
204         break;


205       }
206     }
207   }
208 
209   return result;
210 }
211 
212 
213 // The implementation of the following two methods was factorized into the
214 // class StackValue because it is also used from within deoptimization.cpp for
215 // rematerialization and relocking of non-escaping objects.
216 
217 StackValue *compiledVFrame::create_stack_value(ScopeValue *sv) const {
218   return StackValue::create_stack_value(&_fr, register_map(), sv);






219 }
220 
221 BasicLock* compiledVFrame::resolve_monitor_lock(Location location) const {
222   return StackValue::resolve_monitor_lock(&_fr, location);
223 }
224 
225 
226 GrowableArray<MonitorInfo*>* compiledVFrame::monitors() const {
227   // Natives has no scope
228   if (scope() == NULL) {
229     CompiledMethod* nm = code();
230     Method* method = nm->method();
231     assert(method->is_native(), "Expect a native method");
232     if (!method->is_synchronized()) {
233       return new GrowableArray<MonitorInfo*>(0);
234     }
235     // This monitor is not really needed but return it for now as it might be
236     // useful for stack traces and tools
237     GrowableArray<MonitorInfo*> *monitors = new GrowableArray<MonitorInfo*>(1);
238     // Casting away const

 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 #include "precompiled.hpp"
 26 #include "classfile/javaClasses.inline.hpp"
 27 #include "code/codeCache.hpp"
 28 #include "code/debugInfoRec.hpp"
 29 #include "code/nmethod.hpp"
 30 #include "code/pcDesc.hpp"
 31 #include "code/scopeDesc.hpp"
 32 #include "interpreter/interpreter.hpp"
 33 #include "interpreter/oopMapCache.hpp"
 34 #include "oops/instanceKlass.hpp"
 35 #include "oops/oop.inline.hpp"
 36 #include "prims/jvmtiDeferredUpdates.hpp"
 37 #include "runtime/basicLock.hpp"
 38 #include "runtime/continuation.hpp"
 39 #include "runtime/frame.inline.hpp"
 40 #include "runtime/handles.inline.hpp"
 41 #include "runtime/monitorChunk.hpp"
 42 #include "runtime/registerMap.hpp"
 43 #include "runtime/signature.hpp"
 44 #include "runtime/stubRoutines.hpp"
 45 #include "runtime/vframeArray.hpp"
 46 #include "runtime/vframe_hp.hpp"
 47 #ifdef COMPILER2
 48 #include "opto/matcher.hpp"
 49 #endif
 50 
 51 
 52 // ------------- compiledVFrame --------------
 53 
 54 StackValueCollection* compiledVFrame::locals() const {
 55   // Natives has no scope
 56   if (scope() == NULL) return new StackValueCollection(0);
 57   GrowableArray<ScopeValue*>*  scv_list = scope()->locals();
 58   if (scv_list == NULL) return new StackValueCollection(0);
 59 
 60   // scv_list is the list of ScopeValues describing the JVM stack state.
 61   // There is one scv_list entry for every JVM stack state in use.
 62   int length = scv_list->length();
 63   StackValueCollection* result = new StackValueCollection(length);
 64   for (int i = 0; i < length; i++) {
 65     result->add(create_stack_value(scv_list->at(i)));
 66   }
 67 
 68   // Replace the original values with any stores that have been
 69   // performed through compiledVFrame::update_locals.
 70   if (!register_map()->in_cont()) { // LOOM TODO
 71     GrowableArray<jvmtiDeferredLocalVariableSet*>* list = JvmtiDeferredUpdates::deferred_locals(thread());
 72     if (list != NULL ) {
 73       // In real life this never happens or is typically a single element search
 74       for (int i = 0; i < list->length(); i++) {
 75         if (list->at(i)->matches(this)) {
 76           list->at(i)->update_locals(result);
 77           break;
 78         }
 79       }
 80     }
 81   }
 82 
 83   return result;
 84 }
 85 
 86 
 87 void compiledVFrame::set_locals(StackValueCollection* values) const {
 88 
 89   fatal("Should use update_local for each local update");
 90 }
 91 
 92 void compiledVFrame::update_local(BasicType type, int index, jvalue value) {
 93   assert(index >= 0 && index < method()->max_locals(), "out of bounds");
 94   update_deferred_value(type, index, value);
 95 }
 96 
 97 void compiledVFrame::update_stack(BasicType type, int index, jvalue value) {
 98   assert(index >= 0 && index < method()->max_stack(), "out of bounds");
 99   update_deferred_value(type, index + method()->max_locals(), value);
100 }
101 
102 void compiledVFrame::update_monitor(int index, MonitorInfo* val) {
103   assert(index >= 0, "out of bounds");
104   jvalue value;
105   value.l = cast_from_oop<jobject>(val->owner());
106   update_deferred_value(T_OBJECT, index + method()->max_locals() + method()->max_stack(), value);
107 }
108 
109 void compiledVFrame::update_deferred_value(BasicType type, int index, jvalue value) {
110   assert(fr().is_deoptimized_frame(), "frame must be scheduled for deoptimization");
111   assert(!Continuation::is_frame_in_continuation(thread(), fr()), "No support for deferred values in continuations");
112   GrowableArray<jvmtiDeferredLocalVariableSet*>* deferred = JvmtiDeferredUpdates::deferred_locals(thread());
113   jvmtiDeferredLocalVariableSet* locals = NULL;
114   if (deferred != NULL ) {
115     // See if this vframe has already had locals with deferred writes
116     for (int f = 0; f < deferred->length(); f++ ) {
117       if (deferred->at(f)->matches(this)) {
118         locals = deferred->at(f);
119         break;
120       }
121     }
122     // No matching vframe must push a new vframe
123   } else {
124     // No deferred updates pending for this thread.
125     // allocate in C heap
126     JvmtiDeferredUpdates::create_for(thread());
127     deferred = JvmtiDeferredUpdates::deferred_locals(thread());
128   }
129   if (locals == NULL) {
130     locals = new jvmtiDeferredLocalVariableSet(method(), bci(), fr().id(), vframe_id());
131     deferred->push(locals);

181         update_monitor(i2, mtrs->at(i2));
182       }
183     }
184   }
185 }
186 
187 StackValueCollection* compiledVFrame::expressions() const {
188   // Natives has no scope
189   if (scope() == NULL) return new StackValueCollection(0);
190   GrowableArray<ScopeValue*>*  scv_list = scope()->expressions();
191   if (scv_list == NULL) return new StackValueCollection(0);
192 
193   // scv_list is the list of ScopeValues describing the JVM stack state.
194   // There is one scv_list entry for every JVM stack state in use.
195   int length = scv_list->length();
196   StackValueCollection* result = new StackValueCollection(length);
197   for (int i = 0; i < length; i++) {
198     result->add(create_stack_value(scv_list->at(i)));
199   }
200 
201   if (!register_map()->in_cont()) { // LOOM TODO
202     // Replace the original values with any stores that have been
203     // performed through compiledVFrame::update_stack.
204     GrowableArray<jvmtiDeferredLocalVariableSet*>* list = JvmtiDeferredUpdates::deferred_locals(thread());
205     if (list != NULL ) {
206       // In real life this never happens or is typically a single element search
207       for (int i = 0; i < list->length(); i++) {
208         if (list->at(i)->matches(this)) {
209           list->at(i)->update_stack(result);
210           break;
211         }
212       }
213     }
214   }
215 
216   return result;
217 }
218 
219 
220 // The implementation of the following two methods was factorized into the
221 // class StackValue because it is also used from within deoptimization.cpp for
222 // rematerialization and relocking of non-escaping objects.
223 
224 StackValue *compiledVFrame::create_stack_value(ScopeValue *sv) const {
225   stackChunkOop c = _reg_map.stack_chunk()();
226   const_cast<RegisterMap*>(&_reg_map)->set_stack_chunk(_chunk());
227 
228   StackValue* res = StackValue::create_stack_value(&_fr, register_map(), sv);
229   
230   const_cast<RegisterMap*>(&_reg_map)->set_stack_chunk(c);
231   return res;
232 }
233 
234 BasicLock* compiledVFrame::resolve_monitor_lock(Location location) const {
235   return StackValue::resolve_monitor_lock(&_fr, location);
236 }
237 
238 
239 GrowableArray<MonitorInfo*>* compiledVFrame::monitors() const {
240   // Natives has no scope
241   if (scope() == NULL) {
242     CompiledMethod* nm = code();
243     Method* method = nm->method();
244     assert(method->is_native(), "Expect a native method");
245     if (!method->is_synchronized()) {
246       return new GrowableArray<MonitorInfo*>(0);
247     }
248     // This monitor is not really needed but return it for now as it might be
249     // useful for stack traces and tools
250     GrowableArray<MonitorInfo*> *monitors = new GrowableArray<MonitorInfo*>(1);
251     // Casting away const
< prev index next >