--- old/src/share/vm/oops/valueKlass.cpp 2017-07-04 18:39:47.461151044 +0200 +++ new/src/share/vm/oops/valueKlass.cpp 2017-07-04 18:39:47.386151390 +0200 @@ -26,6 +26,7 @@ #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" @@ -342,37 +343,39 @@ return sig_extended; } -// Returns the basic types and registers for fields to return an -// instance of this value type in registers if possible. -GrowableArray ValueKlass::return_convention(VMRegPair*& regs, int& nb_fields) const { - assert(ValueTypeReturnedAsFields, "inconsistent"); +void ValueKlass::initialize_calling_convention() { + Thread* THREAD = Thread::current(); + assert(!HAS_PENDING_EXCEPTION, "should have no exception"); + ResourceMark rm; const GrowableArray& sig_vk = collect_fields(); - nb_fields = SigEntry::count_fields(sig_vk)+1; + int nb_fields = SigEntry::count_fields(sig_vk)+1; + Array* extended_sig = MetadataFactory::new_array(class_loader_data(), sig_vk.length(), CHECK_AND_CLEAR); + *((Array**)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); - regs = NEW_RESOURCE_ARRAY(VMRegPair, nb_fields); + VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair, nb_fields); int total = SharedRuntime::java_return_convention(sig_bt, regs, nb_fields); - if (total <= 0) { - regs = NULL; + if (total > 0) { + Array* return_regs = MetadataFactory::new_array(class_loader_data(), nb_fields, CHECK_AND_CLEAR); + *((Array**)adr_return_regs()) = return_regs; + for (int i = 0; i < nb_fields; i++ ) { + return_regs->at_put(i, regs[i]); + } } - - 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& handles) const { if (ValueTypeReturnedAsFields) { - int nb_fields; - VMRegPair* regs; - const GrowableArray& sig_vk = return_convention(regs, nb_fields); - - if (regs != NULL) { - regs++; - nb_fields--; - save_oop_fields(sig_vk, reg_map, regs, handles, nb_fields); + if (return_regs() != NULL) { + save_oop_fields(reg_map, handles); return true; } } @@ -380,14 +383,17 @@ } // Same as above but with pre-computed return convention -void ValueKlass::save_oop_fields(const GrowableArray& sig_vk, RegisterMap& reg_map, const VMRegPair* regs, GrowableArray& handles, int nb_fields) const { - int j = 0; +void ValueKlass::save_oop_fields(const RegisterMap& reg_map, GrowableArray& handles) const { Thread* thread = Thread::current(); - for (int i = 0; i < sig_vk.length(); i++) { - BasicType bt = sig_vk.at(i)._bt; + const Array* sig_vk = extended_sig(); + const Array* 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[j]; + 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?"); @@ -398,32 +404,28 @@ continue; } if (bt == T_VOID && - sig_vk.at(i-1)._bt != T_LONG && - sig_vk.at(i-1)._bt != T_DOUBLE) { + 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?"); + 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& handles) const { assert(ValueTypeReturnedAsFields, "inconsistent"); - int nb_fields; - VMRegPair* regs; - const GrowableArray& sig_vk = return_convention(regs, nb_fields); + const Array* sig_vk = extended_sig(); + const Array* regs = return_regs(); 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; + 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[j]; + int off = sig_vk->at(i)._offset; + VMRegPair pair = regs->at(j); address loc = reg_map.location(pair.first()); *(oop*)loc = handles.at(k++)(); } @@ -431,37 +433,39 @@ continue; } if (bt == T_VOID && - sig_vk.at(i-1)._bt != T_LONG && - sig_vk.at(i-1)._bt != T_DOUBLE) { + 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?"); + 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 GrowableArray& sig_vk, const RegisterMap& reg_map, const VMRegPair* regs, - const GrowableArray& handles, int nb_fields, TRAPS) { +oop ValueKlass::realloc_result(const RegisterMap& reg_map, const GrowableArray& handles, TRAPS) { oop new_vt = allocate_instance(CHECK_NULL); - int j = 0; + const Array* sig_vk = extended_sig(); + const Array* 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; + 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) { + 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]; + int off = sig_vk->at(i)._offset; + VMRegPair pair = regs->at(j); address loc = reg_map.location(pair.first()); switch(bt) { case T_BOOLEAN: { @@ -526,7 +530,7 @@ } j++; } - assert(j == nb_fields, "missed a field?"); + assert(j == regs->length(), "missed a field?"); assert(k == handles.length(), "missed an oop?"); return new_vt; } @@ -539,13 +543,11 @@ address loc = map.location(pair.first()); intptr_t ptr = *(intptr_t*)loc; - if (Metaspace::contains((void*)ptr)) { + if ((ptr & 1) != 0) { + ptr = ptr & ~1L; + assert(Metaspace::contains((void*)ptr), "should be klass"); return (ValueKlass*)ptr; } return NULL; -// if (Universe::heap()->is_in_reserved((void*)ptr)) { -// return NULL; -// } -// return (ValueKlass*)ptr; }