< prev index next >

src/share/vm/runtime/sharedRuntime.cpp

Print this page




2627 
2628   // Create a special handler for abstract methods.  Abstract methods
2629   // are never compiled so an i2c entry is somewhat meaningless, but
2630   // throw AbstractMethodError just in case.
2631   // Pass wrong_method_abstract for the c2i transitions to return
2632   // AbstractMethodError for invalid invocations.
2633   address wrong_method_abstract = SharedRuntime::get_handle_wrong_method_abstract_stub();
2634   _abstract_method_handler = AdapterHandlerLibrary::new_entry(new AdapterFingerPrint(0, NULL),
2635                                                               StubRoutines::throw_AbstractMethodError_entry(),
2636                                                               wrong_method_abstract, wrong_method_abstract);
2637 }
2638 
2639 AdapterHandlerEntry* AdapterHandlerLibrary::new_entry(AdapterFingerPrint* fingerprint,
2640                                                       address i2c_entry,
2641                                                       address c2i_entry,
2642                                                       address c2i_unverified_entry,
2643                                                       Symbol* sig_extended) {
2644   return _adapters->new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry, sig_extended);
2645 }
2646 
2647 // Value type arguments are not passed by reference, instead each
2648 // field of the value type is passed as an argument. This helper
2649 // function collects the fields of the value types (including embedded
2650 // value type's fields) in a list. Included with the field's type is
2651 // the offset of each field in the value type: i2c and c2i adapters
2652 // need that to load or store fields. Finally, the list of fields is
2653 // sorted in order of increasing offsets: the adapters and the
2654 // compiled code need and agreed upon order of fields.
2655 //
2656 // The list of basic type that is returned starts with a T_VALUETYPE
2657 // and ends with an extra T_VOID. T_VALUETYPE/T_VOID are used as
2658 // delimiters. Every entry between the two is a field of the value
2659 // type. If there's an embedded value type in the list, it also starts
2660 // with a T_VALUETYPE and ends with a T_VOID. This is so we can
2661 // generate a unique fingerprint for the method's adapters and we can
2662 // generate the list of basic types from the interpreter point of view
2663 // (value types passed as reference: iterate on the list until a
2664 // T_VALUETYPE, drop everything until and including the closing
2665 // T_VOID) or the compiler point of view (each field of the value
2666 // types is an argument: drop all T_VALUETYPE/T_VOID from the list).
2667 static GrowableArray<SigEntry> collect_fields(ValueKlass* vk, int base_off = 0) {
2668   GrowableArray<SigEntry> sig_extended;
2669   sig_extended.push(SigEntry(T_VALUETYPE, base_off));
2670   for (JavaFieldStream fs(vk); !fs.done(); fs.next()) {
2671     if (fs.access_flags().is_static())  continue;
2672     fieldDescriptor& fd = fs.field_descriptor();
2673     BasicType bt = fd.field_type();
2674     int offset = base_off + fd.offset() - (base_off > 0 ? vk->first_field_offset() : 0);
2675     if (bt == T_VALUETYPE) {
2676       Symbol* signature = fd.signature();
2677       JavaThread* THREAD = JavaThread::current();
2678       oop loader = vk->class_loader();
2679       oop protection_domain = vk->protection_domain();
2680       Klass* klass = SystemDictionary::resolve_or_null(signature,
2681                                                        Handle(THREAD, loader), Handle(THREAD, protection_domain),
2682                                                        THREAD);
2683       assert(klass != NULL && !HAS_PENDING_EXCEPTION, "lookup shouldn't fail");
2684       const GrowableArray<SigEntry>& embedded = collect_fields(ValueKlass::cast(klass), offset);
2685       sig_extended.appendAll(&embedded);
2686     } else {
2687       sig_extended.push(SigEntry(bt, offset));
2688       if (bt == T_LONG || bt == T_DOUBLE) {
2689         sig_extended.push(SigEntry(T_VOID, offset));
2690       }
2691     }
2692   }
2693   int offset = base_off + vk->size_helper()*HeapWordSize - (base_off > 0 ? vk->first_field_offset() : 0);
2694   sig_extended.push(SigEntry(T_VOID, offset)); // hack: use T_VOID to mark end of value type fields
2695   if (base_off == 0) {
2696     sig_extended.sort(SigEntry::compare);
2697   }
2698   assert(sig_extended.at(0)._bt == T_VALUETYPE && sig_extended.at(sig_extended.length()-1)._bt == T_VOID, "broken structure");
2699   return sig_extended;
2700 }
2701 
2702 AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(const methodHandle& method) {
2703   AdapterHandlerEntry* entry = get_adapter0(method);
2704   if (method->is_shared()) {
2705     // See comments around Method::link_method()
2706     MutexLocker mu(AdapterHandlerLibrary_lock);
2707     if (method->adapter() == NULL) {
2708       method->update_adapter_trampoline(entry);
2709     }
2710     address trampoline = method->from_compiled_entry();
2711     if (*(int*)trampoline == 0) {
2712       CodeBuffer buffer(trampoline, (int)SharedRuntime::trampoline_size());
2713       MacroAssembler _masm(&buffer);
2714       SharedRuntime::generate_trampoline(&_masm, entry->get_c2i_entry());
2715       assert(*(int*)trampoline != 0, "Instruction(s) for trampoline must not be encoded as zeros.");
2716 
2717       if (PrintInterpreter) {
2718         Disassembler::decode(buffer.insts_begin(), buffer.insts_end());
2719       }
2720     }
2721   }


2748     GrowableArray<SigEntry> sig_extended;
2749     {
2750       MutexUnlocker mul(AdapterHandlerLibrary_lock);
2751       Thread* THREAD = Thread::current();
2752       Klass* holder = method->method_holder();
2753       GrowableArray<BasicType> sig_bt_tmp;
2754 
2755       int i = 0;
2756       if (!method->is_static()) {  // Pass in receiver first
2757         if (ValueTypePassFieldsAsArgs && holder->is_value()) {
2758           ValueKlass* vk = ValueKlass::cast(holder);
2759           if (vk == SystemDictionary::___Value_klass()) {
2760             // If the holder of the method is __Value, we must pass a
2761             // reference. FIXME: this shouldn't be T_OBJECT as a value
2762             // type reference is not necessarily an oop. Ideally we
2763             // would use T_VALUETYPE but we can't because T_VALUETYPE
2764             // is used here as a marker right before the list of
2765             // fields for the value type.
2766             sig_extended.push(SigEntry(T_OBJECT));
2767           } else {
2768             const GrowableArray<SigEntry>& sig_vk = collect_fields(vk);
2769             sig_extended.appendAll(&sig_vk);
2770           }
2771         } else {
2772           sig_extended.push(SigEntry(T_OBJECT));
2773         }
2774       }
2775       for (SignatureStream ss(method->signature()); !ss.at_return_type(); ss.next()) {
2776         if (ValueTypePassFieldsAsArgs && ss.type() == T_VALUETYPE) {
2777           Klass* k = ss.as_klass(Handle(THREAD, holder->class_loader()),
2778                                  Handle(THREAD, holder->protection_domain()),
2779                                  SignatureStream::ReturnNull, THREAD);
2780           assert(k != NULL && !HAS_PENDING_EXCEPTION, "can resolve klass?");
2781           assert(k != SystemDictionary::___Value_klass(), "unsupported");
2782           ValueKlass* vk = ValueKlass::cast(k);
2783           const GrowableArray<SigEntry>& sig_vk = collect_fields(vk);



2784           sig_extended.appendAll(&sig_vk);

2785         } else {
2786           sig_extended.push(SigEntry(ss.type()));
2787           if (ss.type() == T_LONG || ss.type() == T_DOUBLE) {
2788             sig_extended.push(SigEntry(T_VOID));
2789           }
2790         }
2791       }
2792     }
2793 
2794     int values = 0;
2795     if (ValueTypePassFieldsAsArgs) {
2796       for (int i = 0; i < sig_extended.length(); i++) {
2797         if (sig_extended.at(i)._bt == T_VALUETYPE) {
2798           values++;
2799         }
2800       }
2801     }
2802     int total_args_passed_cc = sig_extended.length() - 2 * values;
2803     BasicType* sig_bt_cc = NEW_RESOURCE_ARRAY(BasicType, total_args_passed_cc);
2804 
2805     int j = 0;
2806     for (int i = 0; i < sig_extended.length(); i++) {
2807       if (!ValueTypePassFieldsAsArgs) {
2808         sig_bt_cc[j++] = sig_extended.at(i)._bt;
2809       } else if (sig_extended.at(i)._bt != T_VALUETYPE &&
2810                  (sig_extended.at(i)._bt != T_VOID ||
2811                   sig_extended.at(i-1)._bt == T_LONG ||
2812                   sig_extended.at(i-1)._bt == T_DOUBLE)) {
2813         sig_bt_cc[j++] = sig_extended.at(i)._bt;
2814       }
2815     }
2816     assert(j == total_args_passed_cc, "bad number of arguments");
2817 
2818     int total_args_passed_fp = sig_extended.length();
2819     BasicType* sig_bt_fp = NEW_RESOURCE_ARRAY(BasicType, total_args_passed_fp);
2820     for (int i = 0; i < sig_extended.length(); i++) {
2821       sig_bt_fp[i] = sig_extended.at(i)._bt;
2822     }
2823 
2824     VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed_cc);
2825 
2826     // Lookup method signature's fingerprint
2827     entry = _adapters->lookup(total_args_passed_fp, sig_bt_fp);
2828 
2829 #ifdef ASSERT
2830     AdapterHandlerEntry* shared_entry = NULL;
2831     // Start adapter sharing verification only after the VM is booted.
2832     if (VerifyAdapterSharing && (entry != NULL)) {
2833       shared_entry = entry;
2834       entry = NULL;
2835     }
2836 #endif


3392 JRT_LEAF(void, SharedRuntime::apply_post_barriers(JavaThread* thread, objArrayOopDesc* array))
3393 {
3394   assert(ValueTypePassFieldsAsArgs, "no reason to call this");
3395   assert(array->is_oop(), "should be oop");
3396   for (int i = 0; i < array->length(); ++i) {
3397     instanceOop valueOop = (instanceOop)array->obj_at(i);
3398     ValueKlass* vk = ValueKlass::cast(valueOop->klass());
3399     if (vk->contains_oops()) {
3400       const address dst_oop_addr = ((address) (void*) valueOop);
3401       OopMapBlock* map = vk->start_of_nonstatic_oop_maps();
3402       OopMapBlock* const end = map + vk->nonstatic_oop_map_count();
3403       while (map != end) {
3404         address doop_address = dst_oop_addr + map->offset();
3405         oopDesc::bs()->write_ref_array((HeapWord*) doop_address, map->count());
3406         map++;
3407       }
3408     }
3409   }
3410 }
3411 JRT_END









































































































































































2627 
2628   // Create a special handler for abstract methods.  Abstract methods
2629   // are never compiled so an i2c entry is somewhat meaningless, but
2630   // throw AbstractMethodError just in case.
2631   // Pass wrong_method_abstract for the c2i transitions to return
2632   // AbstractMethodError for invalid invocations.
2633   address wrong_method_abstract = SharedRuntime::get_handle_wrong_method_abstract_stub();
2634   _abstract_method_handler = AdapterHandlerLibrary::new_entry(new AdapterFingerPrint(0, NULL),
2635                                                               StubRoutines::throw_AbstractMethodError_entry(),
2636                                                               wrong_method_abstract, wrong_method_abstract);
2637 }
2638 
2639 AdapterHandlerEntry* AdapterHandlerLibrary::new_entry(AdapterFingerPrint* fingerprint,
2640                                                       address i2c_entry,
2641                                                       address c2i_entry,
2642                                                       address c2i_unverified_entry,
2643                                                       Symbol* sig_extended) {
2644   return _adapters->new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry, sig_extended);
2645 }
2646 























































2647 AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(const methodHandle& method) {
2648   AdapterHandlerEntry* entry = get_adapter0(method);
2649   if (method->is_shared()) {
2650     // See comments around Method::link_method()
2651     MutexLocker mu(AdapterHandlerLibrary_lock);
2652     if (method->adapter() == NULL) {
2653       method->update_adapter_trampoline(entry);
2654     }
2655     address trampoline = method->from_compiled_entry();
2656     if (*(int*)trampoline == 0) {
2657       CodeBuffer buffer(trampoline, (int)SharedRuntime::trampoline_size());
2658       MacroAssembler _masm(&buffer);
2659       SharedRuntime::generate_trampoline(&_masm, entry->get_c2i_entry());
2660       assert(*(int*)trampoline != 0, "Instruction(s) for trampoline must not be encoded as zeros.");
2661 
2662       if (PrintInterpreter) {
2663         Disassembler::decode(buffer.insts_begin(), buffer.insts_end());
2664       }
2665     }
2666   }


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             sig_extended.push(SigEntry(T_OBJECT));
2729           } else {
2730             const GrowableArray<SigEntry>& sig_vk = vk->collect_fields();
2731             sig_extended.appendAll(&sig_vk);
2732           }
2733         } else {
2734           sig_extended.push(SigEntry(ss.type()));
2735           if (ss.type() == T_LONG || ss.type() == T_DOUBLE) {
2736             sig_extended.push(SigEntry(T_VOID));
2737           }
2738         }
2739       }
2740     }
2741 
2742     int total_args_passed_cc = ValueTypePassFieldsAsArgs ? SigEntry::count_fields(sig_extended) : sig_extended.length();








2743     BasicType* sig_bt_cc = NEW_RESOURCE_ARRAY(BasicType, total_args_passed_cc);
2744     SigEntry::fill_sig_bt(sig_extended, sig_bt_cc, total_args_passed_cc, ValueTypePassFieldsAsArgs);












2745 
2746     int total_args_passed_fp = sig_extended.length();
2747     BasicType* sig_bt_fp = NEW_RESOURCE_ARRAY(BasicType, total_args_passed_fp);
2748     for (int i = 0; i < sig_extended.length(); i++) {
2749       sig_bt_fp[i] = sig_extended.at(i)._bt;
2750     }
2751 
2752     VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed_cc);
2753 
2754     // Lookup method signature's fingerprint
2755     entry = _adapters->lookup(total_args_passed_fp, sig_bt_fp);
2756 
2757 #ifdef ASSERT
2758     AdapterHandlerEntry* shared_entry = NULL;
2759     // Start adapter sharing verification only after the VM is booted.
2760     if (VerifyAdapterSharing && (entry != NULL)) {
2761       shared_entry = entry;
2762       entry = NULL;
2763     }
2764 #endif


3320 JRT_LEAF(void, SharedRuntime::apply_post_barriers(JavaThread* thread, objArrayOopDesc* array))
3321 {
3322   assert(ValueTypePassFieldsAsArgs, "no reason to call this");
3323   assert(array->is_oop(), "should be oop");
3324   for (int i = 0; i < array->length(); ++i) {
3325     instanceOop valueOop = (instanceOop)array->obj_at(i);
3326     ValueKlass* vk = ValueKlass::cast(valueOop->klass());
3327     if (vk->contains_oops()) {
3328       const address dst_oop_addr = ((address) (void*) valueOop);
3329       OopMapBlock* map = vk->start_of_nonstatic_oop_maps();
3330       OopMapBlock* const end = map + vk->nonstatic_oop_map_count();
3331       while (map != end) {
3332         address doop_address = dst_oop_addr + map->offset();
3333         oopDesc::bs()->write_ref_array((HeapWord*) doop_address, map->count());
3334         map++;
3335       }
3336     }
3337   }
3338 }
3339 JRT_END
3340 
3341 // We're returning from an interpreted method: load each field into a
3342 // register following the calling convention
3343 JRT_LEAF(void, SharedRuntime::load_value_type_fields_in_regs(JavaThread* thread, oopDesc* res))
3344 {
3345   assert(res->klass()->is_value(), "only value types here");
3346   ResourceMark rm;
3347   RegisterMap reg_map(thread);
3348   frame stubFrame = thread->last_frame();
3349   frame callerFrame = stubFrame.sender(&reg_map);
3350   assert(callerFrame.is_interpreted_frame(), "should be coming from interpreter");
3351 
3352   ValueKlass* vk = ValueKlass::cast(res->klass());
3353 
3354   VMRegPair* regs;
3355   int nb_fields;
3356   const GrowableArray<SigEntry>& sig_vk = vk->return_convention(regs, nb_fields);
3357 
3358   if (regs == NULL) {
3359     // The fields of the value klass don't fit in registers, bail out
3360     return;
3361   }
3362 
3363   int j = 1;
3364   for (int i = 0; i < sig_vk.length(); i++) {
3365     BasicType bt = sig_vk.at(i)._bt;
3366     if (bt == T_VALUETYPE) {
3367       continue;
3368     } 
3369     if (bt == T_VOID) {
3370       if (sig_vk.at(i-1)._bt == T_LONG ||
3371           sig_vk.at(i-1)._bt == T_DOUBLE) {
3372         j++;
3373       }
3374       continue;
3375     }
3376     int off = sig_vk.at(i)._offset;
3377     VMRegPair pair = regs[j];
3378     address loc = reg_map.location(pair.first());
3379     switch(bt) {
3380     case T_BOOLEAN:
3381       *(intptr_t*)loc = *(jboolean*)((address)res + off);
3382       break;
3383     case T_CHAR:
3384       *(intptr_t*)loc = *(jchar*)((address)res + off);
3385       break;
3386     case T_BYTE:
3387       *(intptr_t*)loc = *(jbyte*)((address)res + off);
3388       break;
3389     case T_SHORT:
3390       *(intptr_t*)loc = *(jshort*)((address)res + off);
3391       break;
3392     case T_INT: {
3393       jint v = *(jint*)((address)res + off);
3394       *(intptr_t*)loc = v;
3395       break;
3396     }
3397     case T_LONG:
3398 #ifdef _LP64
3399       *(intptr_t*)loc = *(jlong*)((address)res + off);
3400 #else
3401       Unimplemented();
3402 #endif
3403       break;
3404     case T_OBJECT:
3405     case T_ARRAY: {
3406       oop v = NULL;
3407       if (!UseCompressedOops) {
3408         oop* p = (oop*)((address)res + off);
3409         v = oopDesc::load_heap_oop(p);
3410       } else {
3411         narrowOop* p = (narrowOop*)((address)res + off);
3412         v = oopDesc::load_decode_heap_oop(p);
3413       }
3414       *(oop*)loc = v;
3415       break;
3416     }
3417     case T_FLOAT:
3418       *(jfloat*)loc = *(jfloat*)((address)res + off);
3419       break;
3420     case T_DOUBLE:
3421       *(jdouble*)loc = *(jdouble*)((address)res + off);
3422       break;
3423     default:
3424       ShouldNotReachHere();
3425     }
3426     j++;
3427   }
3428   assert(j == nb_fields, "missed a field?");
3429 
3430 #ifdef ASSERT  
3431   VMRegPair pair = regs[0];
3432   address loc = reg_map.location(pair.first());
3433   assert(*(oopDesc**)loc == res, "overwritten object");
3434 #endif
3435 
3436   thread->set_vm_result(res);
3437 }
3438 JRT_END
3439 
3440 // We've returned to an interpreted method, the interpreter needs a
3441 // reference to a value type instance. Allocate it and initialize it
3442 // from field's values in registers.
3443 JRT_BLOCK_ENTRY(void, SharedRuntime::store_value_type_fields_to_buf(JavaThread* thread, intptr_t res))
3444 {
3445   ResourceMark rm;
3446   RegisterMap reg_map(thread);
3447   frame stubFrame = thread->last_frame();
3448   frame callerFrame = stubFrame.sender(&reg_map);
3449 
3450 #ifdef ASSERT
3451   ValueKlass* verif_vk = ValueKlass::returned_value_type(reg_map);
3452   javaVFrame* vf = javaVFrame::cast(vframe::new_vframe(&callerFrame, &reg_map, thread));
3453   Method* m = vf->method();
3454   int bci = vf->bci();
3455   Bytecode_invoke inv(m, bci);
3456 
3457   {
3458     NoSafepointVerifier nsv;
3459     methodHandle callee = inv.static_target(thread);
3460     assert(!thread->has_pending_exception(), "call resolution should work");
3461     ValueKlass* verif_vk2 = callee->returned_value_type(thread);
3462     assert(verif_vk == NULL || verif_vk == verif_vk2 ||
3463            verif_vk2 == SystemDictionary::___Value_klass(), "Bad value klass");
3464     
3465   }
3466 #endif
3467 
3468   if (Universe::heap()->is_in_reserved((void*)res)) {
3469     // We're not returning with value type fields in registers (the
3470     // calling convention didn't allow it for this value klass)
3471     thread->set_vm_result((oopDesc*)res);
3472     assert(verif_vk == NULL, "broken calling convention");
3473     return;
3474   }
3475 
3476   ValueKlass* vk = (ValueKlass*)res;
3477   assert(verif_vk == vk, "broken calling convention");
3478 
3479   VMRegPair* regs;
3480   int nb_fields;
3481   const GrowableArray<SigEntry>& sig_vk = vk->return_convention(regs, nb_fields);
3482   assert(regs != NULL, "return convention should allow return as fields");
3483 
3484   regs++;
3485   nb_fields--;
3486 
3487   // Allocate handles for every oop fields so they are safe in case of
3488   // a safepoint when allocating
3489   GrowableArray<Handle> handles;
3490   vk->save_oop_fields(sig_vk, reg_map, regs, handles, nb_fields);
3491 
3492   // It's unsafe to safepoint until we are here
3493 
3494   Handle new_vt;
3495   JRT_BLOCK;
3496   {
3497     Thread* THREAD = thread;
3498     oop vt = vk->realloc_result(sig_vk, reg_map, regs, handles, nb_fields, CHECK);
3499     new_vt = Handle(thread, vt);
3500   }
3501   JRT_BLOCK_END;
3502 
3503   thread->set_vm_result(new_vt());
3504 }
3505 JRT_END
3506 
< prev index next >