changeset 3714:b648304ba4ff

Change Graal monitor enter and exit from BasicObjectLock to BasicLock
author Christian Wimmer <christian.wimmer@oracle.com>
date Tue, 13 Dec 2011 21:17:46 -0800
parents d6a0c46a73b2
children 3f6325ddd391
files src/cpu/x86/vm/c1_MacroAssembler_x86.cpp src/cpu/x86/vm/c1_MacroAssembler_x86.hpp src/cpu/x86/vm/c1_Runtime1_x86.cpp src/share/vm/c1/c1_Runtime1.cpp src/share/vm/c1/c1_Runtime1.hpp src/share/vm/classfile/systemDictionary.hpp src/share/vm/classfile/vmSymbols.hpp src/share/vm/graal/graalCodeInstaller.cpp src/share/vm/graal/graalJavaAccess.hpp
diffstat 9 files changed, 117 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp	Tue Dec 13 21:16:50 2011 -0800
+++ b/src/cpu/x86/vm/c1_MacroAssembler_x86.cpp	Tue Dec 13 21:17:46 2011 -0800
@@ -35,7 +35,7 @@
 #include "runtime/os.hpp"
 #include "runtime/stubRoutines.hpp"
 
-int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Register scratch, Label& slow_case) {
+int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr, Register scratch, Label& slow_case, bool use_basic_object_lock) {
   const int aligned_mask = BytesPerWord -1;
   const int hdr_offset = oopDesc::mark_offset_in_bytes();
   assert(hdr == rax, "hdr must be rax, for the cmpxchg instruction");
@@ -45,8 +45,10 @@
 
   verify_oop(obj);
 
-  // save object being locked into the BasicObjectLock
-  movptr(Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()), obj);
+  if (use_basic_object_lock) {
+    // save object being locked into the BasicObjectLock
+    movptr(Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()), obj);
+  }
 
   if (UseBiasedLocking) {
     assert(scratch != noreg, "should have scratch register at this point");
@@ -98,7 +100,7 @@
 }
 
 
-void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) {
+void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case, bool use_basic_object_lock) {
   const int aligned_mask = BytesPerWord -1;
   const int hdr_offset = oopDesc::mark_offset_in_bytes();
   assert(disp_hdr == rax, "disp_hdr must be rax, for the cmpxchg instruction");
@@ -106,8 +108,10 @@
   Label done;
 
   if (UseBiasedLocking) {
-    // load object
-    movptr(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()));
+    if (use_basic_object_lock) {
+      // load object
+      movptr(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()));
+    }
     biased_locking_exit(obj, hdr, done);
   }
 
@@ -118,8 +122,10 @@
   // if we had recursive locking, we are done
   jcc(Assembler::zero, done);
   if (!UseBiasedLocking) {
-    // load object
-    movptr(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()));
+    if (use_basic_object_lock) {
+      // load object
+      movptr(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()));
+    }
   }
   verify_oop(obj);
   // test if object header is pointing to the displaced header, and if so, restore
--- a/src/cpu/x86/vm/c1_MacroAssembler_x86.hpp	Tue Dec 13 21:16:50 2011 -0800
+++ b/src/cpu/x86/vm/c1_MacroAssembler_x86.hpp	Tue Dec 13 21:17:46 2011 -0800
@@ -51,13 +51,13 @@
   // disp_hdr: must point to the displaced header location, contents preserved
   // scratch : scratch register, contents destroyed
   // returns code offset at which to add null check debug information
-  int lock_object  (Register swap, Register obj, Register disp_hdr, Register scratch, Label& slow_case);
+  int lock_object  (Register swap, Register obj, Register disp_hdr, Register scratch, Label& slow_case, bool use_basic_object_lock = true);
 
   // unlocking
   // hdr     : contents destroyed
   // obj     : must point to the object to lock, contents preserved
   // disp_hdr: must be eax & must point to the displaced header location, contents destroyed
-  void unlock_object(Register swap, Register obj, Register lock, Label& slow_case);
+  void unlock_object(Register swap, Register obj, Register lock, Label& slow_case, bool use_basic_object_lock = true);
 
   void initialize_object(
     Register obj,                      // result: pointer to object after successful allocation
--- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Tue Dec 13 21:16:50 2011 -0800
+++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Tue Dec 13 21:17:46 2011 -0800
@@ -2067,17 +2067,17 @@
       // copied from LIR_Assembler::emit_lock
       if (UseFastLocking) {
         assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
-        __ lock_object(scratch1, obj, lock, scratch2, slow_case);
+        __ lock_object(scratch1, obj, lock, scratch2, slow_case, false);
       __ ret(0);
       }
 
       __ bind(slow_case);
       {
         StubFrame f(sasm, "graal_monitorenter", dont_gc_arguments);
-        OopMap* map = save_live_registers(sasm, 1, save_fpu_registers);
+        OopMap* map = save_live_registers(sasm, 2, save_fpu_registers);
 
         // Called with store_parameter and not C abi
-        int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, monitorenter), obj, lock);
+        int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, graal_monitorenter), obj, lock);
 
         oop_maps = new OopMapSet();
         oop_maps->add_gc_map(call_offset, map);
@@ -2101,7 +2101,7 @@
       // copied from LIR_Assembler::emit_lock
       if (UseFastLocking) {
         assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header");
-        __ unlock_object(scratch1, obj, lock2, slow_case);
+        __ unlock_object(scratch1, obj, lock2, slow_case, false);
       __ ret(0);
       }
 
@@ -2113,7 +2113,7 @@
         // note: really a leaf routine but must setup last java sp
         //       => use call_RT for now (speed can be improved by
         //       doing last java sp setup manually)
-        int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, monitorexit), lock);
+        int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, graal_monitorexit), obj, lock);
 
         oop_maps = new OopMapSet();
         oop_maps->add_gc_map(call_offset, map);
--- a/src/share/vm/c1/c1_Runtime1.cpp	Tue Dec 13 21:16:50 2011 -0800
+++ b/src/share/vm/c1/c1_Runtime1.cpp	Tue Dec 13 21:17:46 2011 -0800
@@ -658,6 +658,68 @@
 JRT_END
 
 
+JRT_ENTRY_NO_ASYNC(void, Runtime1::graal_monitorenter(JavaThread* thread, oopDesc* obj, BasicLock* lock))
+  NOT_PRODUCT(_monitorenter_slowcase_cnt++;)
+#ifdef ASSERT
+  if (TraceGraal >= 3) {
+    tty->print_cr("entered locking slow case with obj=" INTPTR_FORMAT " and lock= " INTPTR_FORMAT, obj, lock);
+  }
+  if (PrintBiasedLockingStatistics) {
+    Atomic::inc(BiasedLocking::slow_path_entry_count_addr());
+  }
+#endif
+  Handle h_obj(thread, obj);
+  assert(h_obj()->is_oop(), "must be NULL or an object");
+  if (UseBiasedLocking) {
+    // Retry fast entry if bias is revoked to avoid unnecessary inflation
+    ObjectSynchronizer::fast_enter(h_obj, lock, true, CHECK);
+  } else {
+    if (UseFastLocking) {
+      // When using fast locking, the compiled code has already tried the fast case
+      ObjectSynchronizer::slow_enter(h_obj, lock, THREAD);
+    } else {
+      ObjectSynchronizer::fast_enter(h_obj, lock, false, THREAD);
+    }
+  }
+#ifdef ASSERT
+  if (TraceGraal >= 3) {
+    tty->print_cr("exiting locking");
+    lock->lock()->print_on(tty);
+    tty->print_cr("");
+    tty->print_cr("done");
+  }
+#endif
+JRT_END
+
+
+JRT_LEAF(void, Runtime1::graal_monitorexit(JavaThread* thread, oopDesc* obj, BasicLock* lock))
+  NOT_PRODUCT(_monitorexit_slowcase_cnt++;)
+  assert(thread == JavaThread::current(), "threads must correspond");
+  assert(thread->last_Java_sp(), "last_Java_sp must be set");
+  // monitorexit is non-blocking (leaf routine) => no exceptions can be thrown
+  EXCEPTION_MARK;
+
+#ifdef DEBUG
+  if (!obj->is_oop()) {
+    ResetNoHandleMark rhm;
+    nmethod* method = thread->last_frame().cb()->as_nmethod_or_null();
+    if (method != NULL) {
+      tty->print_cr("ERROR in monitorexit in method %s wrong obj " INTPTR_FORMAT, method->name(), obj);
+    }
+    thread->print_stack_on(tty);
+    assert(false, "invalid lock object pointer dected");
+  }
+#endif
+
+  if (UseFastLocking) {
+    // When using fast locking, the compiled code has already tried the fast case
+    ObjectSynchronizer::slow_exit(obj, lock, THREAD);
+  } else {
+    ObjectSynchronizer::fast_exit(obj, lock, THREAD);
+  }
+JRT_END
+
+
 JRT_ENTRY_NO_ASYNC(void, Runtime1::monitorenter(JavaThread* thread, oopDesc* obj, BasicObjectLock* lock))
   NOT_PRODUCT(_monitorenter_slowcase_cnt++;)
 #ifdef ASSERT
--- a/src/share/vm/c1/c1_Runtime1.hpp	Tue Dec 13 21:16:50 2011 -0800
+++ b/src/share/vm/c1/c1_Runtime1.hpp	Tue Dec 13 21:17:46 2011 -0800
@@ -164,6 +164,9 @@
   static void throw_incompatible_class_change_error(JavaThread* thread);
   static void throw_array_store_exception(JavaThread* thread, oopDesc* object);
 
+  static void graal_monitorenter(JavaThread* thread, oopDesc* obj, BasicLock* lock);
+  static void graal_monitorexit (JavaThread* thread, oopDesc* obj, BasicLock* lock);
+
   static void monitorenter(JavaThread* thread, oopDesc* obj, BasicObjectLock* lock);
   static void monitorexit (JavaThread* thread, BasicObjectLock* lock);
 
--- a/src/share/vm/classfile/systemDictionary.hpp	Tue Dec 13 21:16:50 2011 -0800
+++ b/src/share/vm/classfile/systemDictionary.hpp	Tue Dec 13 21:17:46 2011 -0800
@@ -212,6 +212,7 @@
   template(CiCodePos_klass,              com_sun_cri_ci_CiCodePos,                                  Opt) \
   template(CiConstant_klass,             com_sun_cri_ci_CiConstant,                                 Opt) \
   template(CiVirtualObject_klass,        com_sun_cri_ci_CiVirtualObject,                            Opt) \
+  template(CiMonitorValue_klass,         com_sun_cri_ci_CiMonitorValue,                             Opt) \
   template(CiKind_klass,                 com_sun_cri_ci_CiKind,                                     Opt) \
   template(CiRuntimeCall_klass,          com_sun_cri_ci_CiRuntimeCall,                              Opt) \
   template(RiMethod_klass,               com_sun_cri_ri_RiMethod,                                   Opt) \
--- a/src/share/vm/classfile/vmSymbols.hpp	Tue Dec 13 21:16:50 2011 -0800
+++ b/src/share/vm/classfile/vmSymbols.hpp	Tue Dec 13 21:17:46 2011 -0800
@@ -300,6 +300,7 @@
   template(com_sun_cri_ci_CiCodePos,                  "com/sun/cri/ci/CiCodePos")                                       \
   template(com_sun_cri_ci_CiConstant,                 "com/sun/cri/ci/CiConstant")                                      \
   template(com_sun_cri_ci_CiVirtualObject,            "com/sun/cri/ci/CiVirtualObject")                                 \
+  template(com_sun_cri_ci_CiMonitorValue,             "com/sun/cri/ci/CiMonitorValue")                                  \
   template(com_sun_cri_ci_CiKind,                     "com/sun/cri/ci/CiKind")                                          \
   template(com_sun_cri_ci_CiRuntimeCall,              "com/sun/cri/ci/CiRuntimeCall")                                   \
   template(startCompiler_name,                        "startCompiler")                                                  \
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Tue Dec 13 21:16:50 2011 -0800
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Tue Dec 13 21:17:46 2011 -0800
@@ -221,6 +221,23 @@
   return NULL;
 }
 
+static MonitorValue* get_monitor_value(oop value, int frame_size, GrowableArray<ScopeValue*>* objects) {
+  guarantee(value->is_a(CiMonitorValue::klass()), "Monitors must be of type CiMonitorValue");
+
+  ScopeValue* second = NULL;
+  ScopeValue* owner_value = get_hotspot_value(CiMonitorValue::owner(value), frame_size, objects, second);
+  assert(second == NULL, "monitor cannot occupy two stack slots");
+
+  ScopeValue* lock_data_value = get_hotspot_value(CiMonitorValue::lockData(value), frame_size, objects, second);
+  assert(second == NULL, "monitor cannot occupy two stack slots");
+  assert(lock_data_value->is_location(), "invalid monitor location");
+  Location lock_data_loc = ((LocationValue*)lock_data_value)->location();
+
+  bool eliminated = CiMonitorValue::eliminated(value);
+
+  return new MonitorValue(owner_value, lock_data_loc, eliminated);
+}
+
 void CodeInstaller::initialize_assumptions(oop target_method) {
   _oop_recorder = new OopRecorder(_env->arena());
   _env->set_oop_recorder(_oop_recorder);
@@ -488,26 +505,22 @@
 
     for (jint i = 0; i < values->length(); i++) {
       ScopeValue* second = NULL;
-      ScopeValue* value = get_hotspot_value(((oop*) values->base(T_OBJECT))[i], _frame_size, objects, second);
+      oop value = ((oop*) values->base(T_OBJECT))[i];
 
       if (i < local_count) {
+        ScopeValue* first = get_hotspot_value(value, _frame_size, objects, second);
         if (second != NULL) {
           locals->append(second);
         }
-        locals->append(value);
+        locals->append(first);
       } else if (i < local_count + expression_count) {
+        ScopeValue* first = get_hotspot_value(value, _frame_size, objects, second);
         if (second != NULL) {
-          expressions->append(value);
+          expressions->append(second);
         }
-        expressions->append(value);
+        expressions->append(first);
       } else {
-        assert(second == NULL, "monitor cannot occupy two stack slots");
-        assert(value->is_location(), "invalid monitor location");
-        LocationValue* loc = (LocationValue*)value;
-        int monitor_offset = loc->location().stack_offset();
-        LocationValue* obj = new LocationValue(Location::new_stk_loc(Location::oop, monitor_offset + BasicObjectLock::obj_offset_in_bytes()));
-        bool eliminated = value->is_object();
-        monitors->append(new MonitorValue(obj, Location::new_stk_loc(Location::normal, monitor_offset  + BasicObjectLock::lock_offset_in_bytes()), eliminated));
+        monitors->append(get_monitor_value(value, _frame_size, objects));
       }
       if (second != NULL) {
         i++;
--- a/src/share/vm/graal/graalJavaAccess.hpp	Tue Dec 13 21:16:50 2011 -0800
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Tue Dec 13 21:17:46 2011 -0800
@@ -220,6 +220,11 @@
     oop_field(CiVirtualObject, type, "Lcom/sun/cri/ri/RiType;")                         \
     oop_field(CiVirtualObject, values, "[Lcom/sun/cri/ci/CiValue;")                     \
   end_class                                                                             \
+  start_class(CiMonitorValue)                                                           \
+    oop_field(CiMonitorValue, owner, "Lcom/sun/cri/ci/CiValue;")                        \
+    oop_field(CiMonitorValue, lockData, "Lcom/sun/cri/ci/CiValue;")                     \
+    boolean_field(CiMonitorValue, eliminated)                                           \
+  end_class                                                                             \
   start_class(RiTypeProfile)                                                            \
     int_field(RiTypeProfile, count)                                                     \
     int_field(RiTypeProfile, morphism)                                                  \