hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp
changeset 2570 ecc7862946d4
parent 2534 08dac9ce0cd7
child 4094 1f424b2b2171
equal deleted inserted replaced
2569:9e8daec25638 2570:ecc7862946d4
   154   __ dispatch_next(state);
   154   __ dispatch_next(state);
   155   return entry;
   155   return entry;
   156 }
   156 }
   157 
   157 
   158 
   158 
   159 address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step) {
   159 address TemplateInterpreterGenerator::generate_return_entry_for(TosState state, int step, bool unbox) {
       
   160   TosState incoming_state = state;
       
   161   if (EnableInvokeDynamic) {
       
   162     if (unbox) {
       
   163       incoming_state = atos;
       
   164     }
       
   165   } else {
       
   166     assert(!unbox, "old behavior");
       
   167   }
       
   168 
   160   Label interpreter_entry;
   169   Label interpreter_entry;
   161   address compiled_entry = __ pc();
   170   address compiled_entry = __ pc();
   162 
   171 
   163 #ifdef COMPILER2
   172 #ifdef COMPILER2
   164   // The FPU stack is clean if UseSSE >= 2 but must be cleaned in other cases
   173   // The FPU stack is clean if UseSSE >= 2 but must be cleaned in other cases
   165   if ((state == ftos && UseSSE < 1) || (state == dtos && UseSSE < 2)) {
   174   if ((incoming_state == ftos && UseSSE < 1) || (incoming_state == dtos && UseSSE < 2)) {
   166     for (int i = 1; i < 8; i++) {
   175     for (int i = 1; i < 8; i++) {
   167         __ ffree(i);
   176         __ ffree(i);
   168     }
   177     }
   169   } else if (UseSSE < 2) {
   178   } else if (UseSSE < 2) {
   170     __ empty_FPU_stack();
   179     __ empty_FPU_stack();
   171   }
   180   }
   172 #endif
   181 #endif
   173   if ((state == ftos && UseSSE < 1) || (state == dtos && UseSSE < 2)) {
   182   if ((incoming_state == ftos && UseSSE < 1) || (incoming_state == dtos && UseSSE < 2)) {
   174     __ MacroAssembler::verify_FPU(1, "generate_return_entry_for compiled");
   183     __ MacroAssembler::verify_FPU(1, "generate_return_entry_for compiled");
   175   } else {
   184   } else {
   176     __ MacroAssembler::verify_FPU(0, "generate_return_entry_for compiled");
   185     __ MacroAssembler::verify_FPU(0, "generate_return_entry_for compiled");
   177   }
   186   }
   178 
   187 
   184   address entry = __ pc();
   193   address entry = __ pc();
   185   __ bind(interpreter_entry);
   194   __ bind(interpreter_entry);
   186 
   195 
   187   // In SSE mode, interpreter returns FP results in xmm0 but they need
   196   // In SSE mode, interpreter returns FP results in xmm0 but they need
   188   // to end up back on the FPU so it can operate on them.
   197   // to end up back on the FPU so it can operate on them.
   189   if (state == ftos && UseSSE >= 1) {
   198   if (incoming_state == ftos && UseSSE >= 1) {
   190     __ subptr(rsp, wordSize);
   199     __ subptr(rsp, wordSize);
   191     __ movflt(Address(rsp, 0), xmm0);
   200     __ movflt(Address(rsp, 0), xmm0);
   192     __ fld_s(Address(rsp, 0));
   201     __ fld_s(Address(rsp, 0));
   193     __ addptr(rsp, wordSize);
   202     __ addptr(rsp, wordSize);
   194   } else if (state == dtos && UseSSE >= 2) {
   203   } else if (incoming_state == dtos && UseSSE >= 2) {
   195     __ subptr(rsp, 2*wordSize);
   204     __ subptr(rsp, 2*wordSize);
   196     __ movdbl(Address(rsp, 0), xmm0);
   205     __ movdbl(Address(rsp, 0), xmm0);
   197     __ fld_d(Address(rsp, 0));
   206     __ fld_d(Address(rsp, 0));
   198     __ addptr(rsp, 2*wordSize);
   207     __ addptr(rsp, 2*wordSize);
   199   }
   208   }
   205   // and NULL it as marker that rsp is now tos until next java call
   214   // and NULL it as marker that rsp is now tos until next java call
   206   __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD);
   215   __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD);
   207 
   216 
   208   __ restore_bcp();
   217   __ restore_bcp();
   209   __ restore_locals();
   218   __ restore_locals();
   210   __ get_cache_and_index_at_bcp(rbx, rcx, 1);
   219 
       
   220   Label L_fail;
       
   221 
       
   222   if (unbox && state != atos) {
       
   223     // cast and unbox
       
   224     BasicType type = as_BasicType(state);
       
   225     if (type == T_BYTE)  type = T_BOOLEAN; // FIXME
       
   226     KlassHandle boxk = SystemDictionaryHandles::box_klass(type);
       
   227     __ mov32(rbx, ExternalAddress((address) boxk.raw_value()));
       
   228     __ testl(rax, rax);
       
   229     Label L_got_value, L_get_value;
       
   230     // convert nulls to zeroes (avoid NPEs here)
       
   231     if (!(type == T_FLOAT || type == T_DOUBLE)) {
       
   232       // if rax already contains zero bits, forge ahead
       
   233       __ jcc(Assembler::zero, L_got_value);
       
   234     } else {
       
   235       __ jcc(Assembler::notZero, L_get_value);
       
   236       __ fldz();
       
   237       __ jmp(L_got_value);
       
   238     }
       
   239     __ bind(L_get_value);
       
   240     __ cmp32(rbx, Address(rax, oopDesc::klass_offset_in_bytes()));
       
   241     __ jcc(Assembler::notEqual, L_fail);
       
   242     int offset = java_lang_boxing_object::value_offset_in_bytes(type);
       
   243     // Cf. TemplateTable::getfield_or_static
       
   244     switch (type) {
       
   245       case T_BYTE:     // fall through:
       
   246       case T_BOOLEAN:  __ load_signed_byte(rax, Address(rax, offset));    break;
       
   247       case T_CHAR:     __ load_unsigned_short(rax, Address(rax, offset)); break;
       
   248       case T_SHORT:    __ load_signed_short(rax, Address(rax, offset));   break;
       
   249       case T_INT:      __ movl(rax, Address(rax, offset));                break;
       
   250       case T_FLOAT:    __ fld_s(Address(rax, offset));                    break;
       
   251       case T_DOUBLE:   __ fld_d(Address(rax, offset));                    break;
       
   252       // Access to java.lang.Double.value does not need to be atomic:
       
   253       case T_LONG:   { __ movl(rdx, Address(rax, offset + 4));
       
   254                        __ movl(rax, Address(rax, offset + 0));  }         break;
       
   255       default: ShouldNotReachHere();
       
   256     }
       
   257     __ bind(L_got_value);
       
   258   }
       
   259 
       
   260   Label L_got_cache, L_giant_index;
       
   261   if (EnableInvokeDynamic) {
       
   262     __ cmpb(Address(rsi, 0), Bytecodes::_invokedynamic);
       
   263     __ jcc(Assembler::equal, L_giant_index);
       
   264   }
       
   265   __ get_cache_and_index_at_bcp(rbx, rcx, 1, false);
       
   266   __ bind(L_got_cache);
       
   267   if (unbox && state == atos) {
       
   268     // insert a casting conversion, to keep verifier sane
       
   269     Label L_ok, L_ok_pops;
       
   270     __ testl(rax, rax);
       
   271     __ jcc(Assembler::zero, L_ok);
       
   272     __ push(rax);               // save the object to check
       
   273     __ push(rbx);               // save CP cache reference
       
   274     __ movl(rdx, Address(rax, oopDesc::klass_offset_in_bytes()));
       
   275     __ movl(rbx, Address(rbx, rcx,
       
   276                       Address::times_4, constantPoolCacheOopDesc::base_offset() +
       
   277                       ConstantPoolCacheEntry::f1_offset()));
       
   278     __ movl(rbx, Address(rbx, __ delayed_value(sun_dyn_CallSiteImpl::type_offset_in_bytes, rcx)));
       
   279     __ movl(rbx, Address(rbx, __ delayed_value(java_dyn_MethodType::rtype_offset_in_bytes, rcx)));
       
   280     __ movl(rax, Address(rbx, __ delayed_value(java_lang_Class::klass_offset_in_bytes, rcx)));
       
   281     __ check_klass_subtype(rdx, rax, rbx, L_ok_pops);
       
   282     __ pop(rcx);                // pop and discard CP cache
       
   283     __ mov(rbx, rax);           // target supertype into rbx for L_fail
       
   284     __ pop(rax);                // failed object into rax for L_fail
       
   285     __ jmp(L_fail);
       
   286 
       
   287     __ bind(L_ok_pops);
       
   288     // restore pushed temp regs:
       
   289     __ pop(rbx);
       
   290     __ pop(rax);
       
   291     __ bind(L_ok);
       
   292   }
   211   __ movl(rbx, Address(rbx, rcx,
   293   __ movl(rbx, Address(rbx, rcx,
   212                     Address::times_ptr, constantPoolCacheOopDesc::base_offset() +
   294                     Address::times_ptr, constantPoolCacheOopDesc::base_offset() +
   213                     ConstantPoolCacheEntry::flags_offset()));
   295                     ConstantPoolCacheEntry::flags_offset()));
   214   __ andptr(rbx, 0xFF);
   296   __ andptr(rbx, 0xFF);
   215   __ lea(rsp, Address(rsp, rbx, Interpreter::stackElementScale()));
   297   __ lea(rsp, Address(rsp, rbx, Interpreter::stackElementScale()));
   216   __ dispatch_next(state, step);
   298   __ dispatch_next(state, step);
       
   299 
       
   300   // out of the main line of code...
       
   301   if (EnableInvokeDynamic) {
       
   302     __ bind(L_giant_index);
       
   303     __ get_cache_and_index_at_bcp(rbx, rcx, 1, true);
       
   304     __ jmp(L_got_cache);
       
   305 
       
   306     if (unbox) {
       
   307       __ bind(L_fail);
       
   308       __ push(rbx);             // missed klass (required)
       
   309       __ push(rax);             // bad object (actual)
       
   310       __ movptr(rdx, ExternalAddress((address) &Interpreter::_throw_WrongMethodType_entry));
       
   311       __ call(rdx);
       
   312     }
       
   313   }
       
   314 
   217   return entry;
   315   return entry;
   218 }
   316 }
   219 
   317 
   220 
   318 
   221 address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, int step) {
   319 address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, int step) {