diff src/share/vm/runtime/sharedRuntime.cpp @ 1930:2d26b0046e0d

Merge.
author Thomas Wuerthinger <wuerthinger@ssw.jku.at>
date Tue, 30 Nov 2010 14:53:30 +0100
parents f8ab19e5acae 3dc12ef8735e
children 8d88c9ac9247
line wrap: on
line diff
--- a/src/share/vm/runtime/sharedRuntime.cpp	Mon Nov 29 18:32:30 2010 +0100
+++ b/src/share/vm/runtime/sharedRuntime.cpp	Tue Nov 30 14:53:30 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright 1997-2010 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -16,9 +16,9 @@
  * 2 along with this work; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
  *
  */
 
@@ -191,6 +191,124 @@
   return ((jdouble)fmod((double)x,(double)y));
 JRT_END
 
+#ifdef __SOFTFP__
+JRT_LEAF(jfloat, SharedRuntime::fadd(jfloat x, jfloat y))
+  return x + y;
+JRT_END
+
+JRT_LEAF(jfloat, SharedRuntime::fsub(jfloat x, jfloat y))
+  return x - y;
+JRT_END
+
+JRT_LEAF(jfloat, SharedRuntime::fmul(jfloat x, jfloat y))
+  return x * y;
+JRT_END
+
+JRT_LEAF(jfloat, SharedRuntime::fdiv(jfloat x, jfloat y))
+  return x / y;
+JRT_END
+
+JRT_LEAF(jdouble, SharedRuntime::dadd(jdouble x, jdouble y))
+  return x + y;
+JRT_END
+
+JRT_LEAF(jdouble, SharedRuntime::dsub(jdouble x, jdouble y))
+  return x - y;
+JRT_END
+
+JRT_LEAF(jdouble, SharedRuntime::dmul(jdouble x, jdouble y))
+  return x * y;
+JRT_END
+
+JRT_LEAF(jdouble, SharedRuntime::ddiv(jdouble x, jdouble y))
+  return x / y;
+JRT_END
+
+JRT_LEAF(jfloat, SharedRuntime::i2f(jint x))
+  return (jfloat)x;
+JRT_END
+
+JRT_LEAF(jdouble, SharedRuntime::i2d(jint x))
+  return (jdouble)x;
+JRT_END
+
+JRT_LEAF(jdouble, SharedRuntime::f2d(jfloat x))
+  return (jdouble)x;
+JRT_END
+
+JRT_LEAF(int,  SharedRuntime::fcmpl(float x, float y))
+  return x>y ? 1 : (x==y ? 0 : -1);  /* x<y or is_nan*/
+JRT_END
+
+JRT_LEAF(int,  SharedRuntime::fcmpg(float x, float y))
+  return x<y ? -1 : (x==y ? 0 : 1);  /* x>y or is_nan */
+JRT_END
+
+JRT_LEAF(int,  SharedRuntime::dcmpl(double x, double y))
+  return x>y ? 1 : (x==y ? 0 : -1); /* x<y or is_nan */
+JRT_END
+
+JRT_LEAF(int,  SharedRuntime::dcmpg(double x, double y))
+  return x<y ? -1 : (x==y ? 0 : 1);  /* x>y or is_nan */
+JRT_END
+
+// Functions to return the opposite of the aeabi functions for nan.
+JRT_LEAF(int, SharedRuntime::unordered_fcmplt(float x, float y))
+  return (x < y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0);
+JRT_END
+
+JRT_LEAF(int, SharedRuntime::unordered_dcmplt(double x, double y))
+  return (x < y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0);
+JRT_END
+
+JRT_LEAF(int, SharedRuntime::unordered_fcmple(float x, float y))
+  return (x <= y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0);
+JRT_END
+
+JRT_LEAF(int, SharedRuntime::unordered_dcmple(double x, double y))
+  return (x <= y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0);
+JRT_END
+
+JRT_LEAF(int, SharedRuntime::unordered_fcmpge(float x, float y))
+  return (x >= y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0);
+JRT_END
+
+JRT_LEAF(int, SharedRuntime::unordered_dcmpge(double x, double y))
+  return (x >= y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0);
+JRT_END
+
+JRT_LEAF(int, SharedRuntime::unordered_fcmpgt(float x, float y))
+  return (x > y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0);
+JRT_END
+
+JRT_LEAF(int, SharedRuntime::unordered_dcmpgt(double x, double y))
+  return (x > y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0);
+JRT_END
+
+// Intrinsics make gcc generate code for these.
+float  SharedRuntime::fneg(float f)   {
+  return -f;
+}
+
+double SharedRuntime::dneg(double f)  {
+  return -f;
+}
+
+#endif // __SOFTFP__
+
+#if defined(__SOFTFP__) || defined(E500V2)
+// Intrinsics make gcc generate code for these.
+double SharedRuntime::dabs(double f)  {
+  return (f <= (double)0.0) ? (double)0.0 - f : f;
+}
+
+#endif
+
+#if defined(__SOFTFP__) || defined(PPC)
+double SharedRuntime::dsqrt(double f) {
+  return sqrt(f);
+}
+#endif
 
 JRT_LEAF(jint, SharedRuntime::f2i(jfloat  x))
   if (g_isnan(x))
@@ -340,11 +458,11 @@
   if (at_poll_return) {
     assert(SharedRuntime::polling_page_return_handler_blob() != NULL,
            "polling page return stub not created yet");
-    stub = SharedRuntime::polling_page_return_handler_blob()->instructions_begin();
+    stub = SharedRuntime::polling_page_return_handler_blob()->entry_point();
   } else {
     assert(SharedRuntime::polling_page_safepoint_handler_blob() != NULL,
            "polling page safepoint stub not created yet");
-    stub = SharedRuntime::polling_page_safepoint_handler_blob()->instructions_begin();
+    stub = SharedRuntime::polling_page_safepoint_handler_blob()->entry_point();
   }
 #ifndef PRODUCT
   if( TraceSafepoint ) {
@@ -459,7 +577,7 @@
   }
 
   // found handling method => lookup exception handler
-  int catch_pco = ret_pc - nm->instructions_begin();
+  int catch_pco = ret_pc - nm->code_begin();
 
   ExceptionHandlerTable table(nm);
   HandlerTableEntry *t = table.entry_for(catch_pco, handler_bci, scope_depth);
@@ -492,7 +610,7 @@
     return NULL;
   }
 
-  return nm->instructions_begin() + t->pco();
+  return nm->code_begin() + t->pco();
 }
 
 JRT_ENTRY(void, SharedRuntime::throw_AbstractMethodError(JavaThread* thread))
@@ -787,7 +905,7 @@
 
   // Find bytecode
   Bytecode_invoke* bytecode = Bytecode_invoke_at(caller, bci);
-  bc = bytecode->adjusted_invoke_code();
+  bc = bytecode->java_code();
   int bytecode_index = bytecode->index();
 
   // Find receiver for non-static call
@@ -1443,7 +1561,7 @@
       // for the rest of its life! Just another racing bug in the life of
       // fixup_callers_callsite ...
       //
-      RelocIterator iter(cb, call->instruction_address(), call->next_instruction_address());
+      RelocIterator iter(nm, call->instruction_address(), call->next_instruction_address());
       iter.next();
       assert(iter.has_current(), "must have a reloc at java call site");
       relocInfo::relocType typ = iter.reloc()->type();
@@ -1526,8 +1644,13 @@
 char* SharedRuntime::generate_wrong_method_type_message(JavaThread* thread,
                                                         oopDesc* required,
                                                         oopDesc* actual) {
+  if (TraceMethodHandles) {
+    tty->print_cr("WrongMethodType thread="PTR_FORMAT" req="PTR_FORMAT" act="PTR_FORMAT"",
+                  thread, required, actual);
+  }
   assert(EnableMethodHandles, "");
   oop singleKlass = wrong_method_type_is_for_single_argument(thread, required);
+  char* message = NULL;
   if (singleKlass != NULL) {
     const char* objName = "argument or return value";
     if (actual != NULL) {
@@ -1540,7 +1663,7 @@
     Klass* targetKlass = Klass::cast(required->is_klass()
                                      ? (klassOop)required
                                      : java_lang_Class::as_klassOop(required));
-    return generate_class_cast_message(objName, targetKlass->external_name());
+    message = generate_class_cast_message(objName, targetKlass->external_name());
   } else {
     // %%% need to get the MethodType string, without messing around too much
     // Get a signature from the invoke instruction
@@ -1565,16 +1688,20 @@
     methodOop actual_method = MethodHandles::decode_method(actual,
                                                           kignore, fignore);
     if (actual_method != NULL) {
-      if (actual_method->name() == vmSymbols::invoke_name())
+      if (methodOopDesc::is_method_handle_invoke_name(actual_method->name()))
         mhName = "$";
       else
         mhName = actual_method->signature()->as_C_string();
       if (mhName[0] == '$')
         mhName = actual_method->signature()->as_C_string();
     }
-    return generate_class_cast_message(mhName, targetType,
-                                       " cannot be called as ");
+    message = generate_class_cast_message(mhName, targetType,
+                                          " cannot be called as ");
   }
+  if (TraceMethodHandles) {
+    tty->print_cr("WrongMethodType => message=%s", message);
+  }
+  return message;
 }
 
 oop SharedRuntime::wrong_method_type_is_for_single_argument(JavaThread* thr,
@@ -1850,14 +1977,11 @@
 
       case T_OBJECT:
       case T_ARRAY:
-        if (!TaggedStackInterpreter) {
 #ifdef _LP64
-          return T_LONG;
+        return T_LONG;
 #else
-          return T_INT;
+        return T_INT;
 #endif
-        }
-        return T_OBJECT;
 
       case T_INT:
       case T_LONG:
@@ -2057,6 +2181,8 @@
 int AdapterHandlerTable::_hits;
 int AdapterHandlerTable::_compact;
 
+#endif
+
 class AdapterHandlerTableIterator : public StackObj {
  private:
   AdapterHandlerTable* _table;
@@ -2066,11 +2192,11 @@
   void scan() {
     while (_index < _table->table_size()) {
       AdapterHandlerEntry* a = _table->bucket(_index);
+      _index++;
       if (a != NULL) {
         _current = a;
         return;
       }
-      _index++;
     }
   }
 
@@ -2092,7 +2218,6 @@
     }
   }
 };
-#endif
 
 
 // ---------------------------------------------------------------------------
@@ -2147,7 +2272,7 @@
 
   ResourceMark rm;
 
-  NOT_PRODUCT(int code_size);
+  NOT_PRODUCT(int insts_size);
   AdapterBlob* B = NULL;
   AdapterHandlerEntry* entry = NULL;
   AdapterFingerPrint* fingerprint = NULL;
@@ -2200,7 +2325,7 @@
 
     BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache
     if (buf != NULL) {
-      CodeBuffer buffer(buf->instructions_begin(), buf->instructions_size());
+      CodeBuffer buffer(buf);
       short buffer_locs[20];
       buffer.insts()->initialize_shared_locs((relocInfo*)buffer_locs,
                                              sizeof(buffer_locs)/sizeof(relocInfo));
@@ -2216,19 +2341,19 @@
 #ifdef ASSERT
       if (VerifyAdapterSharing) {
         if (shared_entry != NULL) {
-          assert(shared_entry->compare_code(buf->instructions_begin(), buffer.code_size(), total_args_passed, sig_bt),
+          assert(shared_entry->compare_code(buf->code_begin(), buffer.insts_size(), total_args_passed, sig_bt),
                  "code must match");
           // Release the one just created and return the original
           _adapters->free_entry(entry);
           return shared_entry;
         } else  {
-          entry->save_code(buf->instructions_begin(), buffer.code_size(), total_args_passed, sig_bt);
+          entry->save_code(buf->code_begin(), buffer.insts_size(), total_args_passed, sig_bt);
         }
       }
 #endif
 
       B = AdapterBlob::create(&buffer);
-      NOT_PRODUCT(code_size = buffer.code_size());
+      NOT_PRODUCT(insts_size = buffer.insts_size());
     }
     if (B == NULL) {
       // CodeCache is full, disable compilation
@@ -2238,16 +2363,16 @@
       CompileBroker::handle_full_code_cache();
       return NULL; // Out of CodeCache space
     }
-    entry->relocate(B->instructions_begin());
+    entry->relocate(B->content_begin());
 #ifndef PRODUCT
     // debugging suppport
     if (PrintAdapterHandlers) {
       tty->cr();
       tty->print_cr("i2c argument handler #%d for: %s %s (fingerprint = %s, %d bytes generated)",
                     _adapters->number_of_entries(), (method->is_static() ? "static" : "receiver"),
-                    method->signature()->as_C_string(), fingerprint->as_string(), code_size );
+                    method->signature()->as_C_string(), fingerprint->as_string(), insts_size );
       tty->print_cr("c2i argument handler starts at %p",entry->get_c2i_entry());
-      Disassembler::decode(entry->get_i2c_entry(), entry->get_i2c_entry() + code_size);
+      Disassembler::decode(entry->get_i2c_entry(), entry->get_i2c_entry() + insts_size);
     }
 #endif
 
@@ -2261,14 +2386,11 @@
                  "%s(%s)@" PTR_FORMAT,
                  B->name(),
                  fingerprint->as_string(),
-                 B->instructions_begin());
-    VTune::register_stub(blob_id, B->instructions_begin(), B->instructions_end());
-    Forte::register_stub(blob_id, B->instructions_begin(), B->instructions_end());
+                 B->content_begin());
+    Forte::register_stub(blob_id, B->content_begin(), B->content_end());
 
     if (JvmtiExport::should_post_dynamic_code_generated()) {
-      JvmtiExport::post_dynamic_code_generated(blob_id,
-                                               B->instructions_begin(),
-                                               B->instructions_end());
+      JvmtiExport::post_dynamic_code_generated(blob_id, B->content_begin(), B->content_end());
     }
   }
   return entry;
@@ -2352,7 +2474,7 @@
 
     BufferBlob*  buf = buffer_blob(); // the temporary code buffer in CodeCache
     if (buf != NULL) {
-      CodeBuffer buffer(buf->instructions_begin(), buf->instructions_size());
+      CodeBuffer buffer(buf);
       double locs_buf[20];
       buffer.insts()->initialize_shared_locs((relocInfo*)locs_buf, sizeof(locs_buf) / sizeof(relocInfo));
       MacroAssembler _masm(&buffer);
@@ -2389,15 +2511,13 @@
   }
 
   // Must unlock before calling set_code
+
   // Install the generated code.
   if (nm != NULL) {
     method->set_code(method, nm);
     nm->post_compiled_method_load_event();
   } else {
     // CodeCache is full, disable compilation
-    // Ought to log this but compile log is only per compile thread
-    // and we're some non descript Java thread.
-    MutexUnlocker mu(AdapterHandlerLibrary_lock);
     CompileBroker::handle_full_code_cache();
   }
   return nm;
@@ -2438,7 +2558,7 @@
 
     BufferBlob*  buf = buffer_blob(); // the temporary code buffer in CodeCache
     if (buf != NULL) {
-      CodeBuffer buffer(buf->instructions_begin(), buf->instructions_size());
+      CodeBuffer buffer(buf);
       // Need a few relocation entries
       double locs_buf[20];
       buffer.insts()->initialize_shared_locs(
@@ -2603,17 +2723,9 @@
   // Copy the locals.  Order is preserved so that loading of longs works.
   // Since there's no GC I can copy the oops blindly.
   assert( sizeof(HeapWord)==sizeof(intptr_t), "fix this code");
-  if (TaggedStackInterpreter) {
-    for (int i = 0; i < max_locals; i++) {
-      // copy only each local separately to the buffer avoiding the tag
-      buf[i] = *fr.interpreter_frame_local_at(max_locals-i-1);
-    }
-  } else {
-    Copy::disjoint_words(
-                       (HeapWord*)fr.interpreter_frame_local_at(max_locals-1),
+  Copy::disjoint_words((HeapWord*)fr.interpreter_frame_local_at(max_locals-1),
                        (HeapWord*)&buf[0],
                        max_locals);
-  }
 
   // Inflate locks.  Copy the displaced headers.  Be careful, there can be holes.
   int i = max_locals;
@@ -2639,7 +2751,6 @@
   FREE_C_HEAP_ARRAY(intptr_t,buf);
 JRT_END
 
-#ifndef PRODUCT
 bool AdapterHandlerLibrary::contains(CodeBlob* b) {
   AdapterHandlerTableIterator iter(_adapters);
   while (iter.has_next()) {
@@ -2649,21 +2760,24 @@
   return false;
 }
 
-void AdapterHandlerLibrary::print_handler(CodeBlob* b) {
+void AdapterHandlerLibrary::print_handler_on(outputStream* st, CodeBlob* b) {
   AdapterHandlerTableIterator iter(_adapters);
   while (iter.has_next()) {
     AdapterHandlerEntry* a = iter.next();
     if ( b == CodeCache::find_blob(a->get_i2c_entry()) ) {
-      tty->print("Adapter for signature: ");
-      tty->print_cr("%s i2c: " INTPTR_FORMAT " c2i: " INTPTR_FORMAT " c2iUV: " INTPTR_FORMAT,
-                    a->fingerprint()->as_string(),
-                    a->get_i2c_entry(), a->get_c2i_entry(), a->get_c2i_unverified_entry());
+      st->print("Adapter for signature: ");
+      st->print_cr("%s i2c: " INTPTR_FORMAT " c2i: " INTPTR_FORMAT " c2iUV: " INTPTR_FORMAT,
+                   a->fingerprint()->as_string(),
+                   a->get_i2c_entry(), a->get_c2i_entry(), a->get_c2i_unverified_entry());
+
       return;
     }
   }
   assert(false, "Should have found handler");
 }
 
+#ifndef PRODUCT
+
 void AdapterHandlerLibrary::print_statistics() {
   _adapters->print_statistics();
 }