# HG changeset patch # User goetz # Date 1371803264 -7200 # Node ID a071790264bd1a840413fbe208b3d854430b16e2 # Parent 0f03ff49c7203d539f736f6c81c8c0137af3b142 Remove breakpoint_Relocation. diff --git a/src/cpu/sparc/vm/macroAssembler_sparc.cpp b/src/cpu/sparc/vm/macroAssembler_sparc.cpp --- a/src/cpu/sparc/vm/macroAssembler_sparc.cpp +++ b/src/cpu/sparc/vm/macroAssembler_sparc.cpp @@ -1251,12 +1251,6 @@ while (offset() % modulus != 0) nop(); } - -void MacroAssembler::safepoint() { - relocate(breakpoint_Relocation::spec(breakpoint_Relocation::safepoint)); -} - - void RegistersForDebugging::print(outputStream* s) { FlagSetting fs(Debugging, true); int j; diff --git a/src/cpu/sparc/vm/relocInfo_sparc.cpp b/src/cpu/sparc/vm/relocInfo_sparc.cpp --- a/src/cpu/sparc/vm/relocInfo_sparc.cpp +++ b/src/cpu/sparc/vm/relocInfo_sparc.cpp @@ -193,36 +193,6 @@ return *(address*)addr(); } - -int Relocation::pd_breakpoint_size() { - // minimum breakpoint size, in short words - return NativeIllegalInstruction::instruction_size / sizeof(short); -} - -void Relocation::pd_swap_in_breakpoint(address x, short* instrs, int instrlen) { - Untested("pd_swap_in_breakpoint"); - // %%% probably do not need a general instrlen; just use the trap size - if (instrs != NULL) { - assert(instrlen * sizeof(short) == NativeIllegalInstruction::instruction_size, "enough instrlen in reloc. data"); - for (int i = 0; i < instrlen; i++) { - instrs[i] = ((short*)x)[i]; - } - } - NativeIllegalInstruction::insert(x); -} - - -void Relocation::pd_swap_out_breakpoint(address x, short* instrs, int instrlen) { - Untested("pd_swap_out_breakpoint"); - assert(instrlen * sizeof(short) == sizeof(int), "enough buf"); - union { int l; short s[1]; } u; - for (int i = 0; i < instrlen; i++) { - u.s[i] = instrs[i]; - } - NativeInstruction* ni = nativeInstruction_at(x); - ni->set_long_at(0, u.l); -} - void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { } diff --git a/src/cpu/x86/vm/relocInfo_x86.cpp b/src/cpu/x86/vm/relocInfo_x86.cpp --- a/src/cpu/x86/vm/relocInfo_x86.cpp +++ b/src/cpu/x86/vm/relocInfo_x86.cpp @@ -177,30 +177,6 @@ return *pd_address_in_code(); } -int Relocation::pd_breakpoint_size() { - // minimum breakpoint size, in short words - return NativeIllegalInstruction::instruction_size / sizeof(short); -} - -void Relocation::pd_swap_in_breakpoint(address x, short* instrs, int instrlen) { - Untested("pd_swap_in_breakpoint"); - if (instrs != NULL) { - assert(instrlen * sizeof(short) == NativeIllegalInstruction::instruction_size, "enough instrlen in reloc. data"); - for (int i = 0; i < instrlen; i++) { - instrs[i] = ((short*)x)[i]; - } - } - NativeIllegalInstruction::insert(x); -} - - -void Relocation::pd_swap_out_breakpoint(address x, short* instrs, int instrlen) { - Untested("pd_swap_out_breakpoint"); - assert(NativeIllegalInstruction::instruction_size == sizeof(short), "right address unit for update"); - NativeInstruction* ni = nativeInstruction_at(x); - *(short*)ni->addr_at(0) = instrs[0]; -} - void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { #ifdef _LP64 if (!Assembler::is_polling_page_far()) { diff --git a/src/cpu/zero/vm/relocInfo_zero.cpp b/src/cpu/zero/vm/relocInfo_zero.cpp --- a/src/cpu/zero/vm/relocInfo_zero.cpp +++ b/src/cpu/zero/vm/relocInfo_zero.cpp @@ -52,22 +52,6 @@ return (address *) addr(); } -int Relocation::pd_breakpoint_size() { - ShouldNotCallThis(); -} - -void Relocation::pd_swap_in_breakpoint(address x, - short* instrs, - int instrlen) { - ShouldNotCallThis(); -} - -void Relocation::pd_swap_out_breakpoint(address x, - short* instrs, - int instrlen) { - ShouldNotCallThis(); -} - void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dst) { ShouldNotCallThis(); diff --git a/src/share/vm/code/nmethod.cpp b/src/share/vm/code/nmethod.cpp --- a/src/share/vm/code/nmethod.cpp +++ b/src/share/vm/code/nmethod.cpp @@ -1081,11 +1081,6 @@ metadata_Relocation* reloc = iter.metadata_reloc(); reloc->fix_metadata_relocation(); } - - // There must not be any interfering patches or breakpoints. - assert(!(iter.type() == relocInfo::breakpoint_type - && iter.breakpoint_reloc()->active()), - "no active breakpoint"); } } diff --git a/src/share/vm/code/relocInfo.cpp b/src/share/vm/code/relocInfo.cpp --- a/src/share/vm/code/relocInfo.cpp +++ b/src/share/vm/code/relocInfo.cpp @@ -338,31 +338,6 @@ _limit = limit; } - -void PatchingRelocIterator:: prepass() { - // turn breakpoints off during patching - _init_state = (*this); // save cursor - while (next()) { - if (type() == relocInfo::breakpoint_type) { - breakpoint_reloc()->set_active(false); - } - } - (RelocIterator&)(*this) = _init_state; // reset cursor for client -} - - -void PatchingRelocIterator:: postpass() { - // turn breakpoints back on after patching - (RelocIterator&)(*this) = _init_state; // reset cursor again - while (next()) { - if (type() == relocInfo::breakpoint_type) { - breakpoint_Relocation* bpt = breakpoint_reloc(); - bpt->set_active(bpt->enabled()); - } - } -} - - // All the strange bit-encodings are in here. // The idea is to encode relocation data which are small integers // very efficiently (a single extra halfword). Larger chunks of @@ -704,51 +679,6 @@ _target = address_from_scaled_offset(offset, base); } - -void breakpoint_Relocation::pack_data_to(CodeSection* dest) { - short* p = (short*) dest->locs_end(); - address point = dest->locs_point(); - - *p++ = _bits; - - assert(_target != NULL, "sanity"); - - if (internal()) normalize_address(_target, dest); - - jint target_bits = - (jint)( internal() ? scaled_offset (_target, point) - : runtime_address_to_index(_target) ); - if (settable()) { - // save space for set_target later - p = add_jint(p, target_bits); - } else { - p = add_var_int(p, target_bits); - } - - for (int i = 0; i < instrlen(); i++) { - // put placeholder words until bytes can be saved - p = add_short(p, (short)0x7777); - } - - dest->set_locs_end((relocInfo*) p); -} - - -void breakpoint_Relocation::unpack_data() { - _bits = live_bits(); - - int targetlen = datalen() - 1 - instrlen(); - jint target_bits = 0; - if (targetlen == 0) target_bits = 0; - else if (targetlen == 1) target_bits = *(data()+1); - else if (targetlen == 2) target_bits = relocInfo::jint_from_data(data()+1); - else { ShouldNotReachHere(); } - - _target = internal() ? address_from_scaled_offset(target_bits, addr()) - : index_to_runtime_address (target_bits); -} - - //// miscellaneous methods oop* oop_Relocation::oop_addr() { int n = _oop_index; @@ -933,81 +863,6 @@ return target; } - -breakpoint_Relocation::breakpoint_Relocation(int kind, address target, bool internal) { - bool active = false; - bool enabled = (kind == initialization); - bool removable = (kind != safepoint); - bool settable = (target == NULL); - - int bits = kind; - if (enabled) bits |= enabled_state; - if (internal) bits |= internal_attr; - if (removable) bits |= removable_attr; - if (settable) bits |= settable_attr; - - _bits = bits | high_bit; - _target = target; - - assert(this->kind() == kind, "kind encoded"); - assert(this->enabled() == enabled, "enabled encoded"); - assert(this->active() == active, "active encoded"); - assert(this->internal() == internal, "internal encoded"); - assert(this->removable() == removable, "removable encoded"); - assert(this->settable() == settable, "settable encoded"); -} - - -address breakpoint_Relocation::target() const { - return _target; -} - - -void breakpoint_Relocation::set_target(address x) { - assert(settable(), "must be settable"); - jint target_bits = - (jint)(internal() ? scaled_offset (x, addr()) - : runtime_address_to_index(x)); - short* p = &live_bits() + 1; - p = add_jint(p, target_bits); - assert(p == instrs(), "new target must fit"); - _target = x; -} - - -void breakpoint_Relocation::set_enabled(bool b) { - if (enabled() == b) return; - - if (b) { - set_bits(bits() | enabled_state); - } else { - set_active(false); // remove the actual breakpoint insn, if any - set_bits(bits() & ~enabled_state); - } -} - - -void breakpoint_Relocation::set_active(bool b) { - assert(!b || enabled(), "cannot activate a disabled breakpoint"); - - if (active() == b) return; - - // %%% should probably seize a lock here (might not be the right lock) - //MutexLockerEx ml_patch(Patching_lock, true); - //if (active() == b) return; // recheck state after locking - - if (b) { - set_bits(bits() | active_state); - if (instrlen() == 0) - fatal("breakpoints in original code must be undoable"); - pd_swap_in_breakpoint (addr(), instrs(), instrlen()); - } else { - set_bits(bits() & ~active_state); - pd_swap_out_breakpoint(addr(), instrs(), instrlen()); - } -} - - //--------------------------------------------------------------------------------- // Non-product code diff --git a/src/share/vm/code/relocInfo.hpp b/src/share/vm/code/relocInfo.hpp --- a/src/share/vm/code/relocInfo.hpp +++ b/src/share/vm/code/relocInfo.hpp @@ -49,9 +49,6 @@ // RelocIterator // A StackObj which iterates over the relocations associated with // a range of code addresses. Can be used to operate a copy of code. -// PatchingRelocIterator -// Specialized subtype of RelocIterator which removes breakpoints -// temporarily during iteration, then restores them. // BoundRelocation // An _internal_ type shared by packers and unpackers of relocations. // It pastes together a RelocationHolder with some pointers into @@ -204,15 +201,6 @@ // immediate field must not straddle a unit of memory coherence. // //%note reloc_3 // -// relocInfo::breakpoint_type -- a conditional breakpoint in the code -// Value: none -// Instruction types: any whatsoever -// Data: [b [T]t i...] -// The b is a bit-packed word representing the breakpoint's attributes. -// The t is a target address which the breakpoint calls (when it is enabled). -// The i... is a place to store one or two instruction words overwritten -// by a trap, so that the breakpoint may be subsequently removed. -// // relocInfo::static_stub_type -- an extra stub for each static_call_type // Value: none // Instruction types: a virtual call: { set_oop; jump; } @@ -271,9 +259,9 @@ section_word_type = 9, // internal, but a cross-section reference poll_type = 10, // polling instruction for safepoints poll_return_type = 11, // polling instruction for safepoints at return - breakpoint_type = 12, // an initialization barrier or safepoint - metadata_type = 13, // metadata that used to be oops - yet_unused_type_2 = 14, // Still unused + metadata_type = 12, // metadata that used to be oops + yet_unused_type_2 = 13, // Still unused + yet_unused_type_1 = 14, // Still unused data_prefix_tag = 15, // tag for a prefix (carries data arguments) type_mask = 15 // A mask which selects only the above values }; @@ -312,7 +300,6 @@ visitor(internal_word) \ visitor(poll) \ visitor(poll_return) \ - visitor(breakpoint) \ visitor(section_word) \ @@ -454,7 +441,7 @@ public: enum { // Conservatively large estimate of maximum length (in shorts) - // of any relocation record (probably breakpoints are largest). + // of any relocation record. // Extended format is length prefix, data words, and tag/offset suffix. length_limit = 1 + 1 + (3*BytesPerWord/BytesPerShort) + 1, have_format = format_width > 0 @@ -571,8 +558,6 @@ void initialize(nmethod* nm, address begin, address limit); - friend class PatchingRelocIterator; - // make an uninitialized one, for PatchingRelocIterator: RelocIterator() { initialize_misc(); } public: @@ -779,9 +764,6 @@ void pd_verify_data_value (address x, intptr_t off) { pd_set_data_value(x, off, true); } address pd_call_destination (address orig_addr = NULL); void pd_set_call_destination (address x); - void pd_swap_in_breakpoint (address x, short* instrs, int instrlen); - void pd_swap_out_breakpoint (address x, short* instrs, int instrlen); - static int pd_breakpoint_size (); // this extracts the address of an address in the code stream instead of the reloc data address* pd_address_in_code (); @@ -1302,87 +1284,6 @@ void fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest); }; - -class breakpoint_Relocation : public Relocation { - relocInfo::relocType type() { return relocInfo::breakpoint_type; } - - enum { - // attributes which affect the interpretation of the data: - removable_attr = 0x0010, // buffer [i...] allows for undoing the trap - internal_attr = 0x0020, // the target is an internal addr (local stub) - settable_attr = 0x0040, // the target is settable - - // states which can change over time: - enabled_state = 0x0100, // breakpoint must be active in running code - active_state = 0x0200, // breakpoint instruction actually in code - - kind_mask = 0x000F, // mask for extracting kind - high_bit = 0x4000 // extra bit which is always set - }; - - public: - enum { - // kinds: - initialization = 1, - safepoint = 2 - }; - - // If target is NULL, 32 bits are reserved for a later set_target(). - static RelocationHolder spec(int kind, address target = NULL, bool internal_target = false) { - RelocationHolder rh = newHolder(); - new(rh) breakpoint_Relocation(kind, target, internal_target); - return rh; - } - - private: - // We require every bits value to NOT to fit into relocInfo::datalen_width, - // because we are going to actually store state in the reloc, and so - // cannot allow it to be compressed (and hence copied by the iterator). - - short _bits; // bit-encoded kind, attrs, & state - address _target; - - breakpoint_Relocation(int kind, address target, bool internal_target); - - friend class RelocIterator; - breakpoint_Relocation() { } - - short bits() const { return _bits; } - short& live_bits() const { return data()[0]; } - short* instrs() const { return data() + datalen() - instrlen(); } - int instrlen() const { return removable() ? pd_breakpoint_size() : 0; } - - void set_bits(short x) { - assert(live_bits() == _bits, "must be the only mutator of reloc info"); - live_bits() = _bits = x; - } - - public: - address target() const; - void set_target(address x); - - int kind() const { return bits() & kind_mask; } - bool enabled() const { return (bits() & enabled_state) != 0; } - bool active() const { return (bits() & active_state) != 0; } - bool internal() const { return (bits() & internal_attr) != 0; } - bool removable() const { return (bits() & removable_attr) != 0; } - bool settable() const { return (bits() & settable_attr) != 0; } - - void set_enabled(bool b); // to activate, you must also say set_active - void set_active(bool b); // actually inserts bpt (must be enabled 1st) - - // data is packed as 16 bits, followed by the target (1 or 2 words), followed - // if necessary by empty storage for saving away original instruction bytes. - void pack_data_to(CodeSection* dest); - void unpack_data(); - - // during certain operations, breakpoints must be out of the way: - void fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) { - assert(!active(), "cannot perform relocation on enabled breakpoints"); - } -}; - - // We know all the xxx_Relocation classes, so now we can define these: #define EACH_CASE(name) \ inline name##_Relocation* RelocIterator::name##_reloc() { \ @@ -1401,25 +1302,4 @@ initialize(nm, begin, limit); } -// if you are going to patch code, you should use this subclass of -// RelocIterator -class PatchingRelocIterator : public RelocIterator { - private: - RelocIterator _init_state; - - void prepass(); // deactivates all breakpoints - void postpass(); // reactivates all enabled breakpoints - - // do not copy these puppies; it would have unpredictable side effects - // these are private and have no bodies defined because they should not be called - PatchingRelocIterator(const RelocIterator&); - void operator=(const RelocIterator&); - - public: - PatchingRelocIterator(nmethod* nm, address begin = NULL, address limit = NULL) - : RelocIterator(nm, begin, limit) { prepass(); } - - ~PatchingRelocIterator() { postpass(); } -}; - #endif // SHARE_VM_CODE_RELOCINFO_HPP