< prev index next >

src/share/vm/runtime/sharedRuntime.cpp

Print this page




2693     GrowableArray<SigEntry> sig_extended;
2694     {
2695       MutexUnlocker mul(AdapterHandlerLibrary_lock);
2696       Thread* THREAD = Thread::current();
2697       Klass* holder = method->method_holder();
2698       GrowableArray<BasicType> sig_bt_tmp;
2699 
2700       int i = 0;
2701       if (!method->is_static()) {  // Pass in receiver first
2702         if (ValueTypePassFieldsAsArgs && holder->is_value()) {
2703           ValueKlass* vk = ValueKlass::cast(holder);
2704           if (vk == SystemDictionary::___Value_klass()) {
2705             // If the holder of the method is __Value, we must pass a
2706             // reference. FIXME: this shouldn't be T_OBJECT as a value
2707             // type reference is not necessarily an oop. Ideally we
2708             // would use T_VALUETYPE but we can't because T_VALUETYPE
2709             // is used here as a marker right before the list of
2710             // fields for the value type.
2711             sig_extended.push(SigEntry(T_OBJECT));
2712           } else {
2713             const GrowableArray<SigEntry>& sig_vk = vk->collect_fields();
2714             sig_extended.appendAll(&sig_vk);
2715           }
2716         } else {
2717           sig_extended.push(SigEntry(T_OBJECT));
2718         }
2719       }
2720       for (SignatureStream ss(method->signature()); !ss.at_return_type(); ss.next()) {
2721         if (ValueTypePassFieldsAsArgs && ss.type() == T_VALUETYPE) {
2722           Klass* k = ss.as_klass(Handle(THREAD, holder->class_loader()),
2723                                  Handle(THREAD, holder->protection_domain()),
2724                                  SignatureStream::ReturnNull, THREAD);
2725           assert(k != NULL && !HAS_PENDING_EXCEPTION, "can resolve klass?");
2726           ValueKlass* vk = ValueKlass::cast(k);
2727           if (vk == SystemDictionary::___Value_klass()) {
2728             assert(method->is_compiled_lambda_form() || method->is_method_handle_intrinsic(),
2729                    "should not use __Value for a value type argument");
2730             sig_extended.push(SigEntry(T_OBJECT));
2731           } else {
2732             const GrowableArray<SigEntry>& sig_vk = vk->collect_fields();
2733             sig_extended.appendAll(&sig_vk);
2734           }
2735         } else {
2736           sig_extended.push(SigEntry(ss.type()));
2737           if (ss.type() == T_LONG || ss.type() == T_DOUBLE) {
2738             sig_extended.push(SigEntry(T_VOID));
2739           }
2740         }
2741       }
2742     }
2743 
2744     int total_args_passed_cc = ValueTypePassFieldsAsArgs ? SigEntry::count_fields(sig_extended) : sig_extended.length();
2745     BasicType* sig_bt_cc = NEW_RESOURCE_ARRAY(BasicType, total_args_passed_cc);
2746     SigEntry::fill_sig_bt(sig_extended, sig_bt_cc, total_args_passed_cc, ValueTypePassFieldsAsArgs);
2747 
2748     int total_args_passed_fp = sig_extended.length();
2749     BasicType* sig_bt_fp = NEW_RESOURCE_ARRAY(BasicType, total_args_passed_fp);
2750     for (int i = 0; i < sig_extended.length(); i++) {
2751       sig_bt_fp[i] = sig_extended.at(i)._bt;
2752     }
2753 


3337         map++;
3338       }
3339     }
3340   }
3341 }
3342 JRT_END
3343 
3344 // We're returning from an interpreted method: load each field into a
3345 // register following the calling convention
3346 JRT_LEAF(void, SharedRuntime::load_value_type_fields_in_regs(JavaThread* thread, oopDesc* res))
3347 {
3348   assert(res->klass()->is_value(), "only value types here");
3349   ResourceMark rm;
3350   RegisterMap reg_map(thread);
3351   frame stubFrame = thread->last_frame();
3352   frame callerFrame = stubFrame.sender(&reg_map);
3353   assert(callerFrame.is_interpreted_frame(), "should be coming from interpreter");
3354 
3355   ValueKlass* vk = ValueKlass::cast(res->klass());
3356 
3357   VMRegPair* regs;
3358   int nb_fields;
3359   const GrowableArray<SigEntry>& sig_vk = vk->return_convention(regs, nb_fields);
3360 
3361   if (regs == NULL) {
3362     // The fields of the value klass don't fit in registers, bail out
3363     return;
3364   }
3365 
3366   int j = 1;
3367   for (int i = 0; i < sig_vk.length(); i++) {
3368     BasicType bt = sig_vk.at(i)._bt;
3369     if (bt == T_VALUETYPE) {
3370       continue;
3371     }
3372     if (bt == T_VOID) {
3373       if (sig_vk.at(i-1)._bt == T_LONG ||
3374           sig_vk.at(i-1)._bt == T_DOUBLE) {
3375         j++;
3376       }
3377       continue;
3378     }
3379     int off = sig_vk.at(i)._offset;
3380     VMRegPair pair = regs[j];
3381     address loc = reg_map.location(pair.first());
3382     switch(bt) {
3383     case T_BOOLEAN:
3384       *(intptr_t*)loc = *(jboolean*)((address)res + off);
3385       break;
3386     case T_CHAR:
3387       *(intptr_t*)loc = *(jchar*)((address)res + off);
3388       break;
3389     case T_BYTE:
3390       *(intptr_t*)loc = *(jbyte*)((address)res + off);
3391       break;
3392     case T_SHORT:
3393       *(intptr_t*)loc = *(jshort*)((address)res + off);
3394       break;
3395     case T_INT: {
3396       jint v = *(jint*)((address)res + off);
3397       *(intptr_t*)loc = v;
3398       break;
3399     }
3400     case T_LONG:


3411         oop* p = (oop*)((address)res + off);
3412         v = oopDesc::load_heap_oop(p);
3413       } else {
3414         narrowOop* p = (narrowOop*)((address)res + off);
3415         v = oopDesc::load_decode_heap_oop(p);
3416       }
3417       *(oop*)loc = v;
3418       break;
3419     }
3420     case T_FLOAT:
3421       *(jfloat*)loc = *(jfloat*)((address)res + off);
3422       break;
3423     case T_DOUBLE:
3424       *(jdouble*)loc = *(jdouble*)((address)res + off);
3425       break;
3426     default:
3427       ShouldNotReachHere();
3428     }
3429     j++;
3430   }
3431   assert(j == nb_fields, "missed a field?");
3432 
3433 #ifdef ASSERT
3434   VMRegPair pair = regs[0];
3435   address loc = reg_map.location(pair.first());
3436   assert(*(oopDesc**)loc == res, "overwritten object");
3437 #endif
3438 
3439   thread->set_vm_result(res);
3440 }
3441 JRT_END
3442 
3443 // We've returned to an interpreted method, the interpreter needs a
3444 // reference to a value type instance. Allocate it and initialize it
3445 // from field's values in registers.
3446 JRT_BLOCK_ENTRY(void, SharedRuntime::store_value_type_fields_to_buf(JavaThread* thread, intptr_t res))
3447 {
3448   ResourceMark rm;
3449   RegisterMap reg_map(thread);
3450   frame stubFrame = thread->last_frame();
3451   frame callerFrame = stubFrame.sender(&reg_map);
3452 
3453 #ifdef ASSERT
3454   ValueKlass* verif_vk = ValueKlass::returned_value_type(reg_map);
3455   javaVFrame* vf = javaVFrame::cast(vframe::new_vframe(&callerFrame, &reg_map, thread));
3456   Method* m = vf->method();
3457   int bci = vf->bci();
3458   Bytecode_invoke inv(m, bci);
3459 
3460   {
3461     NoSafepointVerifier nsv;
3462     methodHandle callee = inv.static_target(thread);
3463     assert(!thread->has_pending_exception(), "call resolution should work");
3464     ValueKlass* verif_vk2 = callee->returned_value_type(thread);
3465     assert(verif_vk == NULL || verif_vk == verif_vk2 ||
3466            verif_vk2 == SystemDictionary::___Value_klass(), "Bad value klass");
3467 
3468   }
3469 #endif
3470 
3471     if (!Metaspace::contains((void*)res)) {
3472     // We're not returning with value type fields in registers (the
3473     // calling convention didn't allow it for this value klass)

3474     thread->set_vm_result((oopDesc*)res);
3475     assert(verif_vk == NULL, "broken calling convention");
3476     return;
3477   }
3478 

3479   ValueKlass* vk = (ValueKlass*)res;
3480   assert(verif_vk == vk, "broken calling convention");
3481 
3482   VMRegPair* regs;
3483   int nb_fields;
3484   const GrowableArray<SigEntry>& sig_vk = vk->return_convention(regs, nb_fields);
3485   assert(regs != NULL, "return convention should allow return as fields");
3486 
3487   regs++;
3488   nb_fields--;
3489 
3490   // Allocate handles for every oop fields so they are safe in case of
3491   // a safepoint when allocating
3492   GrowableArray<Handle> handles;
3493   vk->save_oop_fields(sig_vk, reg_map, regs, handles, nb_fields);
3494 
3495   // It's unsafe to safepoint until we are here
3496 
3497   Handle new_vt;
3498   JRT_BLOCK;
3499   {
3500     Thread* THREAD = thread;
3501     oop vt = vk->realloc_result(sig_vk, reg_map, regs, handles, nb_fields, CHECK);
3502     new_vt = Handle(thread, vt);












3503   }
3504   JRT_BLOCK_END;
3505 
3506   thread->set_vm_result(new_vt());
3507 }
3508 JRT_END
3509 


2693     GrowableArray<SigEntry> sig_extended;
2694     {
2695       MutexUnlocker mul(AdapterHandlerLibrary_lock);
2696       Thread* THREAD = Thread::current();
2697       Klass* holder = method->method_holder();
2698       GrowableArray<BasicType> sig_bt_tmp;
2699 
2700       int i = 0;
2701       if (!method->is_static()) {  // Pass in receiver first
2702         if (ValueTypePassFieldsAsArgs && holder->is_value()) {
2703           ValueKlass* vk = ValueKlass::cast(holder);
2704           if (vk == SystemDictionary::___Value_klass()) {
2705             // If the holder of the method is __Value, we must pass a
2706             // reference. FIXME: this shouldn't be T_OBJECT as a value
2707             // type reference is not necessarily an oop. Ideally we
2708             // would use T_VALUETYPE but we can't because T_VALUETYPE
2709             // is used here as a marker right before the list of
2710             // fields for the value type.
2711             sig_extended.push(SigEntry(T_OBJECT));
2712           } else {
2713             const Array<SigEntry>* sig_vk = vk->extended_sig();
2714             sig_extended.appendAll(sig_vk);
2715           }
2716         } else {
2717           sig_extended.push(SigEntry(T_OBJECT));
2718         }
2719       }
2720       for (SignatureStream ss(method->signature()); !ss.at_return_type(); ss.next()) {
2721         if (ValueTypePassFieldsAsArgs && ss.type() == T_VALUETYPE) {
2722           Klass* k = ss.as_klass(Handle(THREAD, holder->class_loader()),
2723                                  Handle(THREAD, holder->protection_domain()),
2724                                  SignatureStream::ReturnNull, THREAD);
2725           assert(k != NULL && !HAS_PENDING_EXCEPTION, "can resolve klass?");
2726           ValueKlass* vk = ValueKlass::cast(k);
2727           if (vk == SystemDictionary::___Value_klass()) {
2728             assert(method->is_compiled_lambda_form() || method->is_method_handle_intrinsic(),
2729                    "should not use __Value for a value type argument");
2730             sig_extended.push(SigEntry(T_OBJECT));
2731           } else {
2732             const Array<SigEntry>* sig_vk = vk->extended_sig();
2733             sig_extended.appendAll(sig_vk);
2734           }
2735         } else {
2736           sig_extended.push(SigEntry(ss.type()));
2737           if (ss.type() == T_LONG || ss.type() == T_DOUBLE) {
2738             sig_extended.push(SigEntry(T_VOID));
2739           }
2740         }
2741       }
2742     }
2743 
2744     int total_args_passed_cc = ValueTypePassFieldsAsArgs ? SigEntry::count_fields(sig_extended) : sig_extended.length();
2745     BasicType* sig_bt_cc = NEW_RESOURCE_ARRAY(BasicType, total_args_passed_cc);
2746     SigEntry::fill_sig_bt(sig_extended, sig_bt_cc, total_args_passed_cc, ValueTypePassFieldsAsArgs);
2747 
2748     int total_args_passed_fp = sig_extended.length();
2749     BasicType* sig_bt_fp = NEW_RESOURCE_ARRAY(BasicType, total_args_passed_fp);
2750     for (int i = 0; i < sig_extended.length(); i++) {
2751       sig_bt_fp[i] = sig_extended.at(i)._bt;
2752     }
2753 


3337         map++;
3338       }
3339     }
3340   }
3341 }
3342 JRT_END
3343 
3344 // We're returning from an interpreted method: load each field into a
3345 // register following the calling convention
3346 JRT_LEAF(void, SharedRuntime::load_value_type_fields_in_regs(JavaThread* thread, oopDesc* res))
3347 {
3348   assert(res->klass()->is_value(), "only value types here");
3349   ResourceMark rm;
3350   RegisterMap reg_map(thread);
3351   frame stubFrame = thread->last_frame();
3352   frame callerFrame = stubFrame.sender(&reg_map);
3353   assert(callerFrame.is_interpreted_frame(), "should be coming from interpreter");
3354 
3355   ValueKlass* vk = ValueKlass::cast(res->klass());
3356 
3357   const Array<SigEntry>* sig_vk = vk->extended_sig() ;
3358   const Array<VMRegPair>* regs = vk->return_regs();

3359 
3360   if (regs == NULL) {
3361     // The fields of the value klass don't fit in registers, bail out
3362     return;
3363   }
3364 
3365   int j = 1;
3366   for (int i = 0; i < sig_vk->length(); i++) {
3367     BasicType bt = sig_vk->at(i)._bt;
3368     if (bt == T_VALUETYPE) {
3369       continue;
3370     }
3371     if (bt == T_VOID) {
3372       if (sig_vk->at(i-1)._bt == T_LONG ||
3373           sig_vk->at(i-1)._bt == T_DOUBLE) {
3374         j++;
3375       }
3376       continue;
3377     }
3378     int off = sig_vk->at(i)._offset;
3379     VMRegPair pair = regs->at(j);
3380     address loc = reg_map.location(pair.first());
3381     switch(bt) {
3382     case T_BOOLEAN:
3383       *(intptr_t*)loc = *(jboolean*)((address)res + off);
3384       break;
3385     case T_CHAR:
3386       *(intptr_t*)loc = *(jchar*)((address)res + off);
3387       break;
3388     case T_BYTE:
3389       *(intptr_t*)loc = *(jbyte*)((address)res + off);
3390       break;
3391     case T_SHORT:
3392       *(intptr_t*)loc = *(jshort*)((address)res + off);
3393       break;
3394     case T_INT: {
3395       jint v = *(jint*)((address)res + off);
3396       *(intptr_t*)loc = v;
3397       break;
3398     }
3399     case T_LONG:


3410         oop* p = (oop*)((address)res + off);
3411         v = oopDesc::load_heap_oop(p);
3412       } else {
3413         narrowOop* p = (narrowOop*)((address)res + off);
3414         v = oopDesc::load_decode_heap_oop(p);
3415       }
3416       *(oop*)loc = v;
3417       break;
3418     }
3419     case T_FLOAT:
3420       *(jfloat*)loc = *(jfloat*)((address)res + off);
3421       break;
3422     case T_DOUBLE:
3423       *(jdouble*)loc = *(jdouble*)((address)res + off);
3424       break;
3425     default:
3426       ShouldNotReachHere();
3427     }
3428     j++;
3429   }
3430   assert(j == regs->length(), "missed a field?");
3431 
3432 #ifdef ASSERT
3433   VMRegPair pair = regs->at(0);
3434   address loc = reg_map.location(pair.first());
3435   assert(*(oopDesc**)loc == res, "overwritten object");
3436 #endif
3437 
3438   thread->set_vm_result(res);
3439 }
3440 JRT_END
3441 
3442 // We've returned to an interpreted method, the interpreter needs a
3443 // reference to a value type instance. Allocate it and initialize it
3444 // from field's values in registers.
3445 JRT_BLOCK_ENTRY(void, SharedRuntime::store_value_type_fields_to_buf(JavaThread* thread, intptr_t res))
3446 {
3447   ResourceMark rm;
3448   RegisterMap reg_map(thread);
3449   frame stubFrame = thread->last_frame();
3450   frame callerFrame = stubFrame.sender(&reg_map);
3451 
3452 #ifdef ASSERT
3453   ValueKlass* verif_vk = ValueKlass::returned_value_type(reg_map);














3454 #endif
3455 
3456   if ((res & 1) == 0) {
3457     // We're not returning with value type fields in registers (the
3458     // calling convention didn't allow it for this value klass)
3459     assert(!Metaspace::contains((void*)res), "should be oop or pointer in buffer area");
3460     thread->set_vm_result((oopDesc*)res);
3461     assert(verif_vk == NULL, "broken calling convention");
3462     return;
3463   }
3464 
3465   res = res & ~1L;
3466   ValueKlass* vk = (ValueKlass*)res;
3467   assert(verif_vk == vk, "broken calling convention");
3468   assert(Metaspace::contains((void*)res), "should be klass");







3469 
3470   // Allocate handles for every oop fields so they are safe in case of
3471   // a safepoint when allocating
3472   GrowableArray<Handle> handles;
3473   vk->save_oop_fields(reg_map, handles);
3474 
3475   // It's unsafe to safepoint until we are here
3476 
3477   Handle new_vt;
3478   JRT_BLOCK;
3479   {
3480     Thread* THREAD = thread;
3481     oop vt = vk->realloc_result(reg_map, handles, CHECK);
3482     new_vt = Handle(thread, vt);
3483 
3484 #ifdef ASSERT
3485     javaVFrame* vf = javaVFrame::cast(vframe::new_vframe(&callerFrame, &reg_map, thread));
3486     Method* m = vf->method();
3487     int bci = vf->bci();
3488     Bytecode_invoke inv(m, bci);
3489 
3490     methodHandle callee = inv.static_target(thread);
3491     assert(!thread->has_pending_exception(), "call resolution should work");
3492     ValueKlass* verif_vk2 = callee->returned_value_type(thread);
3493     assert(verif_vk == verif_vk2 || verif_vk2 == SystemDictionary::___Value_klass(), "Bad value klass");
3494 #endif
3495   }
3496   JRT_BLOCK_END;
3497 
3498   thread->set_vm_result(new_vt());
3499 }
3500 JRT_END
3501 
< prev index next >