# HG changeset patch # User kvn # Date 1343666965 25200 # Node ID 6c5b7a6becc8f27a4705c5774ee29442368a8353 # Parent 97700709684042ed0882b6abca1331f06b9de833 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 diff -r 977007096840 -r 6c5b7a6becc8 make/solaris/makefiles/fastdebug.make --- 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) diff -r 977007096840 -r 6c5b7a6becc8 src/share/vm/opto/callGenerator.cpp --- 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; diff -r 977007096840 -r 6c5b7a6becc8 src/share/vm/opto/chaitin.cpp --- 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; diff -r 977007096840 -r 6c5b7a6becc8 src/share/vm/opto/compile.cpp --- 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); } diff -r 977007096840 -r 6c5b7a6becc8 src/share/vm/opto/doCall.cpp --- 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); diff -r 977007096840 -r 6c5b7a6becc8 src/share/vm/opto/escape.cpp --- 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). diff -r 977007096840 -r 6c5b7a6becc8 src/share/vm/opto/idealGraphPrinter.cpp --- 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)); } } diff -r 977007096840 -r 6c5b7a6becc8 src/share/vm/opto/node.hpp --- 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 diff -r 977007096840 -r 6c5b7a6becc8 src/share/vm/opto/parse1.cpp --- 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(); diff -r 977007096840 -r 6c5b7a6becc8 src/share/vm/utilities/debug.cpp --- 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) { diff -r 977007096840 -r 6c5b7a6becc8 src/share/vm/utilities/debug.hpp --- 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 // 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 -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 -FormatBuffer::FormatBuffer(const char * format, ...) { +FormatBuffer::FormatBuffer(const char * format, ...) : FormatBufferBase(_buffer) { va_list argp; va_start(argp, format); jio_vsnprintf(_buf, bufsz, format, argp); @@ -61,7 +75,7 @@ } template -FormatBuffer::FormatBuffer() { +FormatBuffer::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