< prev index next >

src/cpu/x86/vm/sharedRuntime_x86_64.cpp

Print this page




 466     case T_CHAR:
 467     case T_BYTE:
 468     case T_SHORT:
 469     case T_INT:
 470       if (int_args < Argument::n_int_register_parameters_j) {
 471         regs[i].set1(INT_ArgReg[int_args++]->as_VMReg());
 472       } else {
 473         regs[i].set1(VMRegImpl::stack2reg(stk_args));
 474         stk_args += 2;
 475       }
 476       break;
 477     case T_VOID:
 478       // halves of T_LONG or T_DOUBLE
 479       assert(i != 0 && (sig_bt[i - 1] == T_LONG || sig_bt[i - 1] == T_DOUBLE), "expecting half");
 480       regs[i].set_bad();
 481       break;
 482     case T_LONG:
 483       assert((i + 1) < total_args_passed && sig_bt[i + 1] == T_VOID, "expecting half");
 484       // fall through
 485     case T_OBJECT:

 486     case T_ARRAY:
 487     case T_ADDRESS:
 488     case T_VALUETYPEPTR:
 489       if (int_args < Argument::n_int_register_parameters_j) {
 490         regs[i].set2(INT_ArgReg[int_args++]->as_VMReg());
 491       } else {
 492         regs[i].set2(VMRegImpl::stack2reg(stk_args));
 493         stk_args += 2;
 494       }
 495       break;
 496     case T_FLOAT:
 497       if (fp_args < Argument::n_float_register_parameters_j) {
 498         regs[i].set1(FP_ArgReg[fp_args++]->as_VMReg());
 499       } else {
 500         regs[i].set1(VMRegImpl::stack2reg(stk_args));
 501         stk_args += 2;
 502       }
 503       break;
 504     case T_DOUBLE:
 505       assert((i + 1) < total_args_passed && sig_bt[i + 1] == T_VOID, "expecting half");


 876       // argument when we hit the T_VOID that acts as an end of value
 877       // type delimiter for this value type. Value types are flattened
 878       // so we might encounter embedded value types. Each entry in
 879       // sig_extended contains a field offset in the buffer.
 880       do {
 881         next_arg_comp++;
 882         BasicType bt = sig_extended.at(next_arg_comp)._bt;
 883         BasicType prev_bt = sig_extended.at(next_arg_comp-1)._bt;
 884         if (bt == T_VALUETYPE) {
 885           vt++;
 886           ignored++;
 887         } else if (bt == T_VOID &&
 888                    prev_bt != T_LONG &&
 889                    prev_bt != T_DOUBLE) {
 890           vt--;
 891           ignored++;
 892         } else {
 893           int off = sig_extended.at(next_arg_comp)._offset;
 894           assert(off > 0, "offset in object should be positive");
 895           size_t size_in_bytes = is_java_primitive(bt) ? type2aelembytes(bt) : wordSize;
 896           bool is_oop = (bt == T_OBJECT || bt == T_ARRAY);
 897           has_oop_field = has_oop_field || is_oop;
 898           gen_c2i_adapter_helper(masm, bt, next_arg_comp > 0 ? sig_extended.at(next_arg_comp-1)._bt : T_ILLEGAL,
 899                                  size_in_bytes, regs[next_arg_comp-ignored], Address(r11, off), extraspace, is_oop);
 900         }
 901       } while (vt != 0);
 902       // pass the buffer to the interpreter
 903       __ movptr(Address(rsp, st_off), r11);
 904     }
 905   }
 906 
 907   // If a value type was allocated and initialized, apply post barrier to all oop fields
 908   if (has_value_argument && has_oop_field) {
 909     __ push(r13); // save senderSP
 910     __ push(rbx); // save callee
 911     // Allocate argument register save area
 912     if (frame::arg_reg_save_area_bytes != 0) {
 913       __ subptr(rsp, frame::arg_reg_save_area_bytes);
 914     }
 915     __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::apply_post_barriers), r15_thread, r10);
 916     // De-allocate argument register save area


1135       // T_VOID that acts as an end of value type delimiter for this
1136       // value type. Value types are flattened so we might encounter
1137       // embedded value types. Each entry in sig_extended contains a
1138       // field offset in the buffer.
1139       do {
1140         next_arg_comp++;
1141         BasicType bt = sig_extended.at(next_arg_comp)._bt;
1142         BasicType prev_bt = sig_extended.at(next_arg_comp-1)._bt;
1143         if (bt == T_VALUETYPE) {
1144           vt++;
1145           ignored++;
1146         } else if (bt == T_VOID &&
1147                    prev_bt != T_LONG &&
1148                    prev_bt != T_DOUBLE) {
1149           vt--;
1150           ignored++;
1151         } else {
1152           int off = sig_extended.at(next_arg_comp)._offset;
1153           assert(off > 0, "offset in object should be positive");
1154           size_t size_in_bytes = is_java_primitive(bt) ? type2aelembytes(bt) : wordSize;
1155           bool is_oop = (bt == T_OBJECT || bt == T_ARRAY);
1156           gen_i2c_adapter_helper(masm, bt, prev_bt, size_in_bytes, regs[next_arg_comp - ignored], Address(r10, off), is_oop);
1157         }
1158       } while (vt != 0);
1159     }
1160   }
1161 
1162   // 6243940 We might end up in handle_wrong_method if
1163   // the callee is deoptimized as we race thru here. If that
1164   // happens we don't want to take a safepoint because the
1165   // caller frame will look interpreted and arguments are now
1166   // "compiled" so it is much better to make this transition
1167   // invisible to the stack walking code. Unfortunately if
1168   // we try and find the callee by normal means a safepoint
1169   // is possible. So we stash the desired callee in the thread
1170   // and the vm will find there should this case occur.
1171 
1172   __ movptr(Address(r15_thread, JavaThread::callee_target_offset()), rbx);
1173 
1174   // put Method* where a c2i would expect should we end up there
1175   // only needed because of c2 resolve stubs return Method* as a result in


1230   gen_c2i_adapter(masm, sig_extended, regs, skip_fixup, i2c_entry, oop_maps, frame_complete, frame_size_in_words);
1231 
1232   __ flush();
1233   new_adapter = AdapterBlob::create(masm->code(), frame_complete, frame_size_in_words, oop_maps);
1234 
1235   // If value types are passed as fields, save the extended signature as symbol in
1236   // the AdapterHandlerEntry to be used by nmethod::preserve_callee_argument_oops().
1237   Symbol* extended_signature = NULL;
1238   if (ValueTypePassFieldsAsArgs) {
1239     bool has_value_argument = false;
1240     Thread* THREAD = Thread::current();
1241     ResourceMark rm(THREAD);
1242     int length = sig_extended.length();
1243     char* sig_str = NEW_RESOURCE_ARRAY(char, 2*length + 3);
1244     int idx = 0;
1245     sig_str[idx++] = '(';
1246     for (int index = 0; index < length; index++) {
1247       BasicType bt = sig_extended.at(index)._bt;
1248       if (bt == T_VALUETYPE) {
1249         has_value_argument = true;




1250       } else if (bt == T_VOID) {
1251         // Ignore
1252       } else {
1253         if (bt == T_ARRAY) {
1254           bt = T_OBJECT; // We don't know the element type, treat as Object
1255         }
1256         sig_str[idx++] = type2char(bt);
1257         if (bt == T_OBJECT) {
1258           sig_str[idx++] = ';';
1259         }
1260       }
1261     }
1262     sig_str[idx++] = ')';
1263     sig_str[idx++] = '\0';
1264     if (has_value_argument) {
1265       // Extended signature is only required if a value type argument is passed
1266       extended_signature = SymbolTable::new_permanent_symbol(sig_str, THREAD);
1267     }
1268   }
1269 


4183     BasicType bt = sig_vk->at(i)._bt;
4184     if (bt == T_VALUETYPE) {
4185       continue;
4186     }
4187     if (bt == T_VOID) {
4188       if (sig_vk->at(i-1)._bt == T_LONG ||
4189           sig_vk->at(i-1)._bt == T_DOUBLE) {
4190         j++;
4191       }
4192       continue;
4193     }
4194     int off = sig_vk->at(i)._offset;
4195     VMRegPair pair = regs->at(j);
4196     VMReg r_1 = pair.first();
4197     VMReg r_2 = pair.second();
4198     Address to(rax, off);
4199     if (bt == T_FLOAT) {
4200       __ movflt(to, r_1->as_XMMRegister());
4201     } else if (bt == T_DOUBLE) {
4202       __ movdbl(to, r_1->as_XMMRegister());
4203     } else if (bt == T_OBJECT || bt == T_ARRAY) {
4204       __ store_heap_oop(to, r_1->as_Register());
4205     } else {
4206       assert(is_java_primitive(bt), "unexpected basic type");
4207       size_t size_in_bytes = type2aelembytes(bt);
4208       __ store_sized_value(to, r_1->as_Register(), size_in_bytes);
4209     }
4210     j++;
4211   }
4212   assert(j == regs->length(), "missed a field?");
4213 
4214   __ ret(0);
4215 
4216   int unpack_fields_off = __ offset();
4217 
4218   j = 1;
4219   for (int i = 0; i < sig_vk->length(); i++) {
4220     BasicType bt = sig_vk->at(i)._bt;
4221     if (bt == T_VALUETYPE) {
4222       continue;
4223     }
4224     if (bt == T_VOID) {
4225       if (sig_vk->at(i-1)._bt == T_LONG ||
4226           sig_vk->at(i-1)._bt == T_DOUBLE) {
4227         j++;
4228       }
4229       continue;
4230     }
4231     int off = sig_vk->at(i)._offset;
4232     VMRegPair pair = regs->at(j);
4233     VMReg r_1 = pair.first();
4234     VMReg r_2 = pair.second();
4235     Address from(rax, off);
4236     if (bt == T_FLOAT) {
4237       __ movflt(r_1->as_XMMRegister(), from);
4238     } else if (bt == T_DOUBLE) {
4239       __ movdbl(r_1->as_XMMRegister(), from);
4240     } else if (bt == T_OBJECT || bt == T_ARRAY) {
4241       __ load_heap_oop(r_1->as_Register(), from);
4242     } else {
4243       assert(is_java_primitive(bt), "unexpected basic type");
4244       size_t size_in_bytes = type2aelembytes(bt);
4245       __ load_sized_value(r_1->as_Register(), from, size_in_bytes, bt != T_CHAR && bt != T_BOOLEAN);
4246     }
4247     j++;
4248   }
4249   assert(j == regs->length(), "missed a field?");
4250 
4251   if (StressValueTypeReturnedAsFields) {
4252     __ load_klass(rax, rax);
4253     __ orptr(rax, 1);
4254   }
4255 
4256   __ ret(0);
4257 
4258   __ flush();
4259 
4260   return BufferedValueTypeBlob::create(&buffer, pack_fields_off, unpack_fields_off);


 466     case T_CHAR:
 467     case T_BYTE:
 468     case T_SHORT:
 469     case T_INT:
 470       if (int_args < Argument::n_int_register_parameters_j) {
 471         regs[i].set1(INT_ArgReg[int_args++]->as_VMReg());
 472       } else {
 473         regs[i].set1(VMRegImpl::stack2reg(stk_args));
 474         stk_args += 2;
 475       }
 476       break;
 477     case T_VOID:
 478       // halves of T_LONG or T_DOUBLE
 479       assert(i != 0 && (sig_bt[i - 1] == T_LONG || sig_bt[i - 1] == T_DOUBLE), "expecting half");
 480       regs[i].set_bad();
 481       break;
 482     case T_LONG:
 483       assert((i + 1) < total_args_passed && sig_bt[i + 1] == T_VOID, "expecting half");
 484       // fall through
 485     case T_OBJECT:
 486     case T_VALUETYPE:
 487     case T_ARRAY:
 488     case T_ADDRESS:
 489     case T_VALUETYPEPTR:
 490       if (int_args < Argument::n_int_register_parameters_j) {
 491         regs[i].set2(INT_ArgReg[int_args++]->as_VMReg());
 492       } else {
 493         regs[i].set2(VMRegImpl::stack2reg(stk_args));
 494         stk_args += 2;
 495       }
 496       break;
 497     case T_FLOAT:
 498       if (fp_args < Argument::n_float_register_parameters_j) {
 499         regs[i].set1(FP_ArgReg[fp_args++]->as_VMReg());
 500       } else {
 501         regs[i].set1(VMRegImpl::stack2reg(stk_args));
 502         stk_args += 2;
 503       }
 504       break;
 505     case T_DOUBLE:
 506       assert((i + 1) < total_args_passed && sig_bt[i + 1] == T_VOID, "expecting half");


 877       // argument when we hit the T_VOID that acts as an end of value
 878       // type delimiter for this value type. Value types are flattened
 879       // so we might encounter embedded value types. Each entry in
 880       // sig_extended contains a field offset in the buffer.
 881       do {
 882         next_arg_comp++;
 883         BasicType bt = sig_extended.at(next_arg_comp)._bt;
 884         BasicType prev_bt = sig_extended.at(next_arg_comp-1)._bt;
 885         if (bt == T_VALUETYPE) {
 886           vt++;
 887           ignored++;
 888         } else if (bt == T_VOID &&
 889                    prev_bt != T_LONG &&
 890                    prev_bt != T_DOUBLE) {
 891           vt--;
 892           ignored++;
 893         } else {
 894           int off = sig_extended.at(next_arg_comp)._offset;
 895           assert(off > 0, "offset in object should be positive");
 896           size_t size_in_bytes = is_java_primitive(bt) ? type2aelembytes(bt) : wordSize;
 897           bool is_oop = (bt == T_OBJECT || bt == T_VALUETYPEPTR || bt == T_ARRAY);
 898           has_oop_field = has_oop_field || is_oop;
 899           gen_c2i_adapter_helper(masm, bt, next_arg_comp > 0 ? sig_extended.at(next_arg_comp-1)._bt : T_ILLEGAL,
 900                                  size_in_bytes, regs[next_arg_comp-ignored], Address(r11, off), extraspace, is_oop);
 901         }
 902       } while (vt != 0);
 903       // pass the buffer to the interpreter
 904       __ movptr(Address(rsp, st_off), r11);
 905     }
 906   }
 907 
 908   // If a value type was allocated and initialized, apply post barrier to all oop fields
 909   if (has_value_argument && has_oop_field) {
 910     __ push(r13); // save senderSP
 911     __ push(rbx); // save callee
 912     // Allocate argument register save area
 913     if (frame::arg_reg_save_area_bytes != 0) {
 914       __ subptr(rsp, frame::arg_reg_save_area_bytes);
 915     }
 916     __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::apply_post_barriers), r15_thread, r10);
 917     // De-allocate argument register save area


1136       // T_VOID that acts as an end of value type delimiter for this
1137       // value type. Value types are flattened so we might encounter
1138       // embedded value types. Each entry in sig_extended contains a
1139       // field offset in the buffer.
1140       do {
1141         next_arg_comp++;
1142         BasicType bt = sig_extended.at(next_arg_comp)._bt;
1143         BasicType prev_bt = sig_extended.at(next_arg_comp-1)._bt;
1144         if (bt == T_VALUETYPE) {
1145           vt++;
1146           ignored++;
1147         } else if (bt == T_VOID &&
1148                    prev_bt != T_LONG &&
1149                    prev_bt != T_DOUBLE) {
1150           vt--;
1151           ignored++;
1152         } else {
1153           int off = sig_extended.at(next_arg_comp)._offset;
1154           assert(off > 0, "offset in object should be positive");
1155           size_t size_in_bytes = is_java_primitive(bt) ? type2aelembytes(bt) : wordSize;
1156           bool is_oop = (bt == T_OBJECT || bt == T_VALUETYPEPTR || bt == T_ARRAY);
1157           gen_i2c_adapter_helper(masm, bt, prev_bt, size_in_bytes, regs[next_arg_comp - ignored], Address(r10, off), is_oop);
1158         }
1159       } while (vt != 0);
1160     }
1161   }
1162 
1163   // 6243940 We might end up in handle_wrong_method if
1164   // the callee is deoptimized as we race thru here. If that
1165   // happens we don't want to take a safepoint because the
1166   // caller frame will look interpreted and arguments are now
1167   // "compiled" so it is much better to make this transition
1168   // invisible to the stack walking code. Unfortunately if
1169   // we try and find the callee by normal means a safepoint
1170   // is possible. So we stash the desired callee in the thread
1171   // and the vm will find there should this case occur.
1172 
1173   __ movptr(Address(r15_thread, JavaThread::callee_target_offset()), rbx);
1174 
1175   // put Method* where a c2i would expect should we end up there
1176   // only needed because of c2 resolve stubs return Method* as a result in


1231   gen_c2i_adapter(masm, sig_extended, regs, skip_fixup, i2c_entry, oop_maps, frame_complete, frame_size_in_words);
1232 
1233   __ flush();
1234   new_adapter = AdapterBlob::create(masm->code(), frame_complete, frame_size_in_words, oop_maps);
1235 
1236   // If value types are passed as fields, save the extended signature as symbol in
1237   // the AdapterHandlerEntry to be used by nmethod::preserve_callee_argument_oops().
1238   Symbol* extended_signature = NULL;
1239   if (ValueTypePassFieldsAsArgs) {
1240     bool has_value_argument = false;
1241     Thread* THREAD = Thread::current();
1242     ResourceMark rm(THREAD);
1243     int length = sig_extended.length();
1244     char* sig_str = NEW_RESOURCE_ARRAY(char, 2*length + 3);
1245     int idx = 0;
1246     sig_str[idx++] = '(';
1247     for (int index = 0; index < length; index++) {
1248       BasicType bt = sig_extended.at(index)._bt;
1249       if (bt == T_VALUETYPE) {
1250         has_value_argument = true;
1251       } else if (bt == T_VALUETYPEPTR) {
1252         // non-flattened value type field
1253         sig_str[idx++] = type2char(T_VALUETYPE);
1254         sig_str[idx++] = ';';
1255       } else if (bt == T_VOID) {
1256         // Ignore
1257       } else {
1258         if (bt == T_ARRAY) {
1259           bt = T_OBJECT; // We don't know the element type, treat as Object
1260         }
1261         sig_str[idx++] = type2char(bt);
1262         if (bt == T_OBJECT) {
1263           sig_str[idx++] = ';';
1264         }
1265       }
1266     }
1267     sig_str[idx++] = ')';
1268     sig_str[idx++] = '\0';
1269     if (has_value_argument) {
1270       // Extended signature is only required if a value type argument is passed
1271       extended_signature = SymbolTable::new_permanent_symbol(sig_str, THREAD);
1272     }
1273   }
1274 


4188     BasicType bt = sig_vk->at(i)._bt;
4189     if (bt == T_VALUETYPE) {
4190       continue;
4191     }
4192     if (bt == T_VOID) {
4193       if (sig_vk->at(i-1)._bt == T_LONG ||
4194           sig_vk->at(i-1)._bt == T_DOUBLE) {
4195         j++;
4196       }
4197       continue;
4198     }
4199     int off = sig_vk->at(i)._offset;
4200     VMRegPair pair = regs->at(j);
4201     VMReg r_1 = pair.first();
4202     VMReg r_2 = pair.second();
4203     Address to(rax, off);
4204     if (bt == T_FLOAT) {
4205       __ movflt(to, r_1->as_XMMRegister());
4206     } else if (bt == T_DOUBLE) {
4207       __ movdbl(to, r_1->as_XMMRegister());
4208     } else if (bt == T_OBJECT || bt == T_VALUETYPEPTR || bt == T_ARRAY) {
4209       __ store_heap_oop(to, r_1->as_Register());
4210     } else {
4211       assert(is_java_primitive(bt), "unexpected basic type");
4212       size_t size_in_bytes = type2aelembytes(bt);
4213       __ store_sized_value(to, r_1->as_Register(), size_in_bytes);
4214     }
4215     j++;
4216   }
4217   assert(j == regs->length(), "missed a field?");
4218 
4219   __ ret(0);
4220 
4221   int unpack_fields_off = __ offset();
4222 
4223   j = 1;
4224   for (int i = 0; i < sig_vk->length(); i++) {
4225     BasicType bt = sig_vk->at(i)._bt;
4226     if (bt == T_VALUETYPE) {
4227       continue;
4228     }
4229     if (bt == T_VOID) {
4230       if (sig_vk->at(i-1)._bt == T_LONG ||
4231           sig_vk->at(i-1)._bt == T_DOUBLE) {
4232         j++;
4233       }
4234       continue;
4235     }
4236     int off = sig_vk->at(i)._offset;
4237     VMRegPair pair = regs->at(j);
4238     VMReg r_1 = pair.first();
4239     VMReg r_2 = pair.second();
4240     Address from(rax, off);
4241     if (bt == T_FLOAT) {
4242       __ movflt(r_1->as_XMMRegister(), from);
4243     } else if (bt == T_DOUBLE) {
4244       __ movdbl(r_1->as_XMMRegister(), from);
4245     } else if (bt == T_OBJECT || bt == T_VALUETYPEPTR || bt == T_ARRAY) {
4246       __ load_heap_oop(r_1->as_Register(), from);
4247     } else {
4248       assert(is_java_primitive(bt), "unexpected basic type");
4249       size_t size_in_bytes = type2aelembytes(bt);
4250       __ load_sized_value(r_1->as_Register(), from, size_in_bytes, bt != T_CHAR && bt != T_BOOLEAN);
4251     }
4252     j++;
4253   }
4254   assert(j == regs->length(), "missed a field?");
4255 
4256   if (StressValueTypeReturnedAsFields) {
4257     __ load_klass(rax, rax);
4258     __ orptr(rax, 1);
4259   }
4260 
4261   __ ret(0);
4262 
4263   __ flush();
4264 
4265   return BufferedValueTypeBlob::create(&buffer, pack_fields_off, unpack_fields_off);
< prev index next >