changeset 3536:6c5b7a6becc8

7187454: stack overflow in C2 compiler thread on Solaris x86 Summary: Added new FormatBufferResource class to use thread's resource area for error message buffer. Reviewed-by: twisti
author kvn
date Mon, 30 Jul 2012 09:49:25 -0700
parents 977007096840
children 8cb110fd7627
files make/solaris/makefiles/fastdebug.make src/share/vm/opto/callGenerator.cpp src/share/vm/opto/chaitin.cpp src/share/vm/opto/compile.cpp src/share/vm/opto/doCall.cpp src/share/vm/opto/escape.cpp src/share/vm/opto/idealGraphPrinter.cpp src/share/vm/opto/node.hpp src/share/vm/opto/parse1.cpp src/share/vm/utilities/debug.cpp src/share/vm/utilities/debug.hpp
diffstat 11 files changed, 42 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/make/solaris/makefiles/fastdebug.make	Fri Jul 27 16:14:15 2012 -0700
+++ b/make/solaris/makefiles/fastdebug.make	Mon Jul 30 09:49:25 2012 -0700
@@ -39,9 +39,6 @@
 ifeq ($(COMPILER_REV_NUMERIC), 510)
 # CC 5.10 has bug XXXXX with -xO4
 OPT_CFLAGS/jvmtiClassFileReconstituter.o = $(OPT_CFLAGS/SLOWER)
-# jvm98 crashes on solaris-i586-fastdebug and solaris-sparc-fastdebug with stack overflow
-OPT_CFLAGS/escape.o = $(OPT_CFLAGS) -xspace
-OPT_CFLAGS/matcher.o = $(OPT_CFLAGS) -xspace
 endif # COMPILER_REV_NUMERIC == 510
 
 ifeq ($(COMPILER_REV_NUMERIC), 509)
--- a/src/share/vm/opto/callGenerator.cpp	Fri Jul 27 16:14:15 2012 -0700
+++ b/src/share/vm/opto/callGenerator.cpp	Mon Jul 30 09:49:25 2012 -0700
@@ -737,7 +737,7 @@
     break;
 
   default:
-    fatal(err_msg("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid)));
+    fatal(err_msg_res("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid)));
     break;
   }
   return NULL;
--- a/src/share/vm/opto/chaitin.cpp	Fri Jul 27 16:14:15 2012 -0700
+++ b/src/share/vm/opto/chaitin.cpp	Mon Jul 30 09:49:25 2012 -0700
@@ -1536,7 +1536,7 @@
 
   // Check for AddP-related opcodes
   if( !derived->is_Phi() ) {
-    assert(derived->as_Mach()->ideal_Opcode() == Op_AddP, err_msg("but is: %s", derived->Name()));
+    assert(derived->as_Mach()->ideal_Opcode() == Op_AddP, err_msg_res("but is: %s", derived->Name()));
     Node *base = derived->in(AddPNode::Base);
     derived_base_map[derived->_idx] = base;
     return base;
--- a/src/share/vm/opto/compile.cpp	Fri Jul 27 16:14:15 2012 -0700
+++ b/src/share/vm/opto/compile.cpp	Mon Jul 30 09:49:25 2012 -0700
@@ -3138,7 +3138,7 @@
     default: ShouldNotReachHere();
     }
     assert(constant_addr, "consts section too small");
-    assert((constant_addr - _masm.code()->consts()->start()) == con.offset(), err_msg("must be: %d == %d", constant_addr - _masm.code()->consts()->start(), con.offset()));
+    assert((constant_addr - _masm.code()->consts()->start()) == con.offset(), err_msg_res("must be: %d == %d", constant_addr - _masm.code()->consts()->start(), con.offset()));
   }
 }
 
@@ -3199,7 +3199,7 @@
   if (Compile::current()->in_scratch_emit_size())  return;
 
   assert(labels.is_nonempty(), "must be");
-  assert((uint) labels.length() == n->outcnt(), err_msg("must be equal: %d == %d", labels.length(), n->outcnt()));
+  assert((uint) labels.length() == n->outcnt(), err_msg_res("must be equal: %d == %d", labels.length(), n->outcnt()));
 
   // Since MachConstantNode::constant_offset() also contains
   // table_base_offset() we need to subtract the table_base_offset()
@@ -3211,7 +3211,7 @@
 
   for (uint i = 0; i < n->outcnt(); i++) {
     address* constant_addr = &jump_table_base[i];
-    assert(*constant_addr == (((address) n) + i), err_msg("all jump-table entries must contain adjusted node pointer: " INTPTR_FORMAT " == " INTPTR_FORMAT, *constant_addr, (((address) n) + i)));
+    assert(*constant_addr == (((address) n) + i), err_msg_res("all jump-table entries must contain adjusted node pointer: " INTPTR_FORMAT " == " INTPTR_FORMAT, *constant_addr, (((address) n) + i)));
     *constant_addr = cb.consts()->target(*labels.at(i), (address) constant_addr);
     cb.consts()->relocate((address) constant_addr, relocInfo::internal_word_type);
   }
--- a/src/share/vm/opto/doCall.cpp	Fri Jul 27 16:14:15 2012 -0700
+++ b/src/share/vm/opto/doCall.cpp	Mon Jul 30 09:49:25 2012 -0700
@@ -523,10 +523,10 @@
             retnode = _gvn.transform( new (C, 3) LShiftINode(retnode, intcon(16)) );
             retnode = _gvn.transform( new (C, 3) RShiftINode(retnode, intcon(16)) );
           } else {
-            assert(ct == T_INT, err_msg("rt=%d, ct=%d", rt, ct));
+            assert(ct == T_INT, err_msg_res("rt=%d, ct=%d", rt, ct));
           }
         } else if (rt == T_OBJECT) {
-          assert(ct == T_OBJECT, err_msg("rt=T_OBJECT, ct=%d", ct));
+          assert(ct == T_OBJECT, err_msg_res("rt=T_OBJECT, ct=%d", ct));
           if (ctype->is_loaded()) {
             Node* if_fail = top();
             retnode = gen_checkcast(retnode, makecon(TypeKlassPtr::make(ctype->as_klass())), &if_fail);
@@ -539,7 +539,7 @@
             push(retnode);
           }
         } else {
-          assert(ct == rt, err_msg("unexpected mismatch rt=%d, ct=%d", rt, ct));
+          assert(ct == rt, err_msg_res("unexpected mismatch rt=%d, ct=%d", rt, ct));
           // push a zero; it's better than getting an oop/int mismatch
           retnode = pop_node(rt);
           retnode = zerocon(ct);
--- a/src/share/vm/opto/escape.cpp	Fri Jul 27 16:14:15 2012 -0700
+++ b/src/share/vm/opto/escape.cpp	Mon Jul 30 09:49:25 2012 -0700
@@ -1055,7 +1055,7 @@
       C->log()->text("%s", (iterations >= CG_BUILD_ITER_LIMIT) ? "iterations" : "time");
       C->log()->end_elem(" limit'");
     }
-    assert(false, err_msg("infinite EA connection graph build (%f sec, %d iterations) with %d nodes and worklist size %d",
+    assert(false, err_msg_res("infinite EA connection graph build (%f sec, %d iterations) with %d nodes and worklist size %d",
            time.seconds(), iterations, nodes_size(), ptnodes_worklist.length()));
     // Possible infinite build_connection_graph loop,
     // bailout (no changes to ideal graph were made).
--- a/src/share/vm/opto/idealGraphPrinter.cpp	Fri Jul 27 16:14:15 2012 -0700
+++ b/src/share/vm/opto/idealGraphPrinter.cpp	Mon Jul 30 09:49:25 2012 -0700
@@ -155,8 +155,8 @@
     } else {
       // It would be nice if we could shut down cleanly but it should
       // be an error if we can't connect to the visualizer.
-      fatal(err_msg("Couldn't connect to visualizer at %s:%d",
-                    PrintIdealGraphAddress, PrintIdealGraphPort));
+      fatal(err_msg_res("Couldn't connect to visualizer at %s:%d",
+                        PrintIdealGraphAddress, PrintIdealGraphPort));
     }
   }
 
--- a/src/share/vm/opto/node.hpp	Fri Jul 27 16:14:15 2012 -0700
+++ b/src/share/vm/opto/node.hpp	Mon Jul 30 09:49:25 2012 -0700
@@ -363,7 +363,7 @@
 #endif
 
   // Reference to the i'th input Node.  Error if out of bounds.
-  Node* in(uint i) const { assert(i < _max, err_msg("oob: i=%d, _max=%d", i, _max)); return _in[i]; }
+  Node* in(uint i) const { assert(i < _max, err_msg_res("oob: i=%d, _max=%d", i, _max)); return _in[i]; }
   // Reference to the i'th output Node.  Error if out of bounds.
   // Use this accessor sparingly.  We are going trying to use iterators instead.
   Node* raw_out(uint i) const { assert(i < _outcnt,"oob"); return _out[i]; }
@@ -394,7 +394,7 @@
   void ins_req( uint i, Node *n ); // Insert a NEW required input
   void set_req( uint i, Node *n ) {
     assert( is_not_dead(n), "can not use dead node");
-    assert( i < _cnt, err_msg("oob: i=%d, _cnt=%d", i, _cnt));
+    assert( i < _cnt, err_msg_res("oob: i=%d, _cnt=%d", i, _cnt));
     assert( !VerifyHashTableKeys || _hash_lock == 0,
             "remove node from hash table before modifying it");
     Node** p = &_in[i];    // cache this._in, across the del_out call
--- a/src/share/vm/opto/parse1.cpp	Fri Jul 27 16:14:15 2012 -0700
+++ b/src/share/vm/opto/parse1.cpp	Mon Jul 30 09:49:25 2012 -0700
@@ -1399,7 +1399,7 @@
     int pre_bc_sp = sp();
     int inputs, depth;
     bool have_se = !stopped() && compute_stack_effects(inputs, depth, /*for_parse*/ true);
-    assert(!have_se || pre_bc_sp >= inputs, err_msg("have enough stack to execute this BC: pre_bc_sp=%d, inputs=%d", pre_bc_sp, inputs));
+    assert(!have_se || pre_bc_sp >= inputs, err_msg_res("have enough stack to execute this BC: pre_bc_sp=%d, inputs=%d", pre_bc_sp, inputs));
 #endif //ASSERT
 
     do_one_bytecode();
--- a/src/share/vm/utilities/debug.cpp	Fri Jul 27 16:14:15 2012 -0700
+++ b/src/share/vm/utilities/debug.cpp	Mon Jul 30 09:49:25 2012 -0700
@@ -91,6 +91,13 @@
 #  endif
 #endif // PRODUCT
 
+FormatBufferResource::FormatBufferResource(const char * format, ...)
+  : FormatBufferBase((char*)resource_allocate_bytes(RES_BUFSZ)) {
+  va_list argp;
+  va_start(argp, format);
+  jio_vsnprintf(_buf, RES_BUFSZ, format, argp);
+  va_end(argp);
+}
 
 void warning(const char* format, ...) {
   if (PrintWarnings) {
--- a/src/share/vm/utilities/debug.hpp	Fri Jul 27 16:14:15 2012 -0700
+++ b/src/share/vm/utilities/debug.hpp	Mon Jul 30 09:49:25 2012 -0700
@@ -31,29 +31,43 @@
 #include <stdarg.h>
 
 // Simple class to format the ctor arguments into a fixed-sized buffer.
+class FormatBufferBase {
+ protected:
+  char* _buf;
+  inline FormatBufferBase(char* buf) : _buf(buf) {}
+ public:
+  operator const char *() const { return _buf; }
+};
+
+// Use resource area for buffer
+#define RES_BUFSZ 256
+class FormatBufferResource : public FormatBufferBase {
+ public:
+  FormatBufferResource(const char * format, ...);
+};
+
+// Use stack for buffer
 template <size_t bufsz = 256>
-class FormatBuffer {
+class FormatBuffer : public FormatBufferBase {
  public:
   inline FormatBuffer(const char * format, ...);
   inline void append(const char* format, ...);
   inline void print(const char* format, ...);
   inline void printv(const char* format, va_list ap);
-  operator const char *() const { return _buf; }
 
   char* buffer() { return _buf; }
   int size() { return bufsz; }
 
  private:
   FormatBuffer(const FormatBuffer &); // prevent copies
+  char _buffer[bufsz];
 
  protected:
-  char _buf[bufsz];
-
   inline FormatBuffer();
 };
 
 template <size_t bufsz>
-FormatBuffer<bufsz>::FormatBuffer(const char * format, ...) {
+FormatBuffer<bufsz>::FormatBuffer(const char * format, ...) : FormatBufferBase(_buffer) {
   va_list argp;
   va_start(argp, format);
   jio_vsnprintf(_buf, bufsz, format, argp);
@@ -61,7 +75,7 @@
 }
 
 template <size_t bufsz>
-FormatBuffer<bufsz>::FormatBuffer() {
+FormatBuffer<bufsz>::FormatBuffer() : FormatBufferBase(_buffer) {
   _buf[0] = '\0';
 }
 
@@ -93,6 +107,7 @@
 
 // Used to format messages for assert(), guarantee(), fatal(), etc.
 typedef FormatBuffer<> err_msg;
+typedef FormatBufferResource err_msg_res;
 
 // assertions
 #ifdef ASSERT