< prev index next >

src/share/vm/oops/valueKlass.cpp

Print this page

        

@@ -24,10 +24,11 @@
 
 #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,130 +341,133 @@
   }
   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");
+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();
-  nb_fields = SigEntry::count_fields(sig_vk)+1;
+  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);
-  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<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]);
+    }
   }
-  
-  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);
+    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 GrowableArray<SigEntry>& sig_vk, RegisterMap& reg_map, const VMRegPair* regs, GrowableArray<Handle>& handles, int nb_fields) const {
-  int j = 0;
+void ValueKlass::save_oop_fields(const RegisterMap& reg_map, GrowableArray<Handle>& handles) const {
   Thread* thread = Thread::current();
-  for (int i = 0; i < sig_vk.length(); i++) {
-    BasicType bt = sig_vk.at(i)._bt;
+  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[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?");
       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) {
+        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<Handle>& handles) const {
   assert(ValueTypeReturnedAsFields, "inconsistent");
-  int nb_fields;
-  VMRegPair* regs;
-  const GrowableArray<SigEntry>& sig_vk = return_convention(regs, nb_fields);
+  const Array<SigEntry>* sig_vk = extended_sig();
+  const Array<VMRegPair>* 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++)();
     }
     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) {
+        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<SigEntry>& sig_vk, const RegisterMap& reg_map, const VMRegPair* regs,
-                               const GrowableArray<Handle>& handles, int nb_fields, TRAPS) {
+oop ValueKlass::realloc_result(const RegisterMap& reg_map, const GrowableArray<Handle>& handles, TRAPS) {
   oop new_vt = allocate_instance(CHECK_NULL);
 
-  int j = 0;
+  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;
+  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: {
       jboolean v = *(intptr_t*)loc;
       *(jboolean*)((address)new_vt + off) = v;

@@ -524,11 +528,11 @@
     default:
       ShouldNotReachHere();
     }
     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;
 }
 
 ValueKlass* ValueKlass::returned_value_type(const RegisterMap& map) {

@@ -537,15 +541,13 @@
   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)) {
+  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;
 }
 
< prev index next >