src/share/vm/utilities/exceptions.hpp

Thu, 20 Nov 2008 16:56:09 -0800

author
ysr
date
Thu, 20 Nov 2008 16:56:09 -0800
changeset 888
c96030fff130
parent 435
a61af66fc99e
child 1145
e5b0439ef4ae
permissions
-rw-r--r--

6684579: SoftReference processing can be made more efficient
Summary: For current soft-ref clearing policies, we can decide at marking time if a soft-reference will definitely not be cleared, postponing the decision of whether it will definitely be cleared to the final reference processing phase. This can be especially beneficial in the case of concurrent collectors where the marking is usually concurrent but reference processing is usually not.
Reviewed-by: jmasa

     1 /*
     2  * Copyright 1998-2007 Sun Microsystems, Inc.  All Rights Reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    20  * CA 95054 USA or visit www.sun.com if you need additional information or
    21  * have any questions.
    22  *
    23  */
    25 // This file provides the basic support for exception handling in the VM.
    26 // Note: We do not use C++ exceptions to avoid compiler dependencies and
    27 // unpredictable performance.
    28 //
    29 // Scheme: Exceptions are stored with the thread. There is never more
    30 // than one pending exception per thread. All functions that can throw
    31 // an exception carry a THREAD argument (usually the last argument and
    32 // declared with the TRAPS macro). Throwing an exception means setting
    33 // a pending exception in the thread. Upon return from a function that
    34 // can throw an exception, we must check if an exception is pending.
    35 // The CHECK macros do this in a convenient way. Carrying around the
    36 // thread provides also convenient access to it (e.g. for Handle
    37 // creation, w/o the need for recomputation).
    41 // Forward declarations to be independent of the include structure.
    42 // This allows us to have exceptions.hpp included in top.hpp.
    44 class Thread;
    45 class Handle;
    46 class symbolHandle;
    47 class symbolOopDesc;
    48 class JavaCallArguments;
    50 // The ThreadShadow class is a helper class to access the _pending_exception
    51 // field of the Thread class w/o having access to the Thread's interface (for
    52 // include hierachy reasons).
    54 class ThreadShadow: public CHeapObj {
    55  protected:
    56   oop  _pending_exception;                       // Thread has gc actions.
    57   const char* _exception_file;                   // file information for exception (debugging only)
    58   int         _exception_line;                   // line information for exception (debugging only)
    59   friend void check_ThreadShadow();              // checks _pending_exception offset
    61   // The following virtual exists only to force creation of a vtable.
    62   // We need ThreadShadow to have a vtable, even in product builds,
    63   // so that its layout will start at an offset of zero relative to Thread.
    64   // Some C++ compilers are so "clever" that they put the ThreadShadow
    65   // base class at offset 4 in Thread (after Thread's vtable), if they
    66   // notice that Thread has a vtable but ThreadShadow does not.
    67   virtual void unused_initial_virtual() { }
    69  public:
    70   oop  pending_exception() const                 { return _pending_exception; }
    71   bool has_pending_exception() const             { return _pending_exception != NULL; }
    72   const char* exception_file() const             { return _exception_file; }
    73   int  exception_line() const                    { return _exception_line; }
    75   // Code generation support
    76   static ByteSize pending_exception_offset()     { return byte_offset_of(ThreadShadow, _pending_exception); }
    78   // use THROW whenever possible!
    79   void set_pending_exception(oop exception, const char* file, int line);
    81   // use CLEAR_PENDING_EXCEPTION whenever possible!
    82   void clear_pending_exception();
    84   ThreadShadow() : _pending_exception(NULL),
    85                    _exception_file(NULL), _exception_line(0) {}
    86 };
    89 // Exceptions is a helper class that encapsulates all operations
    90 // that require access to the thread interface and which are
    91 // relatively rare. The Exceptions operations should only be
    92 // used directly if the macros below are insufficient.
    94 class Exceptions {
    95   static bool special_exception(Thread *thread, const char* file, int line, Handle exception);
    96   static bool special_exception(Thread* thread, const char* file, int line, symbolHandle name, const char* message);
    97  public:
    98   // this enum is defined to indicate whether it is safe to
    99   // ignore the encoding scheme of the original message string.
   100   typedef enum {
   101     safe_to_utf8 = 0,
   102     unsafe_to_utf8 = 1
   103   } ExceptionMsgToUtf8Mode;
   104   // Throw exceptions: w/o message, w/ message & with formatted message.
   105   static void _throw_oop(Thread* thread, const char* file, int line, oop exception);
   106   static void _throw(Thread* thread, const char* file, int line, Handle exception);
   107   static void _throw_msg(Thread* thread, const char* file, int line,
   108                          symbolHandle name, const char* message, Handle loader,
   109                          Handle protection_domain);
   110   static void _throw_msg(Thread* thread, const char* file, int line,
   111                          symbolOop name, const char* message);
   112   static void _throw_msg(Thread* thread, const char* file, int line,
   113                          symbolHandle name, const char* message);
   114   static void _throw_args(Thread* thread, const char* file, int line,
   115                           symbolHandle name, symbolHandle signature,
   116                           JavaCallArguments* args);
   117   static void _throw_msg_cause(Thread* thread, const char* file,
   118                          int line, symbolHandle h_name, const char* message,
   119                          Handle h_cause, Handle h_loader, Handle h_protection_domain);
   120   static void _throw_msg_cause(Thread* thread, const char* file, int line,
   121                             symbolHandle name, const char* message, Handle cause);
   123   // There is no THROW... macro for this method. Caller should remember
   124   // to do a return after calling it.
   125   static void fthrow(Thread* thread, const char* file, int line, symbolHandle name,
   126                      const char* format, ...);
   128   // Create and initialize a new exception
   129   static Handle new_exception(Thread* thread, symbolHandle name,
   130                               symbolHandle signature, JavaCallArguments* args,
   131                               Handle cause, Handle loader,
   132                               Handle protection_domain);
   134   static Handle new_exception(Thread* thread, symbolHandle name,
   135                               const char* message, Handle cause, Handle loader,
   136                               Handle protection_domain,
   137                               ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8);
   139  static Handle new_exception(Thread* thread, symbolOop name,
   140                              const char* message,
   141                              ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8);
   143   static void throw_stack_overflow_exception(Thread* thread, const char* file, int line);
   145   // for AbortVMOnException flag
   146   NOT_PRODUCT(static void debug_check_abort(Handle exception);)
   147   NOT_PRODUCT(static void debug_check_abort(const char *value_string);)
   148 };
   151 // The THREAD & TRAPS macros facilitate the declaration of functions that throw exceptions.
   152 // Convention: Use the TRAPS macro as the last argument of such a function; e.g.:
   153 //
   154 // int this_function_may_trap(int x, float y, TRAPS)
   156 #define THREAD __the_thread__
   157 #define TRAPS  Thread* THREAD
   160 // The CHECK... macros should be used to pass along a THREAD reference and to check for pending
   161 // exceptions. In special situations it is necessary to handle pending exceptions explicitly,
   162 // in these cases the PENDING_EXCEPTION helper macros should be used.
   163 //
   164 // Macro naming conventions: Macros that end with _ require a result value to be returned. They
   165 // are for functions with non-void result type. The result value is usually ignored because of
   166 // the exception and is only needed for syntactic correctness. The _0 ending is a shortcut for
   167 // _(0) since this is a frequent case. Example:
   168 //
   169 // int result = this_function_may_trap(x_arg, y_arg, CHECK_0);
   170 //
   171 // CAUTION: make sure that the function call using a CHECK macro is not the only statement of a
   172 // conditional branch w/o enclosing {} braces, since the CHECK macros expand into several state-
   173 // ments!
   175 #define PENDING_EXCEPTION                        (((ThreadShadow*)THREAD)->pending_exception())
   176 #define HAS_PENDING_EXCEPTION                    (((ThreadShadow*)THREAD)->has_pending_exception())
   177 #define CLEAR_PENDING_EXCEPTION                  (((ThreadShadow*)THREAD)->clear_pending_exception())
   179 #define CHECK                                    THREAD); if (HAS_PENDING_EXCEPTION) return       ; (0
   180 #define CHECK_(result)                           THREAD); if (HAS_PENDING_EXCEPTION) return result; (0
   181 #define CHECK_0                                  CHECK_(0)
   182 #define CHECK_NH                                 CHECK_(Handle())
   183 #define CHECK_NULL                               CHECK_(NULL)
   184 #define CHECK_false                              CHECK_(false)
   186 // The THROW... macros should be used to throw an exception. They require a THREAD variable to be
   187 // visible within the scope containing the THROW. Usually this is achieved by declaring the function
   188 // with a TRAPS argument.
   190 #define THREAD_AND_LOCATION                      THREAD, __FILE__, __LINE__
   192 #define THROW_OOP(e)                                \
   193   { Exceptions::_throw_oop(THREAD_AND_LOCATION, e);                             return;  }
   195 #define THROW_HANDLE(e)                                \
   196   { Exceptions::_throw(THREAD_AND_LOCATION, e);                             return;  }
   198 #define THROW(name)                                 \
   199   { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, NULL); return;  }
   201 #define THROW_MSG(name, message)                    \
   202   { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message); return;  }
   204 #define THROW_MSG_LOADER(name, message, loader, protection_domain) \
   205   { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message, loader, protection_domain); return;  }
   207 #define THROW_ARG(name, signature, args) \
   208   { Exceptions::_throw_args(THREAD_AND_LOCATION, name, signature, args);   return; }
   210 #define THROW_OOP_(e, result)                       \
   211   { Exceptions::_throw_oop(THREAD_AND_LOCATION, e);                           return result; }
   213 #define THROW_HANDLE_(e, result)                       \
   214   { Exceptions::_throw(THREAD_AND_LOCATION, e);                           return result; }
   216 #define THROW_(name, result)                        \
   217   { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, NULL); return result; }
   219 #define THROW_MSG_(name, message, result)           \
   220   { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message); return result; }
   222 #define THROW_MSG_LOADER_(name, message, loader, protection_domain, result) \
   223   { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message, loader, protection_domain); return result; }
   225 #define THROW_ARG_(name, signature, args, result) \
   226   { Exceptions::_throw_args(THREAD_AND_LOCATION, name, signature, args); return result; }
   228 #define THROW_MSG_CAUSE_(name, message, cause, result)   \
   229   { Exceptions::_throw_msg_cause(THREAD_AND_LOCATION, name, message, cause); return result; }
   232 #define THROW_OOP_0(e)                      THROW_OOP_(e, 0)
   233 #define THROW_HANDLE_0(e)                   THROW_HANDLE_(e, 0)
   234 #define THROW_0(name)                       THROW_(name, 0)
   235 #define THROW_MSG_0(name, message)          THROW_MSG_(name, message, 0)
   236 #define THROW_WRAPPED_0(name, oop_to_wrap)  THROW_WRAPPED_(name, oop_to_wrap, 0)
   237 #define THROW_ARG_0(name, signature, arg)   THROW_ARG_(name, signature, arg, 0)
   238 #define THROW_MSG_CAUSE_0(name, message, cause) THROW_MSG_CAUSE_(name, message, cause, 0)
   240 // The CATCH macro checks that no exception has been thrown by a function; it is used at
   241 // call sites about which is statically known that the callee cannot throw an exception
   242 // even though it is declared with TRAPS.
   244 #define CATCH                              \
   245   THREAD); if (HAS_PENDING_EXCEPTION) {    \
   246     oop ex = PENDING_EXCEPTION;            \
   247     CLEAR_PENDING_EXCEPTION;               \
   248     ex->print();                           \
   249     ShouldNotReachHere();                  \
   250   } (0
   253 // ExceptionMark is a stack-allocated helper class for local exception handling.
   254 // It is used with the EXCEPTION_MARK macro.
   256 class ExceptionMark {
   257  private:
   258   Thread* _thread;
   260  public:
   261   ExceptionMark(Thread*& thread);
   262   ~ExceptionMark();
   263 };
   267 // Use an EXCEPTION_MARK for 'local' exceptions. EXCEPTION_MARK makes sure that no
   268 // pending exception exists upon entering its scope and tests that no pending exception
   269 // exists when leaving the scope.
   271 // See also preserveException.hpp for PRESERVE_EXCEPTION_MARK macro,
   272 // which preserves pre-existing exceptions and does not allow new
   273 // exceptions.
   275 #define EXCEPTION_MARK                           Thread* THREAD; ExceptionMark __em(THREAD);

mercurial