# HG changeset patch # User Gary Benson # Date 1236608768 14400 # Node ID 5e454391b4cee5b792a700810a9d1c3bb146ada4 # Parent 146e5d33e990ca5aee7fa3c2515c9f09e1b1ef1d 2009-03-09 Gary Benson * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp (SharkTopLevelBlock::_trap_request): New field. (SharkTopLevelBlock::trap_request): New method. (SharkTopLevelBlock::scan_for_traps): Likewise. (SharkTopLevelBlock::has_trap): Rewritten. (SharkTopLevelBlock::trap_index): Removed method. * ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp (SharkTopLevelBlock::scan_for_traps): New method. (SharkTopLevelBlock::emit_IR): s/trap_index/trap_request/. (SharkTopLevelBlock::get_virtual_callee): Removed slow case. * ports/hotspot/src/share/vm/shark/sharkConstantPool.cpp (SharkConstantPool::cache_entry_at): Removed slow case. * ports/hotspot/src/share/vm/shark/sharkRuntime.hpp (SharkRuntime::_resolve_get_put): Removed. (SharkRuntime::_resolve_invoke): Likewise. (SharkRuntime::resolve_get_put): Likewise. (SharkRuntime::resolve_invoke): Likewise. (SharkRuntime::resolve_get_put_C): Likewise. (SharkRuntime::resolve_invoke_C): Likewise. (SharkRuntime::uncommon_trap_C): s/index/trap_request/. * ports/hotspot/src/share/vm/shark/sharkRuntime.cpp (SharkRuntime::_resolve_get_put): Removed. (SharkRuntime::_resolve_invoke): Likewise. (SharkRuntime::initialize): Removed initialization for the above. (SharkRuntime::resolve_get_put_C): Removed. (SharkRuntime::resolve_invoke_C): Likewise. (SharkRuntime::uncommon_trap_C): s/index/trap_request/. * ports/hotspot/src/share/vm/shark/sharkBlock.cpp (SharkBlock::do_field_access): Mismatch case now handled by trap. * ports/hotspot/src/share/vm/includeDB_shark: Updated. (transplanted from a28649aea20fad5a814c3cd8d56b8ed704c7203b) diff -r 146e5d33e990 -r 5e454391b4ce ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Mon Mar 09 10:26:08 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.cpp Mon Mar 09 10:26:08 2009 -0400 @@ -236,6 +236,99 @@ return TRAP_NO_TRAPS; } +int SharkTopLevelBlock::scan_for_traps() +{ + // If typeflow got one then we're already done + if (ciblock()->has_trap()) { + return Deoptimization::make_trap_request( + Deoptimization::Reason_unloaded, + Deoptimization::Action_reinterpret, + ciblock()->trap_index()); + } + + // Scan the bytecode + iter()->reset_to_bci(start()); + while (iter()->next_bci() < limit()) { + iter()->next(); + + ciField *field; + ciMethod *method; + bool will_link; + bool is_field; + + int index = -1; + + switch (bc()) { + case Bytecodes::_getfield: + case Bytecodes::_getstatic: + case Bytecodes::_putfield: + case Bytecodes::_putstatic: + field = iter()->get_field(will_link); + assert(will_link, "typeflow responsibility"); + is_field = (bc() == Bytecodes::_getfield || bc() == Bytecodes::_putfield); + + // If the bytecode does not match the field then bail out to + // the interpreter to throw an IncompatibleClassChangeError + if (is_field == field->is_static()) { + return Deoptimization::make_trap_request( + Deoptimization::Reason_unhandled, + Deoptimization::Action_none); + } + + // If this is a getfield or putfield then there won't be a + // pool access and we're done + if (is_field) + break; + + // There won't be a pool access if this is a getstatic that + // resolves to a handled constant either + if (bc() == Bytecodes::_getstatic && field->is_constant()) { + if (SharkValue::from_ciConstant(field->constant_value())) + break; + } + + // Continue to the check + index = iter()->get_field_index(); + break; + + case Bytecodes::_invokespecial: + case Bytecodes::_invokestatic: + case Bytecodes::_invokevirtual: + case Bytecodes::_invokeinterface: + method = iter()->get_method(will_link); + assert(will_link, "typeflow responsibility"); + + // If this is a non-final invokevirtual then there won't + // be a pool access. We do need to check that its holder + // is linked, however, because its vtable won't have been + // set up otherwise. + if (bc() == Bytecodes::_invokevirtual && !method->is_final_method()) { + if (!method->holder()->is_linked()) { + return Deoptimization::make_trap_request( + Deoptimization::Reason_uninitialized, + Deoptimization::Action_reinterpret); + } + break; + } + + // Continue to the check + index = iter()->get_method_index(); + break; + } + + // If we found a constant pool access on this bytecode then check it + if (index != -1) { + if (!target()->holder()->is_cache_entry_resolved( + Bytes::swap_u2(index), bc())) { + return Deoptimization::make_trap_request( + Deoptimization::Reason_uninitialized, + Deoptimization::Action_reinterpret); + } + } + } + return TRAP_NO_TRAPS; +} + SharkState* SharkTopLevelBlock::entry_state() { if (_entry_state == NULL) { diff -r 146e5d33e990 -r 5e454391b4ce ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp --- a/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp Mon Mar 09 10:26:08 2009 -0400 +++ b/ports/hotspot/src/share/vm/shark/sharkTopLevelBlock.hpp Mon Mar 09 10:26:08 2009 -0400 @@ -130,6 +130,29 @@ private: int scan_for_traps(); + // Traps + private: + enum { + TRAP_UNCHECKED = 232323, // > any constant pool index + TRAP_NO_TRAPS + }; + int _trap_request; + + public: + int trap_request() + { + if (_trap_request == TRAP_UNCHECKED) + _trap_request = scan_for_traps(); + return _trap_request; + } + bool has_trap() + { + return trap_request() != TRAP_NO_TRAPS; + } + + private: + int scan_for_traps(); + // Entry state private: bool _entered;