vframe_hp.cpp revision 3602:da91efe96a93
1/*
2 * Copyright (c) 1997, 2012, 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#include "precompiled.hpp"
26#include "code/codeCache.hpp"
27#include "code/debugInfoRec.hpp"
28#include "code/nmethod.hpp"
29#include "code/pcDesc.hpp"
30#include "code/scopeDesc.hpp"
31#include "interpreter/interpreter.hpp"
32#include "interpreter/oopMapCache.hpp"
33#include "oops/instanceKlass.hpp"
34#include "oops/oop.inline.hpp"
35#include "runtime/basicLock.hpp"
36#include "runtime/handles.inline.hpp"
37#include "runtime/monitorChunk.hpp"
38#include "runtime/signature.hpp"
39#include "runtime/stubRoutines.hpp"
40#include "runtime/vframeArray.hpp"
41#include "runtime/vframe_hp.hpp"
42#ifdef COMPILER2
43#include "opto/matcher.hpp"
44#endif
45
46
47// ------------- compiledVFrame --------------
48
49StackValueCollection* compiledVFrame::locals() const {
50  // Natives has no scope
51  if (scope() == NULL) return new StackValueCollection(0);
52  GrowableArray<ScopeValue*>*  scv_list = scope()->locals();
53  if (scv_list == NULL) return new StackValueCollection(0);
54
55  // scv_list is the list of ScopeValues describing the JVM stack state.
56  // There is one scv_list entry for every JVM stack state in use.
57  int length = scv_list->length();
58  StackValueCollection* result = new StackValueCollection(length);
59  // In rare instances set_locals may have occurred in which case
60  // there are local values that are not described by the ScopeValue anymore
61  GrowableArray<jvmtiDeferredLocalVariable*>* deferred = NULL;
62  GrowableArray<jvmtiDeferredLocalVariableSet*>* list = thread()->deferred_locals();
63  if (list != NULL ) {
64    // In real life this never happens or is typically a single element search
65    for (int i = 0; i < list->length(); i++) {
66      if (list->at(i)->matches((vframe*)this)) {
67        deferred = list->at(i)->locals();
68        break;
69      }
70    }
71  }
72
73  for( int i = 0; i < length; i++ ) {
74    result->add( create_stack_value(scv_list->at(i)) );
75  }
76
77  // Replace specified locals with any deferred writes that are present
78  if (deferred != NULL) {
79    for ( int l = 0;  l < deferred->length() ; l ++) {
80      jvmtiDeferredLocalVariable* val = deferred->at(l);
81      switch (val->type()) {
82      case T_BOOLEAN:
83        result->set_int_at(val->index(), val->value().z);
84        break;
85      case T_CHAR:
86        result->set_int_at(val->index(), val->value().c);
87        break;
88      case T_FLOAT:
89        result->set_float_at(val->index(), val->value().f);
90        break;
91      case T_DOUBLE:
92        result->set_double_at(val->index(), val->value().d);
93        break;
94      case T_BYTE:
95        result->set_int_at(val->index(), val->value().b);
96        break;
97      case T_SHORT:
98        result->set_int_at(val->index(), val->value().s);
99        break;
100      case T_INT:
101        result->set_int_at(val->index(), val->value().i);
102        break;
103      case T_LONG:
104        result->set_long_at(val->index(), val->value().j);
105        break;
106      case T_OBJECT:
107        {
108          Handle obj((oop)val->value().l);
109          result->set_obj_at(val->index(), obj);
110        }
111        break;
112      default:
113        ShouldNotReachHere();
114      }
115    }
116  }
117
118  return result;
119}
120
121
122void compiledVFrame::set_locals(StackValueCollection* values) const {
123
124  fatal("Should use update_local for each local update");
125}
126
127void compiledVFrame::update_local(BasicType type, int index, jvalue value) {
128
129#ifdef ASSERT
130
131  assert(fr().is_deoptimized_frame(), "frame must be scheduled for deoptimization");
132#endif /* ASSERT */
133  GrowableArray<jvmtiDeferredLocalVariableSet*>* deferred = thread()->deferred_locals();
134  if (deferred != NULL ) {
135    // See if this vframe has already had locals with deferred writes
136    int f;
137    for ( f = 0 ; f < deferred->length() ; f++ ) {
138      if (deferred->at(f)->matches(this)) {
139        // Matching, vframe now see if the local already had deferred write
140        GrowableArray<jvmtiDeferredLocalVariable*>* locals = deferred->at(f)->locals();
141        int l;
142        for (l = 0 ; l < locals->length() ; l++ ) {
143          if (locals->at(l)->index() == index) {
144            locals->at(l)->set_value(value);
145            return;
146          }
147        }
148        // No matching local already present. Push a new value onto the deferred collection
149        locals->push(new jvmtiDeferredLocalVariable(index, type, value));
150        return;
151      }
152    }
153    // No matching vframe must push a new vframe
154  } else {
155    // No deferred updates pending for this thread.
156    // allocate in C heap
157    deferred =  new(ResourceObj::C_HEAP, mtCompiler) GrowableArray<jvmtiDeferredLocalVariableSet*> (1, true);
158    thread()->set_deferred_locals(deferred);
159  }
160  deferred->push(new jvmtiDeferredLocalVariableSet(method(), bci(), fr().id()));
161  assert(deferred->top()->id() == fr().id(), "Huh? Must match");
162  deferred->top()->set_local_at(index, type, value);
163}
164
165StackValueCollection* compiledVFrame::expressions() const {
166  // Natives has no scope
167  if (scope() == NULL) return new StackValueCollection(0);
168  GrowableArray<ScopeValue*>*  scv_list = scope()->expressions();
169  if (scv_list == NULL) return new StackValueCollection(0);
170
171  // scv_list is the list of ScopeValues describing the JVM stack state.
172  // There is one scv_list entry for every JVM stack state in use.
173  int length = scv_list->length();
174  StackValueCollection* result = new StackValueCollection(length);
175  for( int i = 0; i < length; i++ )
176    result->add( create_stack_value(scv_list->at(i)) );
177
178  return result;
179}
180
181
182// The implementation of the following two methods was factorized into the
183// class StackValue because it is also used from within deoptimization.cpp for
184// rematerialization and relocking of non-escaping objects.
185
186StackValue *compiledVFrame::create_stack_value(ScopeValue *sv) const {
187  return StackValue::create_stack_value(&_fr, register_map(), sv);
188}
189
190BasicLock* compiledVFrame::resolve_monitor_lock(Location location) const {
191  return StackValue::resolve_monitor_lock(&_fr, location);
192}
193
194
195GrowableArray<MonitorInfo*>* compiledVFrame::monitors() const {
196  // Natives has no scope
197  if (scope() == NULL) {
198    nmethod* nm = code();
199    Method* method = nm->method();
200    assert(method->is_native(), "");
201    if (!method->is_synchronized()) {
202      return new GrowableArray<MonitorInfo*>(0);
203    }
204    // This monitor is really only needed for UseBiasedLocking, but
205    // return it in all cases for now as it might be useful for stack
206    // traces and tools as well
207    GrowableArray<MonitorInfo*> *monitors = new GrowableArray<MonitorInfo*>(1);
208    // Casting away const
209    frame& fr = (frame&) _fr;
210    MonitorInfo* info = new MonitorInfo(
211        fr.get_native_receiver(), fr.get_native_monitor(), false, false);
212    monitors->push(info);
213    return monitors;
214  }
215  GrowableArray<MonitorValue*>* monitors = scope()->monitors();
216  if (monitors == NULL) {
217    return new GrowableArray<MonitorInfo*>(0);
218  }
219  GrowableArray<MonitorInfo*>* result = new GrowableArray<MonitorInfo*>(monitors->length());
220  for (int index = 0; index < monitors->length(); index++) {
221    MonitorValue* mv = monitors->at(index);
222    ScopeValue*   ov = mv->owner();
223    StackValue *owner_sv = create_stack_value(ov); // it is an oop
224    if (ov->is_object() && owner_sv->obj_is_scalar_replaced()) { // The owner object was scalar replaced
225      assert(mv->eliminated(), "monitor should be eliminated for scalar replaced object");
226      // Put klass for scalar replaced object.
227      ScopeValue* kv = ((ObjectValue *)ov)->klass();
228      assert(kv->is_constant_oop(), "klass should be oop constant for scalar replaced object");
229      Handle k(((ConstantOopReadValue*)kv)->value()());
230      assert(java_lang_Class::is_instance(k()), "must be");
231      result->push(new MonitorInfo(k(), resolve_monitor_lock(mv->basic_lock()),
232                                   mv->eliminated(), true));
233    } else {
234      result->push(new MonitorInfo(owner_sv->get_obj()(), resolve_monitor_lock(mv->basic_lock()),
235                                   mv->eliminated(), false));
236    }
237  }
238  return result;
239}
240
241
242compiledVFrame::compiledVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread, nmethod* nm)
243: javaVFrame(fr, reg_map, thread) {
244  _scope  = NULL;
245  // Compiled method (native stub or Java code)
246  // native wrappers have no scope data, it is implied
247  if (!nm->is_native_method()) {
248    _scope  = nm->scope_desc_at(_fr.pc());
249  }
250}
251
252compiledVFrame::compiledVFrame(const frame* fr, const RegisterMap* reg_map, JavaThread* thread, ScopeDesc* scope)
253: javaVFrame(fr, reg_map, thread) {
254  _scope  = scope;
255  guarantee(_scope != NULL, "scope must be present");
256}
257
258
259bool compiledVFrame::is_top() const {
260  // FIX IT: Remove this when new native stubs are in place
261  if (scope() == NULL) return true;
262  return scope()->is_top();
263}
264
265
266nmethod* compiledVFrame::code() const {
267  return CodeCache::find_nmethod(_fr.pc());
268}
269
270
271Method* compiledVFrame::method() const {
272  if (scope() == NULL) {
273    // native nmethods have no scope the method is implied
274    nmethod* nm = code();
275    assert(nm->is_native_method(), "must be native");
276    return nm->method();
277  }
278  return scope()->method();
279}
280
281
282int compiledVFrame::bci() const {
283  int raw = raw_bci();
284  return raw == SynchronizationEntryBCI ? 0 : raw;
285}
286
287
288int compiledVFrame::raw_bci() const {
289  if (scope() == NULL) {
290    // native nmethods have no scope the method/bci is implied
291    nmethod* nm = code();
292    assert(nm->is_native_method(), "must be native");
293    return 0;
294  }
295  return scope()->bci();
296}
297
298bool compiledVFrame::should_reexecute() const {
299  if (scope() == NULL) {
300    // native nmethods have no scope the method/bci is implied
301    nmethod* nm = code();
302    assert(nm->is_native_method(), "must be native");
303    return false;
304  }
305  return scope()->should_reexecute();
306}
307
308vframe* compiledVFrame::sender() const {
309  const frame f = fr();
310  if (scope() == NULL) {
311    // native nmethods have no scope the method/bci is implied
312    nmethod* nm = code();
313    assert(nm->is_native_method(), "must be native");
314    return vframe::sender();
315  } else {
316    return scope()->is_top()
317      ? vframe::sender()
318      : new compiledVFrame(&f, register_map(), thread(), scope()->sender());
319  }
320}
321
322jvmtiDeferredLocalVariableSet::jvmtiDeferredLocalVariableSet(Method* method, int bci, intptr_t* id) {
323  _method = method;
324  _bci = bci;
325  _id = id;
326  // Alway will need at least one, must be on C heap
327  _locals = new(ResourceObj::C_HEAP, mtCompiler) GrowableArray<jvmtiDeferredLocalVariable*> (1, true);
328}
329
330jvmtiDeferredLocalVariableSet::~jvmtiDeferredLocalVariableSet() {
331  for (int i = 0; i < _locals->length() ; i++ ) {
332    delete _locals->at(i);
333  }
334  // Free growableArray and c heap for elements
335  delete _locals;
336}
337
338bool jvmtiDeferredLocalVariableSet::matches(vframe* vf) {
339  if (!vf->is_compiled_frame()) return false;
340  compiledVFrame* cvf = (compiledVFrame*)vf;
341  return cvf->fr().id() == id() && cvf->method() == method() && cvf->bci() == bci();
342}
343
344void jvmtiDeferredLocalVariableSet::set_local_at(int idx, BasicType type, jvalue val) {
345  int i;
346  for ( i = 0 ; i < locals()->length() ; i++ ) {
347    if ( locals()->at(i)->index() == idx) {
348      assert(locals()->at(i)->type() == type, "Wrong type");
349      locals()->at(i)->set_value(val);
350      return;
351    }
352  }
353  locals()->push(new jvmtiDeferredLocalVariable(idx, type, val));
354}
355
356void jvmtiDeferredLocalVariableSet::oops_do(OopClosure* f) {
357  // The Method* is on the stack so a live activation keeps it alive
358  // either by mirror in interpreter or code in compiled code.
359  for ( int i = 0; i < locals()->length(); i++ ) {
360    if ( locals()->at(i)->type() == T_OBJECT) {
361      f->do_oop(locals()->at(i)->oop_addr());
362    }
363  }
364}
365
366jvmtiDeferredLocalVariable::jvmtiDeferredLocalVariable(int index, BasicType type, jvalue value) {
367  _index = index;
368  _type = type;
369  _value = value;
370}
371
372
373#ifndef PRODUCT
374void compiledVFrame::verify() const {
375  Unimplemented();
376}
377#endif // PRODUCT
378