Merge
This commit is contained in:
commit
206c37a5e6
@ -1239,6 +1239,16 @@ oop java_lang_Throwable::message(Handle throwable) {
|
||||
}
|
||||
|
||||
|
||||
// Return Symbol for detailed_message or NULL
|
||||
Symbol* java_lang_Throwable::detail_message(oop throwable) {
|
||||
PRESERVE_EXCEPTION_MARK; // Keep original exception
|
||||
oop detailed_message = java_lang_Throwable::message(throwable);
|
||||
if (detailed_message != NULL) {
|
||||
return java_lang_String::as_symbol(detailed_message, THREAD);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void java_lang_Throwable::set_message(oop throwable, oop value) {
|
||||
throwable->obj_field_put(detailMessage_offset, value);
|
||||
}
|
||||
|
@ -520,6 +520,7 @@ class java_lang_Throwable: AllStatic {
|
||||
static oop message(oop throwable);
|
||||
static oop message(Handle throwable);
|
||||
static void set_message(oop throwable, oop value);
|
||||
static Symbol* detail_message(oop throwable);
|
||||
static void print_stack_element(outputStream *st, Handle mirror, int method,
|
||||
int version, int bci);
|
||||
static void print_stack_element(outputStream *st, methodHandle method, int bci);
|
||||
|
@ -430,9 +430,18 @@ IRT_ENTRY(address, InterpreterRuntime::exception_handler_for_exception(JavaThrea
|
||||
|
||||
// tracing
|
||||
if (TraceExceptions) {
|
||||
ttyLocker ttyl;
|
||||
ResourceMark rm(thread);
|
||||
tty->print_cr("Exception <%s> (" INTPTR_FORMAT ")", h_exception->print_value_string(), (address)h_exception());
|
||||
Symbol* message = java_lang_Throwable::detail_message(h_exception());
|
||||
ttyLocker ttyl; // Lock after getting the detail message
|
||||
if (message != NULL) {
|
||||
tty->print_cr("Exception <%s: %s> (" INTPTR_FORMAT ")",
|
||||
h_exception->print_value_string(), message->as_C_string(),
|
||||
(address)h_exception());
|
||||
} else {
|
||||
tty->print_cr("Exception <%s> (" INTPTR_FORMAT ")",
|
||||
h_exception->print_value_string(),
|
||||
(address)h_exception());
|
||||
}
|
||||
tty->print_cr(" thrown in interpreter method <%s>", h_method->print_value_string());
|
||||
tty->print_cr(" at bci %d for thread " INTPTR_FORMAT, current_bci, thread);
|
||||
}
|
||||
|
@ -244,10 +244,8 @@ void InterpreterOopMap::print() const {
|
||||
method()->print_value();
|
||||
tty->print(" @ %d = [%d] { ", bci(), n);
|
||||
for (int i = 0; i < n; i++) {
|
||||
#ifdef ENABLE_ZAP_DEAD_LOCALS
|
||||
if (is_dead(i)) tty->print("%d+ ", i);
|
||||
else
|
||||
#endif
|
||||
if (is_oop(i)) tty->print("%d ", i);
|
||||
}
|
||||
tty->print_cr("}");
|
||||
@ -402,13 +400,11 @@ void OopMapCacheEntry::set_mask(CellTypeState *vars, CellTypeState *stack, int s
|
||||
value |= (mask << oop_bit_number );
|
||||
}
|
||||
|
||||
#ifdef ENABLE_ZAP_DEAD_LOCALS
|
||||
// set dead bit
|
||||
if (!cell->is_live()) {
|
||||
value |= (mask << dead_bit_number);
|
||||
assert(!cell->is_reference(), "dead value marked as oop");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// make sure last word is stored
|
||||
|
@ -66,19 +66,15 @@ class InterpreterOopMap: ResourceObj {
|
||||
|
||||
public:
|
||||
enum {
|
||||
N = 2, // the number of words reserved
|
||||
N = 4, // the number of words reserved
|
||||
// for inlined mask storage
|
||||
small_mask_limit = N * BitsPerWord, // the maximum number of bits
|
||||
// available for small masks,
|
||||
// small_mask_limit can be set to 0
|
||||
// for testing bit_mask allocation
|
||||
|
||||
#ifdef ENABLE_ZAP_DEAD_LOCALS
|
||||
bits_per_entry = 2,
|
||||
dead_bit_number = 1,
|
||||
#else
|
||||
bits_per_entry = 1,
|
||||
#endif
|
||||
oop_bit_number = 0
|
||||
};
|
||||
|
||||
@ -119,10 +115,6 @@ class InterpreterOopMap: ResourceObj {
|
||||
|
||||
void set_expression_stack_size(int sz) { _expression_stack_size = sz; }
|
||||
|
||||
#ifdef ENABLE_ZAP_DEAD_LOCALS
|
||||
bool is_dead(int offset) const { return (entry_at(offset) & (1 << dead_bit_number)) != 0; }
|
||||
#endif
|
||||
|
||||
// Lookup
|
||||
bool match(methodHandle method, int bci) const { return _method == method() && _bci == bci; }
|
||||
bool is_empty() const;
|
||||
@ -144,6 +136,7 @@ class InterpreterOopMap: ResourceObj {
|
||||
void print() const;
|
||||
|
||||
int number_of_entries() const { return mask_size() / bits_per_entry; }
|
||||
bool is_dead(int offset) const { return (entry_at(offset) & (1 << dead_bit_number)) != 0; }
|
||||
bool is_oop (int offset) const { return (entry_at(offset) & (1 << oop_bit_number )) != 0; }
|
||||
|
||||
int expression_stack_size() const { return _expression_stack_size; }
|
||||
|
@ -520,13 +520,9 @@ bool ConstantPool::resolve_class_constants(TRAPS) {
|
||||
|
||||
Symbol* ConstantPool::exception_message(constantPoolHandle this_cp, int which, constantTag tag, oop pending_exception) {
|
||||
// Dig out the detailed message to reuse if possible
|
||||
Symbol* message = NULL;
|
||||
oop detailed_message = java_lang_Throwable::message(pending_exception);
|
||||
if (detailed_message != NULL) {
|
||||
message = java_lang_String::as_symbol_or_null(detailed_message);
|
||||
if (message != NULL) {
|
||||
return message;
|
||||
}
|
||||
Symbol* message = java_lang_Throwable::detail_message(pending_exception);
|
||||
if (message != NULL) {
|
||||
return message;
|
||||
}
|
||||
|
||||
// Return specific message for the tag
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "interpreter/oopMapCache.hpp"
|
||||
#include "jvmtifiles/jvmtiEnv.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "oops/instanceKlass.hpp"
|
||||
@ -744,6 +745,13 @@ bool VM_GetOrSetLocal::doit_prologue() {
|
||||
}
|
||||
|
||||
void VM_GetOrSetLocal::doit() {
|
||||
InterpreterOopMap oop_mask;
|
||||
_jvf->method()->mask_for(_jvf->bci(), &oop_mask);
|
||||
if (oop_mask.is_dead(_index)) {
|
||||
// The local can be invalid and uninitialized in the scope of current bci
|
||||
_result = JVMTI_ERROR_INVALID_SLOT;
|
||||
return;
|
||||
}
|
||||
if (_set) {
|
||||
// Force deoptimization of frame if compiled because it's
|
||||
// possible the compiler emitted some locals as constant values,
|
||||
|
@ -35,6 +35,18 @@ class Atomic : AllStatic {
|
||||
// can provide an alternative action if not - see supports_cx8() for
|
||||
// a means to test availability.
|
||||
|
||||
// The memory operations that are mentioned with each of the atomic
|
||||
// function families come from src/share/vm/runtime/orderAccess.hpp,
|
||||
// e.g., <fence> is described in that file and is implemented by the
|
||||
// OrderAccess::fence() function. See that file for the gory details
|
||||
// on the Memory Access Ordering Model.
|
||||
|
||||
// All of the atomic operations that imply a read-modify-write action
|
||||
// guarantee a two-way memory barrier across that operation. Historically
|
||||
// these semantics reflect the strength of atomic operations that are
|
||||
// provided on SPARC/X86. We assume that strength is necessary unless
|
||||
// we can prove that a weaker form is sufficiently safe.
|
||||
|
||||
// Atomically store to a location
|
||||
inline static void store (jbyte store_value, jbyte* dest);
|
||||
inline static void store (jshort store_value, jshort* dest);
|
||||
@ -55,7 +67,8 @@ class Atomic : AllStatic {
|
||||
// See comment above about using jlong atomics on 32-bit platforms
|
||||
inline static jlong load(volatile jlong* src);
|
||||
|
||||
// Atomically add to a location, return updated value
|
||||
// Atomically add to a location. Returns updated value. add*() provide:
|
||||
// <fence> add-value-to-dest <membar StoreLoad|StoreStore>
|
||||
inline static jint add (jint add_value, volatile jint* dest);
|
||||
inline static size_t add (size_t add_value, volatile size_t* dest);
|
||||
inline static intptr_t add_ptr(intptr_t add_value, volatile intptr_t* dest);
|
||||
@ -63,30 +76,35 @@ class Atomic : AllStatic {
|
||||
// See comment above about using jlong atomics on 32-bit platforms
|
||||
static jlong add (jlong add_value, volatile jlong* dest);
|
||||
|
||||
// Atomically increment location
|
||||
// Atomically increment location. inc*() provide:
|
||||
// <fence> increment-dest <membar StoreLoad|StoreStore>
|
||||
inline static void inc (volatile jint* dest);
|
||||
static void inc (volatile jshort* dest);
|
||||
inline static void inc (volatile size_t* dest);
|
||||
inline static void inc_ptr(volatile intptr_t* dest);
|
||||
inline static void inc_ptr(volatile void* dest);
|
||||
|
||||
// Atomically decrement a location
|
||||
// Atomically decrement a location. dec*() provide:
|
||||
// <fence> decrement-dest <membar StoreLoad|StoreStore>
|
||||
inline static void dec (volatile jint* dest);
|
||||
static void dec (volatile jshort* dest);
|
||||
inline static void dec (volatile size_t* dest);
|
||||
inline static void dec_ptr(volatile intptr_t* dest);
|
||||
inline static void dec_ptr(volatile void* dest);
|
||||
|
||||
// Performs atomic exchange of *dest with exchange_value. Returns old prior value of *dest.
|
||||
// Performs atomic exchange of *dest with exchange_value. Returns old
|
||||
// prior value of *dest. xchg*() provide:
|
||||
// <fence> exchange-value-with-dest <membar StoreLoad|StoreStore>
|
||||
inline static jint xchg(jint exchange_value, volatile jint* dest);
|
||||
static unsigned int xchg(unsigned int exchange_value, volatile unsigned int* dest);
|
||||
|
||||
inline static intptr_t xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest);
|
||||
inline static void* xchg_ptr(void* exchange_value, volatile void* dest);
|
||||
|
||||
// Performs atomic compare of *dest and compare_value, and exchanges *dest with exchange_value
|
||||
// if the comparison succeeded. Returns prior value of *dest. Guarantees a two-way memory
|
||||
// barrier across the cmpxchg. I.e., it's really a 'fence_cmpxchg_acquire'.
|
||||
// Performs atomic compare of *dest and compare_value, and exchanges
|
||||
// *dest with exchange_value if the comparison succeeded. Returns prior
|
||||
// value of *dest. cmpxchg*() provide:
|
||||
// <fence> compare-and-exchange <membar StoreLoad|StoreStore>
|
||||
static jbyte cmpxchg (jbyte exchange_value, volatile jbyte* dest, jbyte compare_value);
|
||||
inline static jint cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value);
|
||||
// See comment above about using jlong atomics on 32-bit platforms
|
||||
|
48
hotspot/test/runtime/CommandLine/TraceExceptionsTest.java
Normal file
48
hotspot/test/runtime/CommandLine/TraceExceptionsTest.java
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8048933
|
||||
* @summary TraceExceptions output should have the exception message - useful for ClassNotFoundExceptions especially
|
||||
* @library /testlibrary
|
||||
*/
|
||||
|
||||
import com.oracle.java.testlibrary.*;
|
||||
|
||||
public class TraceExceptionsTest {
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
if (!Platform.isDebugBuild()) {
|
||||
System.out.println("Skip the test on product builds since XX:+TraceExceptions is not available on product builds");
|
||||
return;
|
||||
}
|
||||
|
||||
ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
|
||||
"-XX:+TraceExceptions", "NoClassFound");
|
||||
OutputAnalyzer output = new OutputAnalyzer(pb.start());
|
||||
output.shouldContain("<a 'java/lang/ClassNotFoundException': NoClassFound>");
|
||||
output.shouldNotContain("<a 'java/lang/ClassNotFoundException'>");
|
||||
output.shouldHaveExitValue(1);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user