alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (exceptions.hpp)

This example Java source code file (exceptions.hpp) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

check_, check_and_clear_, clear_pending_exception, exceptionmark, exceptionmsgtoutf8mode, exceptions\:\:_throw_msg, handle, has_pending_exception, javacallarguments, null, symbol, thread, threadshadow\*, throw_msg_

The exceptions.hpp Java example source code

/*
 * Copyright (c) 1998, 2013, 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
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#ifndef SHARE_VM_UTILITIES_EXCEPTIONS_HPP
#define SHARE_VM_UTILITIES_EXCEPTIONS_HPP

#include "memory/allocation.hpp"
#include "oops/oopsHierarchy.hpp"
#include "utilities/sizes.hpp"

// This file provides the basic support for exception handling in the VM.
// Note: We do not use C++ exceptions to avoid compiler dependencies and
// unpredictable performance.
//
// Scheme: Exceptions are stored with the thread. There is never more
// than one pending exception per thread. All functions that can throw
// an exception carry a THREAD argument (usually the last argument and
// declared with the TRAPS macro). Throwing an exception means setting
// a pending exception in the thread. Upon return from a function that
// can throw an exception, we must check if an exception is pending.
// The CHECK macros do this in a convenient way. Carrying around the
// thread provides also convenient access to it (e.g. for Handle
// creation, w/o the need for recomputation).



// Forward declarations to be independent of the include structure.
// This allows us to have exceptions.hpp included in top.hpp.

class Thread;
class Handle;
class Symbol;
class JavaCallArguments;

// The ThreadShadow class is a helper class to access the _pending_exception
// field of the Thread class w/o having access to the Thread's interface (for
// include hierachy reasons).

class ThreadShadow: public CHeapObj<mtThread> {
  friend class VMStructs;

 protected:
  oop  _pending_exception;                       // Thread has gc actions.
  const char* _exception_file;                   // file information for exception (debugging only)
  int         _exception_line;                   // line information for exception (debugging only)
  friend void check_ThreadShadow();              // checks _pending_exception offset

  // The following virtual exists only to force creation of a vtable.
  // We need ThreadShadow to have a vtable, even in product builds,
  // so that its layout will start at an offset of zero relative to Thread.
  // Some C++ compilers are so "clever" that they put the ThreadShadow
  // base class at offset 4 in Thread (after Thread's vtable), if they
  // notice that Thread has a vtable but ThreadShadow does not.
  virtual void unused_initial_virtual() { }

 public:
  oop  pending_exception() const                 { return _pending_exception; }
  bool has_pending_exception() const             { return _pending_exception != NULL; }
  const char* exception_file() const             { return _exception_file; }
  int  exception_line() const                    { return _exception_line; }

  // Code generation support
  static ByteSize pending_exception_offset()     { return byte_offset_of(ThreadShadow, _pending_exception); }

  // use THROW whenever possible!
  void set_pending_exception(oop exception, const char* file, int line);

  // use CLEAR_PENDING_EXCEPTION whenever possible!
  void clear_pending_exception();

  ThreadShadow() : _pending_exception(NULL),
                   _exception_file(NULL), _exception_line(0) {}
};


// Exceptions is a helper class that encapsulates all operations
// that require access to the thread interface and which are
// relatively rare. The Exceptions operations should only be
// used directly if the macros below are insufficient.

class Exceptions {
  static bool special_exception(Thread *thread, const char* file, int line, Handle exception);
  static bool special_exception(Thread* thread, const char* file, int line, Symbol* name, const char* message);
 public:
  // this enum is defined to indicate whether it is safe to
  // ignore the encoding scheme of the original message string.
  typedef enum {
    safe_to_utf8 = 0,
    unsafe_to_utf8 = 1
  } ExceptionMsgToUtf8Mode;
  // Throw exceptions: w/o message, w/ message & with formatted message.
  static void _throw_oop(Thread* thread, const char* file, int line, oop exception);
  static void _throw(Thread* thread, const char* file, int line, Handle exception, const char* msg = NULL);

  static void _throw_msg(Thread* thread, const char* file, int line, Symbol* name, const char* message);
  static void _throw_msg(Thread* thread, const char* file, int line, Symbol* name, const char* message,
                         Handle loader, Handle protection_domain);

  static void _throw_msg_cause(Thread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause);
  static void _throw_msg_cause(Thread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause,
                               Handle h_loader, Handle h_protection_domain);

  static void _throw_cause(Thread* thread, const char* file, int line, Symbol* name, Handle h_cause);
  static void _throw_cause(Thread* thread, const char* file, int line, Symbol* name, Handle h_cause,
                           Handle h_loader, Handle h_protection_domain);

  static void _throw_args(Thread* thread, const char* file, int line,
                          Symbol* name, Symbol* signature,
                          JavaCallArguments* args);

  // There is no THROW... macro for this method. Caller should remember
  // to do a return after calling it.
  static void fthrow(Thread* thread, const char* file, int line, Symbol* name,
                     const char* format, ...);

  // Create and initialize a new exception
  static Handle new_exception(Thread* thread, Symbol* name,
                              Symbol* signature, JavaCallArguments* args,
                              Handle loader, Handle protection_domain);

  static Handle new_exception(Thread* thread, Symbol* name,
                              Symbol* signature, JavaCallArguments* args,
                              Handle cause,
                              Handle loader, Handle protection_domain);

  static Handle new_exception(Thread* thread, Symbol* name,
                              Handle cause,
                              Handle loader, Handle protection_domain,
                              ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8);

  static Handle new_exception(Thread* thread, Symbol* name,
                              const char* message, Handle cause,
                              Handle loader, Handle protection_domain,
                              ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8);

  static Handle new_exception(Thread* thread, Symbol* name,
                              const char* message,
                              ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8);

  static void throw_stack_overflow_exception(Thread* thread, const char* file, int line, methodHandle method);

  // for AbortVMOnException flag
  NOT_PRODUCT(static void debug_check_abort(Handle exception, const char* message = NULL);)
  NOT_PRODUCT(static void debug_check_abort(const char *value_string, const char* message = NULL);)
};


// The THREAD & TRAPS macros facilitate the declaration of functions that throw exceptions.
// Convention: Use the TRAPS macro as the last argument of such a function; e.g.:
//
// int this_function_may_trap(int x, float y, TRAPS)

#define THREAD __the_thread__
#define TRAPS  Thread* THREAD


// The CHECK... macros should be used to pass along a THREAD reference and to check for pending
// exceptions. In special situations it is necessary to handle pending exceptions explicitly,
// in these cases the PENDING_EXCEPTION helper macros should be used.
//
// Macro naming conventions: Macros that end with _ require a result value to be returned. They
// are for functions with non-void result type. The result value is usually ignored because of
// the exception and is only needed for syntactic correctness. The _0 ending is a shortcut for
// _(0) since this is a frequent case. Example:
//
// int result = this_function_may_trap(x_arg, y_arg, CHECK_0);
//
// CAUTION: make sure that the function call using a CHECK macro is not the only statement of a
// conditional branch w/o enclosing {} braces, since the CHECK macros expand into several state-
// ments!

#define PENDING_EXCEPTION                        (((ThreadShadow*)THREAD)->pending_exception())
#define HAS_PENDING_EXCEPTION                    (((ThreadShadow*)THREAD)->has_pending_exception())
#define CLEAR_PENDING_EXCEPTION                  (((ThreadShadow*)THREAD)->clear_pending_exception())

#define CHECK                                    THREAD); if (HAS_PENDING_EXCEPTION) return       ; (void)(0
#define CHECK_(result)                           THREAD); if (HAS_PENDING_EXCEPTION) return result; (void)(0
#define CHECK_0                                  CHECK_(0)
#define CHECK_NH                                 CHECK_(Handle())
#define CHECK_NULL                               CHECK_(NULL)
#define CHECK_false                              CHECK_(false)

#define CHECK_AND_CLEAR                         THREAD); if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; return;        } (void)(0
#define CHECK_AND_CLEAR_(result)                THREAD); if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; return result; } (void)(0
#define CHECK_AND_CLEAR_0                       CHECK_AND_CLEAR_(0)
#define CHECK_AND_CLEAR_NH                      CHECK_AND_CLEAR_(Handle())
#define CHECK_AND_CLEAR_NULL                    CHECK_AND_CLEAR_(NULL)
#define CHECK_AND_CLEAR_false                   CHECK_AND_CLEAR_(false)

// The THROW... macros should be used to throw an exception. They require a THREAD variable to be
// visible within the scope containing the THROW. Usually this is achieved by declaring the function
// with a TRAPS argument.

#define THREAD_AND_LOCATION                      THREAD, __FILE__, __LINE__

#define THROW_OOP(e)                                \
  { Exceptions::_throw_oop(THREAD_AND_LOCATION, e);                             return;  }

#define THROW_HANDLE(e)                                \
  { Exceptions::_throw(THREAD_AND_LOCATION, e);                             return;  }

#define THROW(name)                                 \
  { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, NULL); return;  }

#define THROW_MSG(name, message)                    \
  { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message); return;  }

#define THROW_CAUSE(name, cause)   \
  { Exceptions::_throw_cause(THREAD_AND_LOCATION, name, cause); return; }

#define THROW_MSG_LOADER(name, message, loader, protection_domain) \
  { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message, loader, protection_domain); return;  }

#define THROW_ARG(name, signature, args) \
  { Exceptions::_throw_args(THREAD_AND_LOCATION, name, signature, args);   return; }

#define THROW_OOP_(e, result)                       \
  { Exceptions::_throw_oop(THREAD_AND_LOCATION, e);                           return result; }

#define THROW_HANDLE_(e, result)                       \
  { Exceptions::_throw(THREAD_AND_LOCATION, e);                           return result; }

#define THROW_(name, result)                        \
  { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, NULL); return result; }

#define THROW_MSG_(name, message, result)           \
  { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message); return result; }

#define THROW_MSG_LOADER_(name, message, loader, protection_domain, result) \
  { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message, loader, protection_domain); return result; }

#define THROW_ARG_(name, signature, args, result) \
  { Exceptions::_throw_args(THREAD_AND_LOCATION, name, signature, args); return result; }

#define THROW_MSG_CAUSE(name, message, cause)   \
  { Exceptions::_throw_msg_cause(THREAD_AND_LOCATION, name, message, cause); return; }

#define THROW_MSG_CAUSE_(name, message, cause, result)   \
  { Exceptions::_throw_msg_cause(THREAD_AND_LOCATION, name, message, cause); return result; }


#define THROW_OOP_0(e)                      THROW_OOP_(e, 0)
#define THROW_HANDLE_0(e)                   THROW_HANDLE_(e, 0)
#define THROW_0(name)                       THROW_(name, 0)
#define THROW_MSG_0(name, message)          THROW_MSG_(name, message, 0)
#define THROW_WRAPPED_0(name, oop_to_wrap)  THROW_WRAPPED_(name, oop_to_wrap, 0)
#define THROW_ARG_0(name, signature, arg)   THROW_ARG_(name, signature, arg, 0)
#define THROW_MSG_CAUSE_0(name, message, cause) THROW_MSG_CAUSE_(name, message, cause, 0)
#define THROW_MSG_CAUSE_NULL(name, message, cause) THROW_MSG_CAUSE_(name, message, cause, NULL)

#define THROW_NULL(name)                    THROW_(name, NULL)
#define THROW_MSG_NULL(name, message)       THROW_MSG_(name, message, NULL)

// The CATCH macro checks that no exception has been thrown by a function; it is used at
// call sites about which is statically known that the callee cannot throw an exception
// even though it is declared with TRAPS.

#define CATCH                              \
  THREAD); if (HAS_PENDING_EXCEPTION) {    \
    oop ex = PENDING_EXCEPTION;            \
    CLEAR_PENDING_EXCEPTION;               \
    ex->print();                           \
    ShouldNotReachHere();                  \
  } (void)(0

// ExceptionMark is a stack-allocated helper class for local exception handling.
// It is used with the EXCEPTION_MARK macro.

class ExceptionMark {
 private:
  Thread* _thread;

 public:
  ExceptionMark(Thread*& thread);
  ~ExceptionMark();
};



// Use an EXCEPTION_MARK for 'local' exceptions. EXCEPTION_MARK makes sure that no
// pending exception exists upon entering its scope and tests that no pending exception
// exists when leaving the scope.

// See also preserveException.hpp for PRESERVE_EXCEPTION_MARK macro,
// which preserves pre-existing exceptions and does not allow new
// exceptions.

#define EXCEPTION_MARK                           Thread* THREAD = NULL; ExceptionMark __em(THREAD);

#endif // SHARE_VM_UTILITIES_EXCEPTIONS_HPP

Other Java examples (source code examples)

Here is a short list of links related to this Java exceptions.hpp source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.