< prev index next >
src/share/vm/runtime/sharedRuntime.cpp
Print this page
*** 2708,2719 ****
// would use T_VALUETYPE but we can't because T_VALUETYPE
// is used here as a marker right before the list of
// fields for the value type.
sig_extended.push(SigEntry(T_OBJECT));
} else {
! const GrowableArray<SigEntry>& sig_vk = vk->collect_fields();
! sig_extended.appendAll(&sig_vk);
}
} else {
sig_extended.push(SigEntry(T_OBJECT));
}
}
--- 2708,2719 ----
// would use T_VALUETYPE but we can't because T_VALUETYPE
// is used here as a marker right before the list of
// fields for the value type.
sig_extended.push(SigEntry(T_OBJECT));
} else {
! const Array<SigEntry>* sig_vk = vk->extended_sig();
! sig_extended.appendAll(sig_vk);
}
} else {
sig_extended.push(SigEntry(T_OBJECT));
}
}
*** 2727,2738 ****
if (vk == SystemDictionary::___Value_klass()) {
assert(method->is_compiled_lambda_form() || method->is_method_handle_intrinsic(),
"should not use __Value for a value type argument");
sig_extended.push(SigEntry(T_OBJECT));
} else {
! const GrowableArray<SigEntry>& sig_vk = vk->collect_fields();
! sig_extended.appendAll(&sig_vk);
}
} else {
sig_extended.push(SigEntry(ss.type()));
if (ss.type() == T_LONG || ss.type() == T_DOUBLE) {
sig_extended.push(SigEntry(T_VOID));
--- 2727,2738 ----
if (vk == SystemDictionary::___Value_klass()) {
assert(method->is_compiled_lambda_form() || method->is_method_handle_intrinsic(),
"should not use __Value for a value type argument");
sig_extended.push(SigEntry(T_OBJECT));
} else {
! const Array<SigEntry>* sig_vk = vk->extended_sig();
! sig_extended.appendAll(sig_vk);
}
} else {
sig_extended.push(SigEntry(ss.type()));
if (ss.type() == T_LONG || ss.type() == T_DOUBLE) {
sig_extended.push(SigEntry(T_VOID));
*** 3352,3385 ****
frame callerFrame = stubFrame.sender(®_map);
assert(callerFrame.is_interpreted_frame(), "should be coming from interpreter");
ValueKlass* vk = ValueKlass::cast(res->klass());
! VMRegPair* regs;
! int nb_fields;
! const GrowableArray<SigEntry>& sig_vk = vk->return_convention(regs, nb_fields);
if (regs == NULL) {
// The fields of the value klass don't fit in registers, bail out
return;
}
int j = 1;
! for (int i = 0; i < sig_vk.length(); i++) {
! BasicType bt = sig_vk.at(i)._bt;
if (bt == T_VALUETYPE) {
continue;
}
if (bt == T_VOID) {
! if (sig_vk.at(i-1)._bt == T_LONG ||
! sig_vk.at(i-1)._bt == T_DOUBLE) {
j++;
}
continue;
}
! int off = sig_vk.at(i)._offset;
! VMRegPair pair = regs[j];
address loc = reg_map.location(pair.first());
switch(bt) {
case T_BOOLEAN:
*(intptr_t*)loc = *(jboolean*)((address)res + off);
break;
--- 3352,3384 ----
frame callerFrame = stubFrame.sender(®_map);
assert(callerFrame.is_interpreted_frame(), "should be coming from interpreter");
ValueKlass* vk = ValueKlass::cast(res->klass());
! const Array<SigEntry>* sig_vk = vk->extended_sig() ;
! const Array<VMRegPair>* regs = vk->return_regs();
if (regs == NULL) {
// The fields of the value klass don't fit in registers, bail out
return;
}
int j = 1;
! for (int i = 0; i < sig_vk->length(); i++) {
! BasicType bt = sig_vk->at(i)._bt;
if (bt == T_VALUETYPE) {
continue;
}
if (bt == T_VOID) {
! if (sig_vk->at(i-1)._bt == T_LONG ||
! sig_vk->at(i-1)._bt == T_DOUBLE) {
j++;
}
continue;
}
! int off = sig_vk->at(i)._offset;
! VMRegPair pair = regs->at(j);
address loc = reg_map.location(pair.first());
switch(bt) {
case T_BOOLEAN:
*(intptr_t*)loc = *(jboolean*)((address)res + off);
break;
*** 3426,3439 ****
default:
ShouldNotReachHere();
}
j++;
}
! assert(j == nb_fields, "missed a field?");
#ifdef ASSERT
! VMRegPair pair = regs[0];
address loc = reg_map.location(pair.first());
assert(*(oopDesc**)loc == res, "overwritten object");
#endif
thread->set_vm_result(res);
--- 3425,3438 ----
default:
ShouldNotReachHere();
}
j++;
}
! assert(j == regs->length(), "missed a field?");
#ifdef ASSERT
! VMRegPair pair = regs->at(0);
address loc = reg_map.location(pair.first());
assert(*(oopDesc**)loc == res, "overwritten object");
#endif
thread->set_vm_result(res);
*** 3450,3507 ****
frame stubFrame = thread->last_frame();
frame callerFrame = stubFrame.sender(®_map);
#ifdef ASSERT
ValueKlass* verif_vk = ValueKlass::returned_value_type(reg_map);
- javaVFrame* vf = javaVFrame::cast(vframe::new_vframe(&callerFrame, ®_map, thread));
- Method* m = vf->method();
- int bci = vf->bci();
- Bytecode_invoke inv(m, bci);
-
- {
- NoSafepointVerifier nsv;
- methodHandle callee = inv.static_target(thread);
- assert(!thread->has_pending_exception(), "call resolution should work");
- ValueKlass* verif_vk2 = callee->returned_value_type(thread);
- assert(verif_vk == NULL || verif_vk == verif_vk2 ||
- verif_vk2 == SystemDictionary::___Value_klass(), "Bad value klass");
-
- }
#endif
! if (!Metaspace::contains((void*)res)) {
// We're not returning with value type fields in registers (the
// calling convention didn't allow it for this value klass)
thread->set_vm_result((oopDesc*)res);
assert(verif_vk == NULL, "broken calling convention");
return;
}
ValueKlass* vk = (ValueKlass*)res;
assert(verif_vk == vk, "broken calling convention");
!
! VMRegPair* regs;
! int nb_fields;
! const GrowableArray<SigEntry>& sig_vk = vk->return_convention(regs, nb_fields);
! assert(regs != NULL, "return convention should allow return as fields");
!
! regs++;
! nb_fields--;
// Allocate handles for every oop fields so they are safe in case of
// a safepoint when allocating
GrowableArray<Handle> handles;
! vk->save_oop_fields(sig_vk, reg_map, regs, handles, nb_fields);
// It's unsafe to safepoint until we are here
Handle new_vt;
JRT_BLOCK;
{
Thread* THREAD = thread;
! oop vt = vk->realloc_result(sig_vk, reg_map, regs, handles, nb_fields, CHECK);
new_vt = Handle(thread, vt);
}
JRT_BLOCK_END;
thread->set_vm_result(new_vt());
}
--- 3449,3499 ----
frame stubFrame = thread->last_frame();
frame callerFrame = stubFrame.sender(®_map);
#ifdef ASSERT
ValueKlass* verif_vk = ValueKlass::returned_value_type(reg_map);
#endif
! if ((res & 1) == 0) {
// We're not returning with value type fields in registers (the
// calling convention didn't allow it for this value klass)
+ assert(!Metaspace::contains((void*)res), "should be oop or pointer in buffer area");
thread->set_vm_result((oopDesc*)res);
assert(verif_vk == NULL, "broken calling convention");
return;
}
+ res = res & ~1L;
ValueKlass* vk = (ValueKlass*)res;
assert(verif_vk == vk, "broken calling convention");
! assert(Metaspace::contains((void*)res), "should be klass");
// Allocate handles for every oop fields so they are safe in case of
// a safepoint when allocating
GrowableArray<Handle> handles;
! vk->save_oop_fields(reg_map, handles);
// It's unsafe to safepoint until we are here
Handle new_vt;
JRT_BLOCK;
{
Thread* THREAD = thread;
! oop vt = vk->realloc_result(reg_map, handles, CHECK);
new_vt = Handle(thread, vt);
+
+ #ifdef ASSERT
+ javaVFrame* vf = javaVFrame::cast(vframe::new_vframe(&callerFrame, ®_map, thread));
+ Method* m = vf->method();
+ int bci = vf->bci();
+ Bytecode_invoke inv(m, bci);
+
+ methodHandle callee = inv.static_target(thread);
+ assert(!thread->has_pending_exception(), "call resolution should work");
+ ValueKlass* verif_vk2 = callee->returned_value_type(thread);
+ assert(verif_vk == verif_vk2 || verif_vk2 == SystemDictionary::___Value_klass(), "Bad value klass");
+ #endif
}
JRT_BLOCK_END;
thread->set_vm_result(new_vt());
}
< prev index next >