8217717: ZGC: Broken oop map in C1 load barrier stub
authorpliden
Mon, 28 Jan 2019 08:58:42 +0100
changeset 53529 37c8fcc76699
parent 53528 21bcd9cdffb3
child 53530 f5671b2e74df
8217717: ZGC: Broken oop map in C1 load barrier stub Reviewed-by: eosterlund, neliasso Contributed-by: erik.osterlund@oracle.com, per.liden@oracle.com
src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp
src/hotspot/share/c1/c1_LIRAssembler.hpp
src/hotspot/share/gc/shared/c1/barrierSetC1.cpp
src/hotspot/share/gc/shared/c1/barrierSetC1.hpp
src/hotspot/share/gc/z/c1/zBarrierSetC1.cpp
src/hotspot/share/gc/z/c1/zBarrierSetC1.hpp
--- a/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp	Sat Jan 26 12:51:27 2019 -0800
+++ b/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp	Mon Jan 28 08:58:42 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, 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
@@ -280,7 +280,7 @@
     ref_addr = stub->ref_addr()->as_pointer_register();
   } else {
     // Load address into tmp register
-    ce->leal(stub->ref_addr(), stub->tmp(), stub->patch_code(), stub->patch_info());
+    ce->leal(stub->ref_addr(), stub->tmp());
     ref_addr = stub->tmp()->as_pointer_register();
   }
 
--- a/src/hotspot/share/c1/c1_LIRAssembler.hpp	Sat Jan 26 12:51:27 2019 -0800
+++ b/src/hotspot/share/c1/c1_LIRAssembler.hpp	Mon Jan 28 08:58:42 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, 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
@@ -240,7 +240,7 @@
   void align_call(LIR_Code code);
 
   void negate(LIR_Opr left, LIR_Opr dest, LIR_Opr tmp = LIR_OprFact::illegalOpr);
-  void leal(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info);
+  void leal(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_code = lir_patch_none, CodeEmitInfo* info = NULL);
 
   void rt_call(LIR_Opr result, address dest, const LIR_OprList* args, LIR_Opr tmp, CodeEmitInfo* info);
 
--- a/src/hotspot/share/gc/shared/c1/barrierSetC1.cpp	Sat Jan 26 12:51:27 2019 -0800
+++ b/src/hotspot/share/gc/shared/c1/barrierSetC1.cpp	Mon Jan 28 08:58:42 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, 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
@@ -62,9 +62,13 @@
 
   if (resolve_in_register) {
     LIR_Opr resolved_addr = gen->new_pointer_register();
-    __ leal(addr_opr, resolved_addr);
-    resolved_addr = LIR_OprFact::address(new LIR_Address(resolved_addr, access.type()));
-    return resolved_addr;
+    if (needs_patching) {
+      __ leal(addr_opr, resolved_addr, lir_patch_normal, access.patch_emit_info());
+      access.clear_decorators(C1_NEEDS_PATCHING);
+    } else {
+      __ leal(addr_opr, resolved_addr);
+    }
+    return LIR_OprFact::address(new LIR_Address(resolved_addr, access.type()));
   } else {
     return addr_opr;
   }
--- a/src/hotspot/share/gc/shared/c1/barrierSetC1.hpp	Sat Jan 26 12:51:27 2019 -0800
+++ b/src/hotspot/share/gc/shared/c1/barrierSetC1.hpp	Mon Jan 28 08:58:42 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, 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
@@ -92,17 +92,18 @@
     load_offset();
   }
 
-  LIRGenerator* gen() const            { return _gen; }
-  CodeEmitInfo*& patch_emit_info()     { return _patch_emit_info; }
-  CodeEmitInfo*& access_emit_info()    { return _access_emit_info; }
-  LIRAddressOpr& base()                { return _base; }
-  LIRAddressOpr& offset()              { return _offset; }
-  BasicType type() const               { return _type; }
-  LIR_Opr resolved_addr() const        { return _resolved_addr; }
-  void set_resolved_addr(LIR_Opr addr) { _resolved_addr = addr; }
-  bool is_oop() const                  { return _type == T_ARRAY || _type == T_OBJECT; }
-  DecoratorSet decorators() const      { return _decorators; }
-  bool is_raw() const                  { return (_decorators & AS_RAW) != 0; }
+  LIRGenerator* gen() const              { return _gen; }
+  CodeEmitInfo*& patch_emit_info()       { return _patch_emit_info; }
+  CodeEmitInfo*& access_emit_info()      { return _access_emit_info; }
+  LIRAddressOpr& base()                  { return _base; }
+  LIRAddressOpr& offset()                { return _offset; }
+  BasicType type() const                 { return _type; }
+  LIR_Opr resolved_addr() const          { return _resolved_addr; }
+  void set_resolved_addr(LIR_Opr addr)   { _resolved_addr = addr; }
+  bool is_oop() const                    { return _type == T_ARRAY || _type == T_OBJECT; }
+  DecoratorSet decorators() const        { return _decorators; }
+  void clear_decorators(DecoratorSet ds) { _decorators &= ~ds; }
+  bool is_raw() const                    { return (_decorators & AS_RAW) != 0; }
 };
 
 // The BarrierSetC1 class is the main entry point for the GC backend of the Access API in C1.
--- a/src/hotspot/share/gc/z/c1/zBarrierSetC1.cpp	Sat Jan 26 12:51:27 2019 -0800
+++ b/src/hotspot/share/gc/z/c1/zBarrierSetC1.cpp	Mon Jan 28 08:58:42 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -36,7 +36,6 @@
     _ref_addr(access.resolved_addr()),
     _ref(ref),
     _tmp(LIR_OprFact::illegalOpr),
-    _patch_info(access.patch_emit_info()),
     _runtime_stub(runtime_stub) {
 
   // Allocate tmp register if needed
@@ -72,28 +71,14 @@
   return _tmp;
 }
 
-LIR_PatchCode ZLoadBarrierStubC1::patch_code() const {
-  return (_decorators & C1_NEEDS_PATCHING) != 0 ? lir_patch_normal : lir_patch_none;
-}
-
-CodeEmitInfo*& ZLoadBarrierStubC1::patch_info() {
-  return _patch_info;
-}
-
 address ZLoadBarrierStubC1::runtime_stub() const {
   return _runtime_stub;
 }
 
 void ZLoadBarrierStubC1::visit(LIR_OpVisitState* visitor) {
-  if (_patch_info != NULL) {
-    visitor->do_slow_case(_patch_info);
-  } else {
-    visitor->do_slow_case();
-  }
-
+  visitor->do_slow_case();
   visitor->do_input(_ref_addr);
   visitor->do_output(_ref);
-
   if (_tmp->is_valid()) {
     visitor->do_temp(_tmp);
   }
@@ -174,6 +159,14 @@
   __ branch_destination(stub->continuation());
 }
 
+LIR_Opr ZBarrierSetC1::resolve_address(LIRAccess& access, bool resolve_in_register) {
+  // We must resolve in register when patching. This is to avoid
+  // having a patch area in the load barrier stub, since the call
+  // into the runtime to patch will not have the proper oop map.
+  const bool patch_before_barrier = barrier_needed(access) && (access.decorators() & C1_NEEDS_PATCHING) != 0;
+  return BarrierSetC1::resolve_address(access, resolve_in_register || patch_before_barrier);
+}
+
 #undef __
 
 void ZBarrierSetC1::load_at_resolved(LIRAccess& access, LIR_Opr result) {
--- a/src/hotspot/share/gc/z/c1/zBarrierSetC1.hpp	Sat Jan 26 12:51:27 2019 -0800
+++ b/src/hotspot/share/gc/z/c1/zBarrierSetC1.hpp	Mon Jan 28 08:58:42 2019 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, 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
@@ -32,12 +32,11 @@
 
 class ZLoadBarrierStubC1 : public CodeStub {
 private:
-  DecoratorSet  _decorators;
-  LIR_Opr       _ref_addr;
-  LIR_Opr       _ref;
-  LIR_Opr       _tmp;
-  CodeEmitInfo* _patch_info;
-  address       _runtime_stub;
+  DecoratorSet _decorators;
+  LIR_Opr      _ref_addr;
+  LIR_Opr      _ref;
+  LIR_Opr      _tmp;
+  address      _runtime_stub;
 
 public:
   ZLoadBarrierStubC1(LIRAccess& access, LIR_Opr ref, address runtime_stub);
@@ -46,8 +45,6 @@
   LIR_Opr ref() const;
   LIR_Opr ref_addr() const;
   LIR_Opr tmp() const;
-  LIR_PatchCode patch_code() const;
-  CodeEmitInfo*& patch_info();
   address runtime_stub() const;
 
   virtual void emit_code(LIR_Assembler* ce);
@@ -67,6 +64,7 @@
   void load_barrier(LIRAccess& access, LIR_Opr result) const;
 
 protected:
+  virtual LIR_Opr resolve_address(LIRAccess& access, bool resolve_in_register);
   virtual void load_at_resolved(LIRAccess& access, LIR_Opr result);
   virtual LIR_Opr atomic_xchg_at_resolved(LIRAccess& access, LIRItem& value);
   virtual LIR_Opr atomic_cmpxchg_at_resolved(LIRAccess& access, LIRItem& cmp_value, LIRItem& new_value);