@@ -135,6 +135,7 @@ JVMState* LibraryIntrinsic::generate(JVMState* jvms) {
135135
136136 // The intrinsic bailed out
137137 assert (ctrl == kit.control (), " Control flow was added although the intrinsic bailed out" );
138+ assert (jvms->map () == kit.map (), " Out of sync JVM state" );
138139 if (jvms->has_method ()) {
139140 // Not a root compile.
140141 const char * msg;
@@ -1724,18 +1725,15 @@ bool LibraryCallKit::inline_string_char_access(bool is_store) {
17241725 }
17251726
17261727 // Save state and restore on bailout
1727- uint old_sp = sp ();
1728- SafePointNode* old_map = clone_map ();
1728+ SavedState old_state (this );
17291729
17301730 value = must_be_not_null (value, true );
17311731
17321732 Node* adr = array_element_address (value, index, T_CHAR);
17331733 if (adr->is_top ()) {
1734- set_map (old_map);
1735- set_sp (old_sp);
17361734 return false ;
17371735 }
1738- destruct_map_clone (old_map );
1736+ old_state. discard ( );
17391737 if (is_store) {
17401738 access_store_at (value, adr, TypeAryPtr::BYTES, ch, TypeInt::CHAR, T_CHAR, IN_HEAP | MO_UNORDERED | C2_MISMATCHED);
17411739 } else {
@@ -2373,6 +2371,47 @@ DecoratorSet LibraryCallKit::mo_decorator_for_access_kind(AccessKind kind) {
23732371 }
23742372}
23752373
2374+ LibraryCallKit::SavedState::SavedState (LibraryCallKit* kit) :
2375+ _kit(kit),
2376+ _sp(kit->sp ()),
2377+ _jvms(kit->jvms ()),
2378+ _map(kit->clone_map ()),
2379+ _discarded(false )
2380+ {
2381+ for (DUIterator_Fast imax, i = kit->control ()->fast_outs (imax); i < imax; i++) {
2382+ Node* out = kit->control ()->fast_out (i);
2383+ if (out->is_CFG ()) {
2384+ _ctrl_succ.push (out);
2385+ }
2386+ }
2387+ }
2388+
2389+ LibraryCallKit::SavedState::~SavedState () {
2390+ if (_discarded) {
2391+ _kit->destruct_map_clone (_map);
2392+ return ;
2393+ }
2394+ _kit->jvms ()->set_map (_map);
2395+ _kit->jvms ()->set_sp (_sp);
2396+ _map->set_jvms (_kit->jvms ());
2397+ _kit->set_map (_map);
2398+ _kit->set_sp (_sp);
2399+ for (DUIterator_Fast imax, i = _kit->control ()->fast_outs (imax); i < imax; i++) {
2400+ Node* out = _kit->control ()->fast_out (i);
2401+ if (out->is_CFG () && out->in (0 ) == _kit->control () && out != _kit->map () && !_ctrl_succ.member (out)) {
2402+ _kit->_gvn .hash_delete (out);
2403+ out->set_req (0 , _kit->C ->top ());
2404+ _kit->C ->record_for_igvn (out);
2405+ --i; --imax;
2406+ _kit->_gvn .hash_find_insert (out);
2407+ }
2408+ }
2409+ }
2410+
2411+ void LibraryCallKit::SavedState::discard () {
2412+ _discarded = true ;
2413+ }
2414+
23762415bool LibraryCallKit::inline_unsafe_access (bool is_store, const BasicType type, const AccessKind kind, const bool unaligned) {
23772416 if (callee ()->is_static ()) return false ; // caller must have the capability!
23782417 DecoratorSet decorators = C2_UNSAFE_ACCESS;
@@ -2434,8 +2473,7 @@ bool LibraryCallKit::inline_unsafe_access(bool is_store, const BasicType type, c
24342473 offset = ConvL2X (offset);
24352474
24362475 // Save state and restore on bailout
2437- uint old_sp = sp ();
2438- SafePointNode* old_map = clone_map ();
2476+ SavedState old_state (this );
24392477
24402478 Node* adr = make_unsafe_address (base, offset, type, kind == Relaxed);
24412479 assert (!stopped (), " Inlining of unsafe access failed: address construction stopped unexpectedly" );
@@ -2444,8 +2482,6 @@ bool LibraryCallKit::inline_unsafe_access(bool is_store, const BasicType type, c
24442482 if (type != T_OBJECT) {
24452483 decorators |= IN_NATIVE; // off-heap primitive access
24462484 } else {
2447- set_map (old_map);
2448- set_sp (old_sp);
24492485 return false ; // off-heap oop accesses are not supported
24502486 }
24512487 } else {
@@ -2463,8 +2499,6 @@ bool LibraryCallKit::inline_unsafe_access(bool is_store, const BasicType type, c
24632499
24642500 const TypePtr* adr_type = _gvn.type (adr)->isa_ptr ();
24652501 if (adr_type == TypePtr::NULL_PTR) {
2466- set_map (old_map);
2467- set_sp (old_sp);
24682502 return false ; // off-heap access with zero address
24692503 }
24702504
@@ -2474,8 +2508,6 @@ bool LibraryCallKit::inline_unsafe_access(bool is_store, const BasicType type, c
24742508
24752509 if (alias_type->adr_type () == TypeInstPtr::KLASS ||
24762510 alias_type->adr_type () == TypeAryPtr::RANGE) {
2477- set_map (old_map);
2478- set_sp (old_sp);
24792511 return false ; // not supported
24802512 }
24812513
@@ -2494,16 +2526,14 @@ bool LibraryCallKit::inline_unsafe_access(bool is_store, const BasicType type, c
24942526 }
24952527 if ((bt == T_OBJECT) != (type == T_OBJECT)) {
24962528 // Don't intrinsify mismatched object accesses
2497- set_map (old_map);
2498- set_sp (old_sp);
24992529 return false ;
25002530 }
25012531 mismatched = (bt != type);
25022532 } else if (alias_type->adr_type ()->isa_oopptr ()) {
25032533 mismatched = true ; // conservatively mark all "wide" on-heap accesses as mismatched
25042534 }
25052535
2506- destruct_map_clone (old_map );
2536+ old_state. discard ( );
25072537 assert (!mismatched || alias_type->adr_type ()->is_oopptr (), " off-heap access can't be mismatched" );
25082538
25092539 if (mismatched) {
@@ -2739,8 +2769,7 @@ bool LibraryCallKit::inline_unsafe_load_store(const BasicType type, const LoadSt
27392769 // 32-bit machines ignore the high half of long offsets
27402770 offset = ConvL2X (offset);
27412771 // Save state and restore on bailout
2742- uint old_sp = sp ();
2743- SafePointNode* old_map = clone_map ();
2772+ SavedState old_state (this );
27442773 Node* adr = make_unsafe_address (base, offset,type, false );
27452774 const TypePtr *adr_type = _gvn.type (adr)->isa_ptr ();
27462775
@@ -2749,12 +2778,10 @@ bool LibraryCallKit::inline_unsafe_load_store(const BasicType type, const LoadSt
27492778 if (bt != T_ILLEGAL &&
27502779 (is_reference_type (bt) != (type == T_OBJECT))) {
27512780 // Don't intrinsify mismatched object accesses.
2752- set_map (old_map);
2753- set_sp (old_sp);
27542781 return false ;
27552782 }
27562783
2757- destruct_map_clone (old_map );
2784+ old_state. discard ( );
27582785
27592786 // For CAS, unlike inline_unsafe_access, there seems no point in
27602787 // trying to refine types. Just use the coarse types here.
0 commit comments