src/cpu/x86/vm/templateInterpreter_x86_32.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File hotspot-dvm Cdiff src/cpu/x86/vm/templateInterpreter_x86_32.cpp

src/cpu/x86/vm/templateInterpreter_x86_32.cpp

Print this page
rev 423 : imported patch indy.patch

*** 164,188 **** __ dispatch_next(state); return entry; } ! address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step) { Label interpreter_entry; address compiled_entry = __ pc(); #ifdef COMPILER2 // The FPU stack is clean if UseSSE >= 2 but must be cleaned in other cases ! if ((state == ftos && UseSSE < 1) || (state == dtos && UseSSE < 2)) { for (int i = 1; i < 8; i++) { __ ffree(i); } } else if (UseSSE < 2) { __ empty_FPU_stack(); } #endif ! if ((state == ftos && UseSSE < 1) || (state == dtos && UseSSE < 2)) { __ MacroAssembler::verify_FPU(1, "generate_return_entry_for compiled"); } else { __ MacroAssembler::verify_FPU(0, "generate_return_entry_for compiled"); } --- 164,197 ---- __ dispatch_next(state); return entry; } ! address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, bool unbox) { ! TosState incoming_state = state; ! if (InvokeDynamic) { ! if (unbox) { ! incoming_state = atos; ! } ! } else { ! assert(!unbox, "old behavior"); ! } ! Label interpreter_entry; address compiled_entry = __ pc(); #ifdef COMPILER2 // The FPU stack is clean if UseSSE >= 2 but must be cleaned in other cases ! if ((incoming_state == ftos && UseSSE < 1) || (incoming_state == dtos && UseSSE < 2)) { for (int i = 1; i < 8; i++) { __ ffree(i); } } else if (UseSSE < 2) { __ empty_FPU_stack(); } #endif ! if ((incoming_state == ftos && UseSSE < 1) || (incoming_state == dtos && UseSSE < 2)) { __ MacroAssembler::verify_FPU(1, "generate_return_entry_for compiled"); } else { __ MacroAssembler::verify_FPU(0, "generate_return_entry_for compiled"); }
*** 194,209 **** address entry = __ pc(); __ bind(interpreter_entry); // In SSE mode, interpreter returns FP results in xmm0 but they need // to end up back on the FPU so it can operate on them. ! if (state == ftos && UseSSE >= 1) { __ subptr(rsp, wordSize); __ movflt(Address(rsp, 0), xmm0); __ fld_s(Address(rsp, 0)); __ addptr(rsp, wordSize); ! } else if (state == dtos && UseSSE >= 2) { __ subptr(rsp, 2*wordSize); __ movdbl(Address(rsp, 0), xmm0); __ fld_d(Address(rsp, 0)); __ addptr(rsp, 2*wordSize); } --- 203,218 ---- address entry = __ pc(); __ bind(interpreter_entry); // In SSE mode, interpreter returns FP results in xmm0 but they need // to end up back on the FPU so it can operate on them. ! if (incoming_state == ftos && UseSSE >= 1) { __ subptr(rsp, wordSize); __ movflt(Address(rsp, 0), xmm0); __ fld_s(Address(rsp, 0)); __ addptr(rsp, wordSize); ! } else if (incoming_state == dtos && UseSSE >= 2) { __ subptr(rsp, 2*wordSize); __ movdbl(Address(rsp, 0), xmm0); __ fld_d(Address(rsp, 0)); __ addptr(rsp, 2*wordSize); }
*** 215,231 **** // and NULL it as marker that rsp is now tos until next java call __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); __ restore_bcp(); __ restore_locals(); ! __ get_cache_and_index_at_bcp(rbx, rcx, 1); __ movl(rbx, Address(rbx, rcx, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::flags_offset())); __ andptr(rbx, 0xFF); __ lea(rsp, Address(rsp, rbx, Interpreter::stackElementScale())); __ dispatch_next(state, step); return entry; } address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, int step) { --- 224,343 ---- // and NULL it as marker that rsp is now tos until next java call __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); __ restore_bcp(); __ restore_locals(); ! ! Label L_fail; ! ! if (unbox && state != atos) { ! // cast and unbox ! BasicType type = as_BasicType(state); ! if (type == T_BYTE) type = T_BOOLEAN; // FIXME ! KlassHandle boxk = KlassHandles::box_klass(type); ! __ mov32(rbx, ExternalAddress((address) boxk.raw_value())); ! __ testl(rax, rax); ! Label L_got_value, L_get_value; ! // convert nulls to zeroes (avoid NPEs here) ! if (!(type == T_FLOAT || type == T_DOUBLE)) { ! // if rax already contains zero bits, forge ahead ! __ jcc(Assembler::zero, L_got_value); ! } else { ! __ jcc(Assembler::notZero, L_get_value); ! __ fldz(); ! __ jmp(L_got_value); ! } ! __ bind(L_get_value); ! __ cmp32(rbx, Address(rax, oopDesc::klass_offset_in_bytes())); ! __ jcc(Assembler::notEqual, L_fail); ! int offset = java_lang_boxing_object::value_offset_in_bytes(type); ! // Cf. TemplateTable::getfield_or_static ! switch (type) { ! case T_BYTE: // fall through: ! case T_BOOLEAN: __ load_signed_byte(rax, Address(rax, offset)); break; ! case T_CHAR: __ load_unsigned_word(rax, Address(rax, offset)); break; ! case T_SHORT: __ load_signed_word(rax, Address(rax, offset)); break; ! case T_INT: __ movl(rax, Address(rax, offset)); break; ! case T_FLOAT: __ fld_s(Address(rax, offset)); break; ! case T_DOUBLE: __ fld_d(Address(rax, offset)); break; ! // Access to java.lang.Double.value does not need to be atomic: ! case T_LONG: { __ movl(rdx, Address(rax, offset + 4)); ! __ movl(rax, Address(rax, offset + 0)); } break; ! default: ShouldNotReachHere(); ! } ! __ bind(L_got_value); ! ! // put FPU results into xmm0, as above: ! if (state == ftos && UseSSE >= 1) { ! __ subl(rsp, wordSize); ! __ movflt(Address(rsp, 0), xmm0); ! __ fld_s(Address(rsp, 0)); ! __ addl(rsp, wordSize); ! } else if (state == dtos && UseSSE >= 2) { ! __ subl(rsp, 2*wordSize); ! __ movdbl(Address(rsp, 0), xmm0); ! __ fld_d(Address(rsp, 0)); ! __ addl(rsp, 2*wordSize); ! } ! } ! ! Label L_got_cache, L_giant_index; ! if (InvokeDynamic) { ! __ cmpb(Address(rsi, 0), Bytecodes::_invokedynamic); ! __ jcc(Assembler::equal, L_giant_index); ! } ! __ get_cache_and_index_at_bcp(rbx, rcx, 1, false); ! __ bind(L_got_cache); ! if (unbox && state == atos) { ! // insert a casting conversion, to keep verifier sane ! Label L_ok, L_ok_pops; ! __ testl(rax, rax); ! __ jcc(Assembler::zero, L_ok); ! __ push(rax); // save the object to check ! __ movl(rax, Address(rax, oopDesc::klass_offset_in_bytes())); ! __ push(rbx); // save CP cache reference ! __ push(rcx); // save CP cache reference ! __ movl(rbx, Address(rbx, rcx, ! Address::times_4, constantPoolCacheOopDesc::base_offset() + ! ConstantPoolCacheEntry::f1_offset())); ! __ movl(rbx, Address(rbx, __ delayed_value(java_dyn_impl_DynCallSite::type_offset_in_bytes, rcx))); ! __ movl(rbx, Address(rbx, __ delayed_value(java_dyn_MethodType::rtype_offset_in_bytes, rcx))); ! __ movl(rbx, Address(rbx, __ delayed_value(java_lang_Class::klass_offset_in_bytes, rcx))); ! __ check_klass_subtype(rax, rbx, rcx, L_ok_pops); ! __ addptr(rsp, 2*wordSize); // toss rcx, keep rbx as failed klass ! __ pop(rax); ! __ jmp(L_fail); ! ! __ bind(L_ok_pops); ! // restore pushed temp regs: ! __ pop(rcx); ! __ pop(rbx); ! __ pop(rax); ! __ bind(L_ok); ! } __ movl(rbx, Address(rbx, rcx, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::flags_offset())); __ andptr(rbx, 0xFF); __ lea(rsp, Address(rsp, rbx, Interpreter::stackElementScale())); __ dispatch_next(state, step); + + // out of the main line of code... + if (InvokeDynamic) { + __ bind(L_giant_index); + __ get_cache_and_index_at_bcp(rbx, rcx, 1, true); + __ jmp(L_got_cache); + + if (unbox) { + __ bind(L_fail); + __ push(rbx); // missed klass (required) + __ push(rax); // bad object (actual) + __ movptr(rdx, ExternalAddress((address) &Interpreter::_throw_WrongMethodType_entry)); + __ call(rdx); + } + } + return entry; } address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, int step) {
src/cpu/x86/vm/templateInterpreter_x86_32.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File