< prev index next >

src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp

Print this page




 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);


 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_VALUETYPEPTR || 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_VALUETYPEPTR || 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_VALUETYPEPTR) {
1251         // non-flattened value type field
1252         sig_str[idx++] = type2char(T_VALUETYPE);
1253         sig_str[idx++] = ';';
1254       } else if (bt == T_VOID) {
1255         // Ignore
1256       } else {
1257         if (bt == T_ARRAY) {
1258           bt = T_OBJECT; // We don't know the element type, treat as Object
1259         }
1260         sig_str[idx++] = type2char(bt);
1261         if (bt == T_OBJECT) {
1262           sig_str[idx++] = ';';
1263         }
1264       }
1265     }
1266     sig_str[idx++] = ')';
1267     sig_str[idx++] = '\0';
1268     if (has_value_argument) {
1269       // Extended signature is only required if a value type argument is passed
1270       extended_signature = SymbolTable::new_permanent_symbol(sig_str, THREAD);
1271     }
1272   }
1273 


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