Skip to content
This repository was archived by the owner on Aug 16, 2023. It is now read-only.

Commit 89b5bd4

Browse files
committed
[GR-8809] Use implicit exception table for dispatch and printing.
PullRequest: graal-jvmci-8/44
2 parents b7f293a + 111dbfd commit 89b5bd4

File tree

10 files changed

+104
-59
lines changed

10 files changed

+104
-59
lines changed

src/share/vm/code/exceptionHandlerTable.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ void ImplicitExceptionTable::append( uint exec_off, uint cont_off ) {
175175
_len = l+1;
176176
};
177177

178-
uint ImplicitExceptionTable::at( uint exec_off ) const {
178+
uint ImplicitExceptionTable::continuation_offset( uint exec_off ) const {
179179
uint l = len();
180180
for( uint i=0; i<l; i++ )
181181
if( *adr(i) == exec_off )

src/share/vm/code/exceptionHandlerTable.hpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,16 +144,32 @@ class ImplicitExceptionTable VALUE_OBJ_CLASS_SPEC {
144144
implicit_null_entry *_data;
145145
implicit_null_entry *adr( uint idx ) const { return &_data[2*idx]; }
146146
ReallocMark _nesting; // assertion check for reallocations
147+
147148
public:
148149
ImplicitExceptionTable( ) : _data(0), _size(0), _len(0) { }
149150
// (run-time) construction from nmethod
150151
ImplicitExceptionTable( const nmethod *nm );
151152

152153
void set_size( uint size );
153154
void append( uint exec_off, uint cont_off );
154-
uint at( uint exec_off ) const;
155+
156+
#ifdef INCLUDE_JVMCI
157+
void add_deoptimize(uint exec_off) {
158+
// Use the same offset as a marker value for deoptimization
159+
append(exec_off, exec_off);
160+
}
161+
#endif
162+
163+
// Returns the offset to continue execution at. If the returned
164+
// value equals exec_off then the dispatch is expected to be a
165+
// deoptimization instead.
166+
uint continuation_offset( uint exec_off ) const;
155167

156168
uint len() const { return _len; }
169+
170+
uint get_exec_offset(uint i) { assert(i < _len, "oob"); return *adr(i); }
171+
uint get_cont_offset(uint i) { assert(i < _len, "oob"); return *(adr(i) + 1); }
172+
157173
int size_in_bytes() const { return len() == 0 ? 0 : ((2 * len() + 1) * sizeof(implicit_null_entry)); }
158174

159175
void copy_to(nmethod* nm);

src/share/vm/code/nmethod.cpp

Lines changed: 66 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "oops/methodData.hpp"
3838
#include "prims/jvmtiRedefineClassesTrace.hpp"
3939
#include "prims/jvmtiImpl.hpp"
40+
#include "runtime/deoptimization.hpp"
4041
#include "runtime/orderAccess.inline.hpp"
4142
#include "runtime/sharedRuntime.hpp"
4243
#include "runtime/sweeper.hpp"
@@ -1136,6 +1137,7 @@ void nmethod::print_nmethod(bool printmethod) {
11361137
ttyLocker ttyl; // keep the following output all in one block
11371138
if (xtty != NULL) {
11381139
xtty->begin_head("print_nmethod");
1140+
log_identity(xtty);
11391141
xtty->stamp();
11401142
xtty->end_head();
11411143
}
@@ -2789,11 +2791,11 @@ bool nmethod::is_patchable_at(address instr_addr) {
27892791
}
27902792

27912793

2792-
address nmethod::continuation_for_implicit_exception(address pc) {
2794+
address nmethod::continuation_for_implicit_exception(address pc, bool for_div0_check) {
27932795
// Exception happened outside inline-cache check code => we are inside
27942796
// an active nmethod => use cpc to determine a return address
27952797
int exception_offset = pc - code_begin();
2796-
int cont_offset = ImplicitExceptionTable(this).at( exception_offset );
2798+
int cont_offset = ImplicitExceptionTable(this).continuation_offset( exception_offset );
27972799
#ifdef ASSERT
27982800
if (cont_offset == 0) {
27992801
Thread* thread = ThreadLocalStorage::get_thread_slow();
@@ -2813,6 +2815,18 @@ address nmethod::continuation_for_implicit_exception(address pc) {
28132815
// Let the normal error handling report the exception
28142816
return NULL;
28152817
}
2818+
if (cont_offset == exception_offset) {
2819+
#if INCLUDE_JVMCI
2820+
Deoptimization::DeoptReason deopt_reason = for_div0_check ? Deoptimization::Reason_div0_check : Deoptimization::Reason_null_check;
2821+
JavaThread *thread = JavaThread::current();
2822+
thread->set_jvmci_implicit_exception_pc(pc);
2823+
thread->set_pending_deoptimization(Deoptimization::make_trap_request(deopt_reason,
2824+
Deoptimization::Action_reinterpret));
2825+
return (SharedRuntime::deopt_blob()->implicit_exception_uncommon_trap());
2826+
#else
2827+
ShouldNotReachHere();
2828+
#endif
2829+
}
28162830
return code_begin() + cont_offset;
28172831
}
28182832

@@ -2934,6 +2948,28 @@ void nmethod::verify() {
29342948
}
29352949
}
29362950

2951+
#ifdef INCLUDE_JVMCI
2952+
{
2953+
// Verify that implicit exceptions that deoptimize have a PcDesc and OopMap
2954+
OopMapSet* oms = oop_maps();
2955+
ImplicitExceptionTable implicit_table(this);
2956+
for (uint i = 0; i < implicit_table.len(); i++) {
2957+
int exec_offset = (int) implicit_table.get_exec_offset(i);
2958+
if (implicit_table.get_exec_offset(i) == implicit_table.get_cont_offset(i)) {
2959+
assert(find_pc_desc(code_begin() + exec_offset, false) != NULL, "missing PcDesc");
2960+
bool found = false;
2961+
for (int i = 0, imax = oms->size(); i < imax; i++) {
2962+
if (oms->at(i)->offset() == exec_offset) {
2963+
found = true;
2964+
break;
2965+
}
2966+
}
2967+
assert(found, "missing oopmap");
2968+
}
2969+
}
2970+
}
2971+
#endif
2972+
29372973
VerifyOopsClosure voc(this);
29382974
oops_do(&voc);
29392975
assert(voc.ok(), "embedded oops must be OK");
@@ -3366,21 +3402,40 @@ void nmethod::print_nmethod_labels(outputStream* stream, address block_begin) co
33663402
}
33673403

33683404
void nmethod::print_code_comment_on(outputStream* st, int column, u_char* begin, u_char* end) {
3369-
// First, find an oopmap in (begin, end].
3370-
// We use the odd half-closed interval so that oop maps and scope descs
3371-
// which are tied to the byte after a call are printed with the call itself.
3405+
ImplicitExceptionTable implicit_table(this);
3406+
int pc_offset = begin - code_begin();
3407+
int cont_offset = implicit_table.continuation_offset(pc_offset);
3408+
if (cont_offset != 0) {
3409+
st->move_to(column);
3410+
if (pc_offset == cont_offset) {
3411+
st->print("; implicit exception: deoptimizes");
3412+
} else {
3413+
st->print("; implicit exception: dispatches to " INTPTR_FORMAT, code_begin() + cont_offset);
3414+
}
3415+
}
3416+
3417+
// Find an oopmap in (begin, end]. We use the odd half-closed
3418+
// interval so that oop maps and scope descs which are tied to the
3419+
// byte after a call are printed with the call itself. OopMaps
3420+
// associated with implicit exceptions are printed with the implicit
3421+
// instruction.
33723422
address base = code_begin();
33733423
OopMapSet* oms = oop_maps();
33743424
if (oms != NULL) {
33753425
for (int i = 0, imax = oms->size(); i < imax; i++) {
33763426
OopMap* om = oms->at(i);
33773427
address pc = base + om->offset();
3378-
if (pc > begin) {
3379-
if (pc <= end) {
3380-
st->move_to(column);
3381-
st->print("; ");
3382-
om->print_on(st);
3383-
}
3428+
#ifdef INCLUDE_JVMCI
3429+
bool is_implicit_deopt = implicit_table.continuation_offset(om->offset()) == (uint) om->offset();
3430+
#else
3431+
bool is_implicit_deopt = false;
3432+
#endif
3433+
if (is_implicit_deopt ? pc == begin : pc > begin && pc <= end) {
3434+
st->move_to(column);
3435+
st->print("; ");
3436+
om->print_on(st);
3437+
}
3438+
if (pc > end) {
33843439
break;
33853440
}
33863441
}
@@ -3457,12 +3512,6 @@ void nmethod::print_code_comment_on(outputStream* st, int column, u_char* begin,
34573512
st->move_to(column);
34583513
st->print("; {%s}", str);
34593514
}
3460-
int cont_offset = ImplicitExceptionTable(this).at(begin - code_begin());
3461-
if (cont_offset != 0) {
3462-
st->move_to(column);
3463-
st->print("; implicit exception: dispatches to " INTPTR_FORMAT, code_begin() + cont_offset);
3464-
}
3465-
34663515
}
34673516

34683517
#ifndef PRODUCT

src/share/vm/code/nmethod.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "code/pcDesc.hpp"
3030
#include "oops/metadata.hpp"
3131

32+
3233
// This class is used internally by nmethods, to cache
3334
// exception/pc/handler information.
3435

@@ -557,6 +558,8 @@ class nmethod : public CodeBlob {
557558
void fix_oop_relocations(address begin, address end, bool initialize_immediates);
558559
inline void initialize_immediate_oop(oop* dest, jobject handle);
559560

561+
address continuation_for_implicit_exception(address pc, bool for_div0_check);
562+
560563
public:
561564
void fix_oop_relocations(address begin, address end) { fix_oop_relocations(begin, end, false); }
562565
void fix_oop_relocations() { fix_oop_relocations(NULL, NULL, false); }
@@ -597,7 +600,8 @@ class nmethod : public CodeBlob {
597600
void clean_exception_cache(BoolObjectClosure* is_alive);
598601

599602
// implicit exceptions support
600-
address continuation_for_implicit_exception(address pc);
603+
address continuation_for_implicit_div0_exception(address pc) { return continuation_for_implicit_exception(pc, true); }
604+
address continuation_for_implicit_null_exception(address pc) { return continuation_for_implicit_exception(pc, false); }
601605

602606
// On-stack replacement support
603607
int osr_entry_bci() const { assert(is_osr_method(), "wrong kind of nmethod"); return _entry_bci; }

src/share/vm/jvmci/jvmciCodeInstaller.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ JVMCIEnv::CodeInstallResult CodeInstaller::install(JVMCICompiler* compiler, Hand
509509
id = CompileBroker::assign_compile_id_unlocked(Thread::current(), method, entry_bci);
510510
}
511511
result = JVMCIEnv::register_method(method, nm, entry_bci, &_offsets, _orig_pc_offset, &buffer,
512-
stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table,
512+
stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table, &_implicit_exception_table,
513513
compiler, _debug_recorder, _dependencies, env, id,
514514
has_unsafe_access, _has_wide_vector, installed_code, compiled_code, speculation_log);
515515
cb = nm;
@@ -695,12 +695,18 @@ JVMCIEnv::CodeInstallResult CodeInstaller::initialize_buffer(CodeBuffer& buffer,
695695
} else if (site->is_a(site_Infopoint::klass())) {
696696
// three reasons for infopoints denote actual safepoints
697697
oop reason = site_Infopoint::reason(site);
698-
if (site_InfopointReason::SAFEPOINT() == reason || site_InfopointReason::CALL() == reason || site_InfopointReason::IMPLICIT_EXCEPTION() == reason) {
698+
if (site_InfopointReason::SAFEPOINT() == reason ||
699+
site_InfopointReason::CALL() == reason ||
700+
site_InfopointReason::IMPLICIT_EXCEPTION() == reason) {
699701
TRACE_jvmci_4("safepoint at %i", pc_offset);
700702
site_Safepoint(buffer, pc_offset, site, CHECK_OK);
701703
if (_orig_pc_offset < 0) {
702704
JVMCI_ERROR_OK("method contains safepoint, but has no deopt rescue slot");
703705
}
706+
if (site_InfopointReason::IMPLICIT_EXCEPTION() == reason) {
707+
TRACE_jvmci_4("implicit exception at %i", pc_offset);
708+
_implicit_exception_table.add_deoptimize(pc_offset);
709+
}
704710
} else {
705711
TRACE_jvmci_4("infopoint at %i", pc_offset);
706712
site_Infopoint(buffer, pc_offset, site, CHECK_OK);

src/share/vm/jvmci/jvmciCodeInstaller.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ class CodeInstaller : public StackObj {
8383
DebugInformationRecorder* _debug_recorder;
8484
Dependencies* _dependencies;
8585
ExceptionHandlerTable _exception_handler_table;
86+
ImplicitExceptionTable _implicit_exception_table;
8687

8788
static ConstantOopWriteValue* _oop_null_scope_value;
8889
static ConstantIntValue* _int_m1_scope_value;

src/share/vm/jvmci/jvmciEnv.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,7 @@ JVMCIEnv::CodeInstallResult JVMCIEnv::register_method(
446446
int frame_words,
447447
OopMapSet* oop_map_set,
448448
ExceptionHandlerTable* handler_table,
449+
ImplicitExceptionTable* implicit_exception_table,
449450
AbstractCompiler* compiler,
450451
DebugInformationRecorder* debug_info,
451452
Dependencies* dependencies,
@@ -500,15 +501,14 @@ JVMCIEnv::CodeInstallResult JVMCIEnv::register_method(
500501
// as in C2, then it must be freed.
501502
//code_buffer->free_blob();
502503
} else {
503-
ImplicitExceptionTable implicit_tbl;
504504
nm = nmethod::new_nmethod(method,
505505
compile_id,
506506
entry_bci,
507507
offsets,
508508
orig_pc_offset,
509509
debug_info, dependencies, code_buffer,
510510
frame_words, oop_map_set,
511-
handler_table, &implicit_tbl,
511+
handler_table, implicit_exception_table,
512512
compiler, comp_level,
513513
JNIHandles::make_weak_global(installed_code),
514514
JNIHandles::make_weak_global(speculation_log));

src/share/vm/jvmci/jvmciEnv.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ class JVMCIEnv : StackObj {
163163
int frame_words,
164164
OopMapSet* oop_map_set,
165165
ExceptionHandlerTable* handler_table,
166+
ImplicitExceptionTable* implicit_exception_table,
166167
AbstractCompiler* compiler,
167168
DebugInformationRecorder* debug_info,
168169
Dependencies* dependencies,

src/share/vm/runtime/sharedRuntime.cpp

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -783,18 +783,9 @@ JRT_ENTRY(void, SharedRuntime::throw_StackOverflowError(JavaThread* thread))
783783
throw_and_post_jvmti_exception(thread, exception);
784784
JRT_END
785785

786-
#if INCLUDE_JVMCI
787-
address SharedRuntime::deoptimize_for_implicit_exception(JavaThread* thread, address pc, nmethod* nm, int deopt_reason) {
788-
assert(deopt_reason > Deoptimization::Reason_none && deopt_reason < Deoptimization::Reason_LIMIT, "invalid deopt reason");
789-
thread->set_jvmci_implicit_exception_pc(pc);
790-
thread->set_pending_deoptimization(Deoptimization::make_trap_request((Deoptimization::DeoptReason)deopt_reason, Deoptimization::Action_reinterpret));
791-
return (SharedRuntime::deopt_blob()->implicit_exception_uncommon_trap());
792-
}
793-
#endif
794-
795786
address SharedRuntime::continuation_for_implicit_exception(JavaThread* thread,
796787
address pc,
797-
SharedRuntime::ImplicitExceptionKind exception_kind)
788+
ImplicitExceptionKind exception_kind)
798789
{
799790
address target_pc = NULL;
800791

@@ -889,18 +880,7 @@ address SharedRuntime::continuation_for_implicit_exception(JavaThread* thread,
889880
#ifndef PRODUCT
890881
_implicit_null_throws++;
891882
#endif
892-
#if INCLUDE_JVMCI
893-
if (nm->is_compiled_by_jvmci() && nm->pc_desc_at(pc) != NULL) {
894-
// If there's no PcDesc then we'll die way down inside of
895-
// deopt instead of just getting normal error reporting,
896-
// so only go there if it will succeed.
897-
return deoptimize_for_implicit_exception(thread, pc, nm, Deoptimization::Reason_null_check);
898-
} else {
899-
#endif
900-
target_pc = nm->continuation_for_implicit_exception(pc);
901-
#if INCLUDE_JVMCI
902-
}
903-
#endif
883+
target_pc = nm->continuation_for_implicit_null_exception(pc);
904884
// If there's an unexpected fault, target_pc might be NULL,
905885
// in which case we want to fall through into the normal
906886
// error handling code.
@@ -916,15 +896,7 @@ address SharedRuntime::continuation_for_implicit_exception(JavaThread* thread,
916896
#ifndef PRODUCT
917897
_implicit_div0_throws++;
918898
#endif
919-
#if INCLUDE_JVMCI
920-
if (nm->is_compiled_by_jvmci() && nm->pc_desc_at(pc) != NULL) {
921-
return deoptimize_for_implicit_exception(thread, pc, nm, Deoptimization::Reason_div0_check);
922-
} else {
923-
#endif
924-
target_pc = nm->continuation_for_implicit_exception(pc);
925-
#if INCLUDE_JVMCI
926-
}
927-
#endif
899+
target_pc = nm->continuation_for_implicit_div0_exception(pc);
928900
// If there's an unexpected fault, target_pc might be NULL,
929901
// in which case we want to fall through into the normal
930902
// error handling code.

src/share/vm/runtime/sharedRuntime.hpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -199,10 +199,6 @@ class SharedRuntime: AllStatic {
199199
static address continuation_for_implicit_exception(JavaThread* thread,
200200
address faulting_pc,
201201
ImplicitExceptionKind exception_kind);
202-
#if INCLUDE_JVMCI
203-
static address deoptimize_for_implicit_exception(JavaThread* thread, address pc, nmethod* nm, int deopt_reason);
204-
#endif
205-
206202
// Shared stub locations
207203
static address get_poll_stub(address pc);
208204

0 commit comments

Comments
 (0)