8215205: javaVFrame much slower than vframeStream
Reviewed-by: mchung, thartmann
This commit is contained in:
parent
84105b36fd
commit
32ea2e5343
src/hotspot/share
@ -51,9 +51,9 @@ ScopeDesc::ScopeDesc(const CompiledMethod* code, int decode_offset, bool reexecu
|
||||
}
|
||||
|
||||
|
||||
ScopeDesc::ScopeDesc(const ScopeDesc* parent) {
|
||||
void ScopeDesc::initialize(const ScopeDesc* parent, int decode_offset) {
|
||||
_code = parent->_code;
|
||||
_decode_offset = parent->_sender_decode_offset;
|
||||
_decode_offset = decode_offset;
|
||||
_objects = parent->_objects;
|
||||
_reexecute = false; //reexecute only applies to the first scope
|
||||
_rethrow_exception = false;
|
||||
@ -61,6 +61,14 @@ ScopeDesc::ScopeDesc(const ScopeDesc* parent) {
|
||||
decode_body();
|
||||
}
|
||||
|
||||
ScopeDesc::ScopeDesc(const ScopeDesc* parent) {
|
||||
initialize(parent, parent->_sender_decode_offset);
|
||||
}
|
||||
|
||||
ScopeDesc::ScopeDesc(const ScopeDesc* parent, int decode_offset) {
|
||||
initialize(parent, decode_offset);
|
||||
}
|
||||
|
||||
|
||||
void ScopeDesc::decode_body() {
|
||||
if (decode_offset() == DebugInformationRecorder::serialized_null) {
|
||||
|
@ -67,6 +67,9 @@ class ScopeDesc : public ResourceObj {
|
||||
// avoid a .hpp-.hpp dependency.)
|
||||
ScopeDesc(const CompiledMethod* code, int decode_offset, bool reexecute, bool rethrow_exception, bool return_oop);
|
||||
|
||||
// Direct access to scope
|
||||
ScopeDesc* at_offset(int decode_offset) { return new ScopeDesc(this, decode_offset); }
|
||||
|
||||
// JVM state
|
||||
Method* method() const { return _method; }
|
||||
int bci() const { return _bci; }
|
||||
@ -85,12 +88,16 @@ class ScopeDesc : public ResourceObj {
|
||||
// Returns where the scope was decoded
|
||||
int decode_offset() const { return _decode_offset; }
|
||||
|
||||
int sender_decode_offset() const { return _sender_decode_offset; }
|
||||
|
||||
// Tells whether sender() returns NULL
|
||||
bool is_top() const;
|
||||
|
||||
private:
|
||||
// Alternative constructor
|
||||
void initialize(const ScopeDesc* parent, int decode_offset);
|
||||
// Alternative constructors
|
||||
ScopeDesc(const ScopeDesc* parent);
|
||||
ScopeDesc(const ScopeDesc* parent, int decode_offset);
|
||||
|
||||
// JVM state
|
||||
Method* _method;
|
||||
|
@ -452,8 +452,10 @@ vframeStream::vframeStream(JavaThread* thread, frame top_frame,
|
||||
_stop_at_java_call_stub = stop_at_java_call_stub;
|
||||
|
||||
// skip top frame, as it may not be at safepoint
|
||||
_prev_frame = top_frame;
|
||||
_frame = top_frame.sender(&_reg_map);
|
||||
while (!fill_from_frame()) {
|
||||
_prev_frame = _frame;
|
||||
_frame = _frame.sender(&_reg_map);
|
||||
}
|
||||
}
|
||||
@ -534,6 +536,37 @@ void vframeStreamCommon::skip_reflection_related_frames() {
|
||||
}
|
||||
}
|
||||
|
||||
javaVFrame* vframeStreamCommon::asJavaVFrame() {
|
||||
javaVFrame* result = NULL;
|
||||
if (_mode == compiled_mode) {
|
||||
guarantee(_frame.is_compiled_frame(), "expected compiled Java frame");
|
||||
|
||||
// lazy update to register map
|
||||
bool update_map = true;
|
||||
RegisterMap map(_thread, update_map);
|
||||
frame f = _prev_frame.sender(&map);
|
||||
|
||||
guarantee(f.is_compiled_frame(), "expected compiled Java frame");
|
||||
|
||||
compiledVFrame* cvf = compiledVFrame::cast(vframe::new_vframe(&f, &map, _thread));
|
||||
|
||||
guarantee(cvf->cb() == cb(), "wrong code blob");
|
||||
|
||||
// get the same scope as this stream
|
||||
cvf = cvf->at_scope(_decode_offset, _vframe_id);
|
||||
|
||||
guarantee(cvf->scope()->decode_offset() == _decode_offset, "wrong scope");
|
||||
guarantee(cvf->scope()->sender_decode_offset() == _sender_decode_offset, "wrong scope");
|
||||
guarantee(cvf->vframe_id() == _vframe_id, "wrong vframe");
|
||||
|
||||
result = cvf;
|
||||
} else {
|
||||
result = javaVFrame::cast(vframe::new_vframe(&_frame, &_reg_map, _thread));
|
||||
}
|
||||
guarantee(result->method() == method(), "wrong method");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#ifndef PRODUCT
|
||||
void vframe::print() {
|
||||
|
@ -278,12 +278,16 @@ class MonitorInfo : public ResourceObj {
|
||||
class vframeStreamCommon : StackObj {
|
||||
protected:
|
||||
// common
|
||||
frame _prev_frame;
|
||||
frame _frame;
|
||||
JavaThread* _thread;
|
||||
RegisterMap _reg_map;
|
||||
enum { interpreted_mode, compiled_mode, at_end_mode } _mode;
|
||||
|
||||
// For compiled_mode
|
||||
int _decode_offset;
|
||||
int _sender_decode_offset;
|
||||
int _vframe_id;
|
||||
|
||||
// Cached information
|
||||
Method* _method;
|
||||
@ -320,6 +324,8 @@ class vframeStreamCommon : StackObj {
|
||||
return (CompiledMethod*) cb();
|
||||
}
|
||||
|
||||
javaVFrame* asJavaVFrame();
|
||||
|
||||
// Frame type
|
||||
inline bool is_interpreted_frame() const;
|
||||
inline bool is_entry_frame() const;
|
||||
|
@ -44,6 +44,7 @@ inline void vframeStreamCommon::next() {
|
||||
|
||||
// handle general case
|
||||
do {
|
||||
_prev_frame = _frame;
|
||||
_frame = _frame.sender(&_reg_map);
|
||||
} while (!fill_from_frame());
|
||||
}
|
||||
@ -59,6 +60,7 @@ inline vframeStream::vframeStream(JavaThread* thread, bool stop_at_java_call_stu
|
||||
|
||||
_frame = _thread->last_frame();
|
||||
while (!fill_from_frame()) {
|
||||
_prev_frame = _frame;
|
||||
_frame = _frame.sender(&_reg_map);
|
||||
}
|
||||
}
|
||||
@ -68,12 +70,14 @@ inline bool vframeStreamCommon::fill_in_compiled_inlined_sender() {
|
||||
return false;
|
||||
}
|
||||
fill_from_compiled_frame(_sender_decode_offset);
|
||||
++_vframe_id;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
inline void vframeStreamCommon::fill_from_compiled_frame(int decode_offset) {
|
||||
_mode = compiled_mode;
|
||||
_decode_offset = decode_offset;
|
||||
|
||||
// Range check to detect ridiculous offsets.
|
||||
if (decode_offset == DebugInformationRecorder::serialized_null ||
|
||||
@ -118,6 +122,8 @@ inline void vframeStreamCommon::fill_from_compiled_frame(int decode_offset) {
|
||||
inline void vframeStreamCommon::fill_from_compiled_native_frame() {
|
||||
_mode = compiled_mode;
|
||||
_sender_decode_offset = DebugInformationRecorder::serialized_null;
|
||||
_decode_offset = DebugInformationRecorder::serialized_null;
|
||||
_vframe_id = 0;
|
||||
_method = nm()->method();
|
||||
_bci = 0;
|
||||
}
|
||||
@ -187,6 +193,7 @@ inline bool vframeStreamCommon::fill_from_frame() {
|
||||
decode_offset = pc_desc->scope_decode_offset();
|
||||
}
|
||||
fill_from_compiled_frame(decode_offset);
|
||||
_vframe_id = 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -252,6 +252,14 @@ compiledVFrame::compiledVFrame(const frame* fr, const RegisterMap* reg_map, Java
|
||||
guarantee(_scope != NULL, "scope must be present");
|
||||
}
|
||||
|
||||
compiledVFrame* compiledVFrame::at_scope(int decode_offset, int vframe_id) {
|
||||
if (scope()->decode_offset() != decode_offset) {
|
||||
ScopeDesc* scope = this->scope()->at_offset(decode_offset);
|
||||
return new compiledVFrame(frame_pointer(), register_map(), thread(), scope, vframe_id);
|
||||
}
|
||||
assert(_vframe_id == vframe_id, "wrong frame id");
|
||||
return this;
|
||||
}
|
||||
|
||||
bool compiledVFrame::is_top() const {
|
||||
// FIX IT: Remove this when new native stubs are in place
|
||||
|
@ -72,6 +72,9 @@ class compiledVFrame: public javaVFrame {
|
||||
// Returns the scopeDesc
|
||||
ScopeDesc* scope() const { return _scope; }
|
||||
|
||||
// Return the compiledVFrame for the desired scope
|
||||
compiledVFrame* at_scope(int decode_offset, int vframe_id);
|
||||
|
||||
// Returns SynchronizationEntryBCI or bci() (used for synchronization)
|
||||
int raw_bci() const;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user