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