< prev index next >

src/share/vm/oops/valueKlass.cpp

Print this page

        

*** 24,33 **** --- 24,34 ---- #include "precompiled.hpp" #include "gc/shared/gcLocker.inline.hpp" #include "interpreter/interpreter.hpp" #include "logging/log.hpp" + #include "memory/metadataFactory.hpp" #include "oops/oop.inline.hpp" #include "oops/fieldStreams.hpp" #include "oops/method.hpp" #include "oops/objArrayKlass.hpp" #include "oops/valueKlass.hpp"
*** 340,469 **** } assert(sig_extended.at(0)._bt == T_VALUETYPE && sig_extended.at(sig_extended.length()-1)._bt == T_VOID, "broken structure"); return sig_extended; } ! // Returns the basic types and registers for fields to return an ! // instance of this value type in registers if possible. ! GrowableArray<SigEntry> ValueKlass::return_convention(VMRegPair*& regs, int& nb_fields) const { ! assert(ValueTypeReturnedAsFields, "inconsistent"); const GrowableArray<SigEntry>& sig_vk = collect_fields(); ! nb_fields = SigEntry::count_fields(sig_vk)+1; BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, nb_fields); sig_bt[0] = T_METADATA; SigEntry::fill_sig_bt(sig_vk, sig_bt+1, nb_fields-1, true); ! regs = NEW_RESOURCE_ARRAY(VMRegPair, nb_fields); int total = SharedRuntime::java_return_convention(sig_bt, regs, nb_fields); ! if (total <= 0) { ! regs = NULL; } - - return sig_vk; } // Create handles for all oop fields returned in registers that are // going to be live across a safepoint. bool ValueKlass::save_oop_results(RegisterMap& reg_map, GrowableArray<Handle>& handles) const { if (ValueTypeReturnedAsFields) { ! int nb_fields; ! VMRegPair* regs; ! const GrowableArray<SigEntry>& sig_vk = return_convention(regs, nb_fields); ! ! if (regs != NULL) { ! regs++; ! nb_fields--; ! save_oop_fields(sig_vk, reg_map, regs, handles, nb_fields); return true; } } return false; } // Same as above but with pre-computed return convention ! void ValueKlass::save_oop_fields(const GrowableArray<SigEntry>& sig_vk, RegisterMap& reg_map, const VMRegPair* regs, GrowableArray<Handle>& handles, int nb_fields) const { ! int j = 0; Thread* thread = Thread::current(); ! for (int i = 0; i < sig_vk.length(); i++) { ! BasicType bt = sig_vk.at(i)._bt; if (bt == T_OBJECT || bt == T_ARRAY) { ! int off = sig_vk.at(i)._offset; ! VMRegPair pair = regs[j]; address loc = reg_map.location(pair.first()); oop v = *(oop*)loc; assert(v == NULL || v->is_oop(), "not an oop?"); assert(Universe::heap()->is_in_or_null(v), "must be heap pointer"); handles.push(Handle(thread, v)); } if (bt == T_VALUETYPE) { continue; } if (bt == T_VOID && ! sig_vk.at(i-1)._bt != T_LONG && ! sig_vk.at(i-1)._bt != T_DOUBLE) { continue; } j++; } ! assert(j == nb_fields, "missed a field?"); } // Update oop fields in registers from handles after a safepoint void ValueKlass::restore_oop_results(RegisterMap& reg_map, GrowableArray<Handle>& handles) const { assert(ValueTypeReturnedAsFields, "inconsistent"); ! int nb_fields; ! VMRegPair* regs; ! const GrowableArray<SigEntry>& sig_vk = return_convention(regs, nb_fields); assert(regs != NULL, "inconsistent"); ! regs++; ! nb_fields--; ! ! int j = 0; ! for (int i = 0, k = 0; i < sig_vk.length(); i++) { ! BasicType bt = sig_vk.at(i)._bt; if (bt == T_OBJECT || bt == T_ARRAY) { ! int off = sig_vk.at(i)._offset; ! VMRegPair pair = regs[j]; address loc = reg_map.location(pair.first()); *(oop*)loc = handles.at(k++)(); } if (bt == T_VALUETYPE) { continue; } if (bt == T_VOID && ! sig_vk.at(i-1)._bt != T_LONG && ! sig_vk.at(i-1)._bt != T_DOUBLE) { continue; } j++; } ! assert(j == nb_fields, "missed a field?"); } // Fields are in registers. Create an instance of the value type and // initialize it with the values of the fields. ! oop ValueKlass::realloc_result(const GrowableArray<SigEntry>& sig_vk, const RegisterMap& reg_map, const VMRegPair* regs, ! const GrowableArray<Handle>& handles, int nb_fields, TRAPS) { oop new_vt = allocate_instance(CHECK_NULL); ! int j = 0; int k = 0; ! 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: { jboolean v = *(intptr_t*)loc; *(jboolean*)((address)new_vt + off) = v; --- 341,473 ---- } assert(sig_extended.at(0)._bt == T_VALUETYPE && sig_extended.at(sig_extended.length()-1)._bt == T_VOID, "broken structure"); return sig_extended; } ! void ValueKlass::initialize_calling_convention() { ! Thread* THREAD = Thread::current(); ! assert(!HAS_PENDING_EXCEPTION, "should have no exception"); ! ResourceMark rm; const GrowableArray<SigEntry>& sig_vk = collect_fields(); ! int nb_fields = SigEntry::count_fields(sig_vk)+1; ! Array<SigEntry>* extended_sig = MetadataFactory::new_array<SigEntry>(class_loader_data(), sig_vk.length(), CHECK_AND_CLEAR); ! *((Array<SigEntry>**)adr_extended_sig()) = extended_sig; ! for (int i = 0; i < sig_vk.length(); i++ ) { ! extended_sig->at_put(i, sig_vk.at(i)); ! } ! BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, nb_fields); sig_bt[0] = T_METADATA; SigEntry::fill_sig_bt(sig_vk, sig_bt+1, nb_fields-1, true); ! VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair, nb_fields); int total = SharedRuntime::java_return_convention(sig_bt, regs, nb_fields); ! if (total > 0) { ! Array<VMRegPair>* return_regs = MetadataFactory::new_array<VMRegPair>(class_loader_data(), nb_fields, CHECK_AND_CLEAR); ! *((Array<VMRegPair>**)adr_return_regs()) = return_regs; ! for (int i = 0; i < nb_fields; i++ ) { ! return_regs->at_put(i, regs[i]); ! } } } // Create handles for all oop fields returned in registers that are // going to be live across a safepoint. bool ValueKlass::save_oop_results(RegisterMap& reg_map, GrowableArray<Handle>& handles) const { if (ValueTypeReturnedAsFields) { ! if (return_regs() != NULL) { ! save_oop_fields(reg_map, handles); return true; } } return false; } // Same as above but with pre-computed return convention ! void ValueKlass::save_oop_fields(const RegisterMap& reg_map, GrowableArray<Handle>& handles) const { Thread* thread = Thread::current(); ! const Array<SigEntry>* sig_vk = extended_sig(); ! const Array<VMRegPair>* regs = return_regs(); ! int j = 1; ! ! for (int i = 0; i < sig_vk->length(); i++) { ! BasicType bt = sig_vk->at(i)._bt; if (bt == T_OBJECT || bt == T_ARRAY) { ! int off = sig_vk->at(i)._offset; ! VMRegPair pair = regs->at(j); address loc = reg_map.location(pair.first()); oop v = *(oop*)loc; assert(v == NULL || v->is_oop(), "not an oop?"); assert(Universe::heap()->is_in_or_null(v), "must be heap pointer"); handles.push(Handle(thread, v)); } if (bt == T_VALUETYPE) { continue; } if (bt == T_VOID && ! sig_vk->at(i-1)._bt != T_LONG && ! sig_vk->at(i-1)._bt != T_DOUBLE) { continue; } j++; } ! assert(j == regs->length(), "missed a field?"); } // Update oop fields in registers from handles after a safepoint void ValueKlass::restore_oop_results(RegisterMap& reg_map, GrowableArray<Handle>& handles) const { assert(ValueTypeReturnedAsFields, "inconsistent"); ! const Array<SigEntry>* sig_vk = extended_sig(); ! const Array<VMRegPair>* regs = return_regs(); assert(regs != NULL, "inconsistent"); ! int j = 1; ! for (int i = 0, k = 0; i < sig_vk->length(); i++) { ! BasicType bt = sig_vk->at(i)._bt; if (bt == T_OBJECT || bt == T_ARRAY) { ! int off = sig_vk->at(i)._offset; ! VMRegPair pair = regs->at(j); address loc = reg_map.location(pair.first()); *(oop*)loc = handles.at(k++)(); } if (bt == T_VALUETYPE) { continue; } if (bt == T_VOID && ! sig_vk->at(i-1)._bt != T_LONG && ! sig_vk->at(i-1)._bt != T_DOUBLE) { continue; } j++; } ! assert(j == regs->length(), ""); } // Fields are in registers. Create an instance of the value type and // initialize it with the values of the fields. ! oop ValueKlass::realloc_result(const RegisterMap& reg_map, const GrowableArray<Handle>& handles, TRAPS) { oop new_vt = allocate_instance(CHECK_NULL); ! const Array<SigEntry>* sig_vk = extended_sig(); ! const Array<VMRegPair>* regs = return_regs(); ! ! int j = 1; int k = 0; ! 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: { jboolean v = *(intptr_t*)loc; *(jboolean*)((address)new_vt + off) = v;
*** 524,534 **** default: ShouldNotReachHere(); } j++; } ! assert(j == nb_fields, "missed a field?"); assert(k == handles.length(), "missed an oop?"); return new_vt; } ValueKlass* ValueKlass::returned_value_type(const RegisterMap& map) { --- 528,538 ---- default: ShouldNotReachHere(); } j++; } ! assert(j == regs->length(), "missed a field?"); assert(k == handles.length(), "missed an oop?"); return new_vt; } ValueKlass* ValueKlass::returned_value_type(const RegisterMap& map) {
*** 537,551 **** int nb = SharedRuntime::java_return_convention(&bt, &pair, 1); assert(nb == 1, "broken"); address loc = map.location(pair.first()); intptr_t ptr = *(intptr_t*)loc; ! if (Metaspace::contains((void*)ptr)) { return (ValueKlass*)ptr; } return NULL; - // if (Universe::heap()->is_in_reserved((void*)ptr)) { - // return NULL; - // } - // return (ValueKlass*)ptr; } --- 541,553 ---- int nb = SharedRuntime::java_return_convention(&bt, &pair, 1); assert(nb == 1, "broken"); address loc = map.location(pair.first()); intptr_t ptr = *(intptr_t*)loc; ! if ((ptr & 1) != 0) { ! ptr = ptr & ~1L; ! assert(Metaspace::contains((void*)ptr), "should be klass"); return (ValueKlass*)ptr; } return NULL; }
< prev index next >