< 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(&reg_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(&reg_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(&reg_map); #ifdef ASSERT ValueKlass* verif_vk = ValueKlass::returned_value_type(reg_map); - javaVFrame* vf = javaVFrame::cast(vframe::new_vframe(&callerFrame, &reg_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(&reg_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, &reg_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 >