--- a/hotspot/src/os/linux/vm/os_linux.cpp Tue Apr 29 15:17:27 2014 +0200
+++ b/hotspot/src/os/linux/vm/os_linux.cpp Thu May 08 15:08:45 2014 -0700
@@ -5272,7 +5272,6 @@
//
static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
- static bool proc_task_unchecked = true;
pid_t tid = thread->osthread()->thread_id();
char *s;
char stat[2048];
@@ -5285,24 +5284,7 @@
long ldummy;
FILE *fp;
- snprintf(proc_name, 64, "/proc/%d/stat", tid);
-
- // The /proc/<tid>/stat aggregates per-process usage on
- // new Linux kernels 2.6+ where NPTL is supported.
- // The /proc/self/task/<tid>/stat still has the per-thread usage.
- // See bug 6328462.
- // There possibly can be cases where there is no directory
- // /proc/self/task, so we check its availability.
- if (proc_task_unchecked && os::Linux::is_NPTL()) {
- // This is executed only once
- proc_task_unchecked = false;
- fp = fopen("/proc/self/task", "r");
- if (fp != NULL) {
- snprintf(proc_name, 64, "/proc/self/task/%d/stat", tid);
- fclose(fp);
- }
- }
-
+ snprintf(proc_name, 64, "/proc/self/task/%d/stat", tid);
fp = fopen(proc_name, "r");
if ( fp == NULL ) return -1;
statlen = fread(stat, 1, 2047, fp);
--- a/hotspot/src/share/vm/adlc/filebuff.cpp Tue Apr 29 15:17:27 2014 +0200
+++ b/hotspot/src/share/vm/adlc/filebuff.cpp Thu May 08 15:08:45 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -89,200 +89,6 @@
return retval;
}
-//------------------------------FileBuffRegion---------------------------------
-// Create a new region in a FileBuff.
-FileBuffRegion::FileBuffRegion( FileBuff* bufr, int soln, int ln,
- int off, int len)
-: _bfr(bufr), _sol(soln), _line(ln), _offset(off), _length(len) {
- _next = NULL; // No chained regions
-}
-
-//------------------------------~FileBuffRegion--------------------------------
-// Delete the entire linked list of buffer regions.
-FileBuffRegion::~FileBuffRegion() {
- if( _next ) delete _next;
-}
-
-//------------------------------copy-------------------------------------------
-// Deep copy a FileBuffRegion
-FileBuffRegion *FileBuffRegion::copy() {
- if( !this ) return NULL; // The empty buffer region
- FileBuffRegion *br = new FileBuffRegion(_bfr,_sol,_line,_offset,_length);
- if( _next ) br->_next = _next->copy();
- return br;
-}
-
-//------------------------------merge------------------------------------------
-// Merge another buffer region into this buffer region. Make overlapping areas
-// become a single region. Remove (delete) the input FileBuffRegion.
-// Since the buffer regions are sorted by file offset, this is a varient of a
-// "sorted-merge" running in linear time.
-FileBuffRegion *FileBuffRegion::merge( FileBuffRegion *br ) {
- if( !br ) return this; // Merging nothing
- if( !this ) return br; // Merging into nothing
-
- assert( _bfr == br->_bfr, "" ); // Check for pointer-equivalent buffers
-
- if( _offset < br->_offset ) { // "this" starts before "br"
- if( _offset+_length < br->_offset ) { // "this" ends before "br"
- if( _next ) _next->merge( br ); // Merge with remainder of list
- else _next = br; // No more in this list; just append.
- } else { // Regions overlap.
- int l = br->_offset + br->_length - _offset;
- if( l > _length ) _length = l; // Pick larger region
- FileBuffRegion *nr = br->_next; // Get rest of region
- br->_next = NULL; // Remove indication of rest of region
- delete br; // Delete this region (it's been subsumed).
- if( nr ) merge( nr ); // Merge with rest of region
- } // End of if regions overlap or not.
- } else { // "this" starts after "br"
- if( br->_offset+br->_length < _offset ) { // "br" ends before "this"
- FileBuffRegion *nr = new FileBuffRegion(_bfr,_sol,_line,_offset,_length);
- nr->_next = _next; // Structure copy "this" guy to "nr"
- *this = *br; // Structure copy "br" over "this".
- br->_next = NULL; // Remove indication of rest of region
- delete br; // Delete this region (it's been copied)
- merge( nr ); // Finish merging
- } else { // Regions overlap.
- int l = _offset + _length - br->_offset;
- if( l > _length ) _length = l; // Pick larger region
- _offset = br->_offset; // Start with earlier region
- _sol = br->_sol; // Also use earlier line start
- _line = br->_line; // Also use earlier line
- FileBuffRegion *nr = br->_next; // Get rest of region
- br->_next = NULL; // Remove indication of rest of region
- delete br; // Delete this region (it's been subsumed).
- if( nr ) merge( nr ); // Merge with rest of region
- } // End of if regions overlap or not.
- }
- return this;
-}
-
-//------------------------------expandtab--------------------------------------
-static int expandtab( ostream &os, int off, char c, char fill1, char fill2 ) {
- if( c == '\t' ) { // Tab?
- do os << fill1; // Expand the tab; Output space
- while( (++off) & 7 ); // Expand to tab stop
- } else { // Normal character
- os << fill2; // Display normal character
- off++; // Increment "cursor" offset
- }
- return off;
-}
-
-//------------------------------printline--------------------------------------
-// Print and highlite a region of a line. Return the amount of highliting left
-// to do (i.e. highlite length minus length of line).
-static int printline( ostream& os, const char *fname, int line,
- const char *_sol, int skip, int len ) {
-
- // Display the entire tab-expanded line
- os << fname << ":" << line << ": ";
- const char *t = strchr(_sol,'\n')+1; // End of line
- int off = 0; // Cursor offset for tab expansion
- const char *s = _sol; // Nice string pointer
- while( t-s ) { // Display whole line
- char c = *s++; // Get next character to display
- off = expandtab(os,off,c,' ',c);
- }
-
- // Display the tab-expanded skippings before underlining.
- os << fname << ":" << line << ": ";
- off = 0; // Cursor offset for tab expansion
- s = _sol; // Restart string pointer
-
- // Start underlining.
- if( skip != -1 ) { // The no-start-indicating flag
- const char *u = _sol+skip; // Amount to skip
- while( u-s ) // Display skipped part
- off = expandtab(os,off,*s++,' ',' ');
- os << '^'; // Start region
- off++; // Moved cursor
- len--; // 1 less char to do
- if( *s++ == '\t' ) // Starting character is a tab?
- off = expandtab(os,off,'\t','-','^');
- }
-
- // Long region doesn't end on this line
- int llen = (int)(t-s); // Length of line, minus what's already done
- if( len > llen ) { // Doing entire rest of line?
- while( t-s ) // Display rest of line
- off = expandtab(os,off,*s++,'-','-');
- os << '\n'; // EOL
- return len-llen; // Return what's not yet done.
- }
-
- // Region does end on this line. This code fails subtly if the region ends
- // in a tab character.
- int i;
- for( i=1; i<len; i++ ) // Underline just what's needed
- off = expandtab(os,off,*s++,'-','-');
- if( i == len ) os << '^'; // Mark end of region
- os << '\n'; // End of marked line
- return 0; // All done
-}
-
-//------------------------------print------------------------------------------
-//std::ostream& operator<< ( std::ostream& os, FileBuffRegion &br ) {
-ostream& operator<< ( ostream& os, FileBuffRegion &br ) {
- if( &br == NULL ) return os; // The empty buffer region
- FileBuffRegion *brp = &br; // Pointer to region
- while( brp ) { // While have chained regions
- brp->print(os); // Print region
- brp = brp->_next; // Chain to next
- }
- return os; // Return final stream
-}
-
-//------------------------------print------------------------------------------
-// Print the FileBuffRegion to a stream. FileBuffRegions are printed with the
-// filename and line number to the left, and complete text lines to the right.
-// Selected portions (portions of a line actually in the FileBuffRegion are
-// underlined. Ellipses are used for long multi-line regions.
-//void FileBuffRegion::print( std::ostream& os ) {
-void FileBuffRegion::print( ostream& os ) {
- if( !this ) return; // Nothing to print
- char *s = _bfr->get_line();
- int skip = (int)(_offset - _sol); // Amount to skip to start of data
- int len = printline( os, _bfr->_fp->_name, _line, s, skip, _length );
-
- if( !len ) return; // All done; exit
-
- // Here we require at least 2 lines
- int off1 = _length - len + skip; // Length of line 1
- int off2 = off1 + _sol; // Offset to start of line 2
- char *s2 = _bfr->get_line(); // Start of line 2
- char *s3 = strchr( s2, '\n' )+1; // Start of line 3 (unread)
- if( len <= (s3-s2) ) { // It all fits on the next line
- printline( os, _bfr->_fp->_name, _line+1, s2, -1, len ); // Print&underline
- return;
- }
-
- // Here we require at least 3 lines
- int off3 = off2 + (int)(s3-s2); // Offset to start of line 3
- s3 = _bfr->get_line(); // Start of line 3 (read)
- const char *s4 = strchr( s3, '\n' )+1;// Start of line 4 (unread)
- if( len < (s4-s3) ) { // It all fits on the next 2 lines
- s2 = _bfr->get_line();
- len = printline( os, _bfr->_fp->_name, _line+1, s2, -1, len ); // Line 2
- s3 = _bfr->get_line();
- printline( os, _bfr->_fp->_name, _line+2, s3, -1, len ); // Line 3
- return;
- }
-
- // Here we require at least 4 lines.
- // Print only the 1st and last line, with ellipses in middle.
- os << "...\n"; // The ellipses
- int cline = _line+1; // Skipped 2 lines
- do { // Do until find last line
- len -= (int)(s3-s2); // Remove length of line
- cline++; // Next line
- s2 = _bfr->get_line(); // Get next line from end of this line
- s3 = strchr( s2, '\n' ) + 1;// Get end of next line
- } while( len > (s3-s2) ); // Repeat until last line
- printline( os, _bfr->_fp->_name, cline, s2, -1, len ); // Print & underline
-}
-
//------------------------------file_error-------------------------------------
void FileBuff::file_error(int flag, int linenum, const char *fmt, ...)
{
--- a/hotspot/src/share/vm/adlc/filebuff.hpp Tue Apr 29 15:17:27 2014 +0200
+++ b/hotspot/src/share/vm/adlc/filebuff.hpp Thu May 08 15:08:45 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -46,7 +46,6 @@
// This class defines a nicely behaved buffer of text. Entire file of text
// is read into buffer at creation, with sentinels at start and end.
class FileBuff {
- friend class FileBuffRegion;
private:
long _bufferSize; // Size of text holding buffer.
long _offset; // Expected filepointer offset.
@@ -82,29 +81,4 @@
// when the pointer is valid (i.e. just obtained from getline()).
long getoff(const char* s) { return _bufoff + (long)(s - _buf); }
};
-
-//------------------------------FileBuffRegion---------------------------------
-// A buffer region is really a region of some file, specified as a linked list
-// of offsets and lengths. These regions can be merged; overlapping regions
-// will coalesce.
-class FileBuffRegion {
- public: // Workaround dev-studio friend/private bug
- FileBuffRegion *_next; // Linked list of regions sorted by offset.
- private:
- FileBuff *_bfr; // The Buffer of the file
- int _offset, _length; // The file area
- int _sol; // Start of line where the file area starts
- int _line; // First line of region
-
- public:
- FileBuffRegion(FileBuff*, int sol, int line, int offset, int len);
- ~FileBuffRegion();
-
- FileBuffRegion *copy(); // Deep copy
- FileBuffRegion *merge(FileBuffRegion*); // Merge 2 regions; delete input
-
- void print(ostream&);
- friend ostream& operator<< (ostream&, FileBuffRegion&);
-};
-
#endif // SHARE_VM_ADLC_FILEBUFF_HPP
--- a/hotspot/src/share/vm/classfile/resolutionErrors.cpp Tue Apr 29 15:17:27 2014 +0200
+++ b/hotspot/src/share/vm/classfile/resolutionErrors.cpp Thu May 08 15:08:45 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -32,12 +32,13 @@
// add new entry to the table
void ResolutionErrorTable::add_entry(int index, unsigned int hash,
- constantPoolHandle pool, int cp_index, Symbol* error)
+ constantPoolHandle pool, int cp_index,
+ Symbol* error, Symbol* message)
{
assert_locked_or_safepoint(SystemDictionary_lock);
assert(!pool.is_null() && error != NULL, "adding NULL obj");
- ResolutionErrorEntry* entry = new_entry(hash, pool(), cp_index, error);
+ ResolutionErrorEntry* entry = new_entry(hash, pool(), cp_index, error, message);
add_entry(index, entry);
}
@@ -58,19 +59,26 @@
}
void ResolutionErrorEntry::set_error(Symbol* e) {
- assert(e == NULL || _error == NULL, "cannot reset error");
+ assert(e != NULL, "must set a value");
_error = e;
- if (_error != NULL) _error->increment_refcount();
+ _error->increment_refcount();
+}
+
+void ResolutionErrorEntry::set_message(Symbol* c) {
+ assert(c != NULL, "must set a value");
+ _message = c;
+ _message->increment_refcount();
}
// create new error entry
ResolutionErrorEntry* ResolutionErrorTable::new_entry(int hash, ConstantPool* pool,
- int cp_index, Symbol* error)
+ int cp_index, Symbol* error,
+ Symbol* message)
{
ResolutionErrorEntry* entry = (ResolutionErrorEntry*)Hashtable<ConstantPool*, mtClass>::new_entry(hash, pool);
entry->set_cp_index(cp_index);
- NOT_PRODUCT(entry->set_error(NULL);)
entry->set_error(error);
+ entry->set_message(message);
return entry;
}
@@ -79,6 +87,7 @@
// decrement error refcount
assert(entry->error() != NULL, "error should be set");
entry->error()->decrement_refcount();
+ entry->message()->decrement_refcount();
Hashtable<ConstantPool*, mtClass>::free_entry(entry);
}
--- a/hotspot/src/share/vm/classfile/resolutionErrors.hpp Tue Apr 29 15:17:27 2014 +0200
+++ b/hotspot/src/share/vm/classfile/resolutionErrors.hpp Thu May 08 15:08:45 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -38,7 +38,8 @@
public:
ResolutionErrorTable(int table_size);
- ResolutionErrorEntry* new_entry(int hash, ConstantPool* pool, int cp_index, Symbol* error);
+ ResolutionErrorEntry* new_entry(int hash, ConstantPool* pool, int cp_index,
+ Symbol* error, Symbol* message);
void free_entry(ResolutionErrorEntry *entry);
ResolutionErrorEntry* bucket(int i) {
@@ -55,7 +56,7 @@
}
void add_entry(int index, unsigned int hash,
- constantPoolHandle pool, int which, Symbol* error);
+ constantPoolHandle pool, int which, Symbol* error, Symbol* message);
// find error given the constant pool and constant pool index
@@ -79,10 +80,10 @@
private:
int _cp_index;
Symbol* _error;
+ Symbol* _message;
public:
- ConstantPool* pool() const { return (ConstantPool*)literal(); }
- ConstantPool** pool_addr() { return (ConstantPool**)literal_addr(); }
+ ConstantPool* pool() const { return literal(); }
int cp_index() const { return _cp_index; }
void set_cp_index(int cp_index) { _cp_index = cp_index; }
@@ -90,6 +91,9 @@
Symbol* error() const { return _error; }
void set_error(Symbol* e);
+ Symbol* message() const { return _message; }
+ void set_message(Symbol* c);
+
ResolutionErrorEntry* next() const {
return (ResolutionErrorEntry*)HashtableEntry<ConstantPool*, mtClass>::next();
}
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Tue Apr 29 15:17:27 2014 +0200
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp Thu May 08 15:08:45 2014 -0700
@@ -173,12 +173,14 @@
if (HAS_PENDING_EXCEPTION || klass == NULL) {
KlassHandle k_h(THREAD, klass);
// can return a null klass
- klass = handle_resolution_exception(class_name, class_loader, protection_domain, throw_error, k_h, THREAD);
+ klass = handle_resolution_exception(class_name, throw_error, k_h, THREAD);
}
return klass;
}
-Klass* SystemDictionary::handle_resolution_exception(Symbol* class_name, Handle class_loader, Handle protection_domain, bool throw_error, KlassHandle klass_h, TRAPS) {
+Klass* SystemDictionary::handle_resolution_exception(Symbol* class_name,
+ bool throw_error,
+ KlassHandle klass_h, TRAPS) {
if (HAS_PENDING_EXCEPTION) {
// If we have a pending exception we forward it to the caller, unless throw_error is true,
// in which case we have to check whether the pending exception is a ClassNotFoundException,
@@ -386,7 +388,7 @@
}
if (HAS_PENDING_EXCEPTION || superk_h() == NULL) {
// can null superk
- superk_h = KlassHandle(THREAD, handle_resolution_exception(class_name, class_loader, protection_domain, true, superk_h, THREAD));
+ superk_h = KlassHandle(THREAD, handle_resolution_exception(class_name, true, superk_h, THREAD));
}
return superk_h();
@@ -2112,12 +2114,13 @@
// Add entry to resolution error table to record the error when the first
// attempt to resolve a reference to a class has failed.
-void SystemDictionary::add_resolution_error(constantPoolHandle pool, int which, Symbol* error) {
+void SystemDictionary::add_resolution_error(constantPoolHandle pool, int which,
+ Symbol* error, Symbol* message) {
unsigned int hash = resolution_errors()->compute_hash(pool, which);
int index = resolution_errors()->hash_to_index(hash);
{
MutexLocker ml(SystemDictionary_lock, Thread::current());
- resolution_errors()->add_entry(index, hash, pool, which, error);
+ resolution_errors()->add_entry(index, hash, pool, which, error, message);
}
}
@@ -2127,13 +2130,19 @@
}
// Lookup resolution error table. Returns error if found, otherwise NULL.
-Symbol* SystemDictionary::find_resolution_error(constantPoolHandle pool, int which) {
+Symbol* SystemDictionary::find_resolution_error(constantPoolHandle pool, int which,
+ Symbol** message) {
unsigned int hash = resolution_errors()->compute_hash(pool, which);
int index = resolution_errors()->hash_to_index(hash);
{
MutexLocker ml(SystemDictionary_lock, Thread::current());
ResolutionErrorEntry* entry = resolution_errors()->find_entry(index, hash, pool, which);
- return (entry != NULL) ? entry->error() : (Symbol*)NULL;
+ if (entry != NULL) {
+ *message = entry->message();
+ return entry->error();
+ } else {
+ return NULL;
+ }
}
}
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp Tue Apr 29 15:17:27 2014 +0200
+++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp Thu May 08 15:08:45 2014 -0700
@@ -227,7 +227,7 @@
static Klass* resolve_or_fail(Symbol* class_name, bool throw_error, TRAPS);
private:
// handle error translation for resolve_or_null results
- static Klass* handle_resolution_exception(Symbol* class_name, Handle class_loader, Handle protection_domain, bool throw_error, KlassHandle klass_h, TRAPS);
+ static Klass* handle_resolution_exception(Symbol* class_name, bool throw_error, KlassHandle klass_h, TRAPS);
public:
@@ -529,9 +529,11 @@
// Record the error when the first attempt to resolve a reference from a constant
// pool entry to a class fails.
- static void add_resolution_error(constantPoolHandle pool, int which, Symbol* error);
+ static void add_resolution_error(constantPoolHandle pool, int which, Symbol* error,
+ Symbol* message);
static void delete_resolution_error(ConstantPool* pool);
- static Symbol* find_resolution_error(constantPoolHandle pool, int which);
+ static Symbol* find_resolution_error(constantPoolHandle pool, int which,
+ Symbol** message);
private:
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp Tue Apr 29 15:17:27 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp Thu May 08 15:08:45 2014 -0700
@@ -223,12 +223,6 @@
}
}
-void ConcurrentMarkSweepThread::print_on(outputStream* st) const {
- st->print("\"%s\" ", name());
- Thread::print_on(st);
- st->cr();
-}
-
void ConcurrentMarkSweepThread::print_all_on(outputStream* st) {
if (_cmst != NULL) {
_cmst->print_on(st);
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp Tue Apr 29 15:17:27 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp Thu May 08 15:08:45 2014 -0700
@@ -94,8 +94,6 @@
static void threads_do(ThreadClosure* tc);
// Printing
- void print_on(outputStream* st) const;
- void print() const { print_on(tty); }
static void print_all_on(outputStream* st);
static void print_all() { print_all_on(tty); }
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp Tue Apr 29 15:17:27 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.cpp Thu May 08 15:08:45 2014 -0700
@@ -58,6 +58,9 @@
}
initialize();
create_and_start();
+
+ // set name
+ set_name("G1 Concurrent Refinement Thread#%d", worker_id);
}
void ConcurrentG1RefineThread::initialize() {
@@ -247,12 +250,3 @@
}
}
-void ConcurrentG1RefineThread::print() const {
- print_on(tty);
-}
-
-void ConcurrentG1RefineThread::print_on(outputStream* st) const {
- st->print("\"G1 Concurrent Refinement Thread#%d\" ", _worker_id);
- Thread::print_on(st);
- st->cr();
-}
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp Tue Apr 29 15:17:27 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1RefineThread.hpp Thu May 08 15:08:45 2014 -0700
@@ -77,10 +77,6 @@
void initialize();
- // Printing
- void print() const;
- void print_on(outputStream* st) const;
-
// Total virtual time so far.
double vtime_accum() { return _vtime_accum; }
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Tue Apr 29 15:17:27 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp Thu May 08 15:08:45 2014 -0700
@@ -46,6 +46,8 @@
_in_progress(false),
_vtime_accum(0.0),
_vtime_mark_accum(0.0) {
+
+ set_name("G1 Main Concurrent Mark GC Thread");
create_and_start();
}
@@ -322,16 +324,6 @@
}
}
-void ConcurrentMarkThread::print() const {
- print_on(tty);
-}
-
-void ConcurrentMarkThread::print_on(outputStream* st) const {
- st->print("\"G1 Main Concurrent Mark GC Thread\" ");
- Thread::print_on(st);
- st->cr();
-}
-
void ConcurrentMarkThread::sleepBeforeNextCycle() {
// We join here because we don't want to do the "shouldConcurrentMark()"
// below while the world is otherwise stopped.
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.hpp Tue Apr 29 15:17:27 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.hpp Thu May 08 15:08:45 2014 -0700
@@ -60,10 +60,6 @@
static void makeSurrogateLockerThread(TRAPS);
static SurrogateLockerThread* slt() { return _slt; }
- // Printing
- void print_on(outputStream* st) const;
- void print() const;
-
// Total virtual time so far.
double vtime_accum();
// Marking virtual time so far
--- a/hotspot/src/share/vm/gc_implementation/g1/g1StringDedupThread.cpp Tue Apr 29 15:17:27 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1StringDedupThread.cpp Thu May 08 15:08:45 2014 -0700
@@ -53,12 +53,6 @@
return _thread;
}
-void G1StringDedupThread::print_on(outputStream* st) const {
- st->print("\"%s\" ", name());
- Thread::print_on(st);
- st->cr();
-}
-
void G1StringDedupThread::run() {
G1StringDedupStat total_stat;
--- a/hotspot/src/share/vm/gc_implementation/g1/g1StringDedupThread.hpp Tue Apr 29 15:17:27 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1StringDedupThread.hpp Thu May 08 15:08:45 2014 -0700
@@ -52,7 +52,6 @@
static G1StringDedupThread* thread();
virtual void run();
- virtual void print_on(outputStream* st) const;
};
#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1STRINGDEDUPTHREAD_HPP
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp Tue Apr 29 15:17:27 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp Thu May 08 15:08:45 2014 -0700
@@ -87,12 +87,6 @@
_time_stamp_index = 0;
}
-void GCTaskThread::print_on(outputStream* st) const {
- st->print("\"%s\" ", name());
- Thread::print_on(st);
- st->cr();
-}
-
// GC workers get tasks from the GCTaskManager and execute
// them in this method. If there are no tasks to execute,
// the GC workers wait in the GCTaskManager's get_task()
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.hpp Tue Apr 29 15:17:27 2014 +0200
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.hpp Thu May 08 15:08:45 2014 -0700
@@ -69,8 +69,6 @@
void start();
void print_task_time_stamps();
- void print_on(outputStream* st) const;
- void print() const { print_on(tty); }
protected:
// Constructor. Clients use factory, but there could be subclasses.
--- a/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp Tue Apr 29 15:17:27 2014 +0200
+++ b/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp Thu May 08 15:08:45 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 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
@@ -120,7 +120,7 @@
// chunk.
TreeList<FreeChunk, ::AdaptiveFreeList<FreeChunk> >* curTL = this;
- if (surplus() <= 0) {
+ if (curTL->surplus() <= 0) {
/* Use the hint to find a size with a surplus, and reset the hint. */
TreeList<FreeChunk, ::AdaptiveFreeList<FreeChunk> >* hintTL = this;
while (hintTL->hint() != 0) {
--- a/hotspot/src/share/vm/oops/constantPool.cpp Tue Apr 29 15:17:27 2014 +0200
+++ b/hotspot/src/share/vm/oops/constantPool.cpp Thu May 08 15:08:45 2014 -0700
@@ -223,14 +223,14 @@
// The original attempt to resolve this constant pool entry failed so find the
- // original error and throw it again (JVMS 5.4.3).
+ // class of the original error and throw another error of the same class (JVMS 5.4.3).
+ // If there is a detail message, pass that detail message to the error constructor.
+ // The JVMS does not strictly require us to duplicate the same detail message,
+ // or any internal exception fields such as cause or stacktrace. But since the
+ // detail message is often a class name or other literal string, we will repeat it if
+ // we can find it in the symbol table.
if (in_error) {
- Symbol* error = SystemDictionary::find_resolution_error(this_cp, which);
- guarantee(error != (Symbol*)NULL, "tag mismatch with resolution error table");
- ResourceMark rm;
- // exception text will be the class name
- const char* className = this_cp->unresolved_klass_at(which)->as_C_string();
- THROW_MSG_0(error, className);
+ throw_resolution_error(this_cp, which, CHECK_0);
}
if (do_resolve) {
@@ -250,11 +250,6 @@
// Failed to resolve class. We must record the errors so that subsequent attempts
// to resolve this constant pool entry fail with the same error (JVMS 5.4.3).
if (HAS_PENDING_EXCEPTION) {
- ResourceMark rm;
- Symbol* error = PENDING_EXCEPTION->klass()->name();
-
- bool throw_orig_error = false;
- {
MonitorLockerEx ml(this_cp->lock());
// some other thread has beaten us and has resolved the class.
@@ -264,32 +259,9 @@
return entry.get_klass();
}
- if (!PENDING_EXCEPTION->
- is_a(SystemDictionary::LinkageError_klass())) {
- // Just throw the exception and don't prevent these classes from
- // being loaded due to virtual machine errors like StackOverflow
- // and OutOfMemoryError, etc, or if the thread was hit by stop()
- // Needs clarification to section 5.4.3 of the VM spec (see 6308271)
- }
- else if (!this_cp->tag_at(which).is_unresolved_klass_in_error()) {
- SystemDictionary::add_resolution_error(this_cp, which, error);
- this_cp->tag_at_put(which, JVM_CONSTANT_UnresolvedClassInError);
- } else {
- // some other thread has put the class in error state.
- error = SystemDictionary::find_resolution_error(this_cp, which);
- assert(error != NULL, "checking");
- throw_orig_error = true;
- }
- } // unlocked
-
- if (throw_orig_error) {
- CLEAR_PENDING_EXCEPTION;
- ResourceMark rm;
- const char* className = this_cp->unresolved_klass_at(which)->as_C_string();
- THROW_MSG_0(error, className);
- }
-
- return 0;
+ // The tag could have changed to in-error before the lock but we have to
+ // handle that here for the class case.
+ save_and_throw_exception(this_cp, which, constantTag(JVM_CONSTANT_UnresolvedClass), CHECK_0);
}
if (TraceClassResolution && !k()->oop_is_array()) {
@@ -587,16 +559,55 @@
return true;
}
-// If resolution for MethodHandle or MethodType fails, save the exception
+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;
+ }
+ }
+
+ // Return specific message for the tag
+ switch (tag.value()) {
+ case JVM_CONSTANT_UnresolvedClass:
+ // return the class name in the error message
+ message = this_cp->unresolved_klass_at(which);
+ break;
+ case JVM_CONSTANT_MethodHandle:
+ // return the method handle name in the error message
+ message = this_cp->method_handle_name_ref_at(which);
+ break;
+ case JVM_CONSTANT_MethodType:
+ // return the method type signature in the error message
+ message = this_cp->method_type_signature_at(which);
+ break;
+ default:
+ ShouldNotReachHere();
+ }
+
+ return message;
+}
+
+void ConstantPool::throw_resolution_error(constantPoolHandle this_cp, int which, TRAPS) {
+ Symbol* message = NULL;
+ Symbol* error = SystemDictionary::find_resolution_error(this_cp, which, &message);
+ assert(error != NULL && message != NULL, "checking");
+ CLEAR_PENDING_EXCEPTION;
+ ResourceMark rm;
+ THROW_MSG(error, message->as_C_string());
+}
+
+// If resolution for Class, MethodHandle or MethodType fails, save the exception
// in the resolution error table, so that the same exception is thrown again.
void ConstantPool::save_and_throw_exception(constantPoolHandle this_cp, int which,
- int tag, TRAPS) {
- ResourceMark rm;
+ constantTag tag, TRAPS) {
+ assert(this_cp->lock()->is_locked(), "constant pool lock should be held");
Symbol* error = PENDING_EXCEPTION->klass()->name();
- MonitorLockerEx ml(this_cp->lock()); // lock cpool to change tag.
- int error_tag = (tag == JVM_CONSTANT_MethodHandle) ?
- JVM_CONSTANT_MethodHandleInError : JVM_CONSTANT_MethodTypeInError;
+ int error_tag = tag.error_value();
if (!PENDING_EXCEPTION->
is_a(SystemDictionary::LinkageError_klass())) {
@@ -604,20 +615,21 @@
// being loaded due to virtual machine errors like StackOverflow
// and OutOfMemoryError, etc, or if the thread was hit by stop()
// Needs clarification to section 5.4.3 of the VM spec (see 6308271)
-
} else if (this_cp->tag_at(which).value() != error_tag) {
- SystemDictionary::add_resolution_error(this_cp, which, error);
+ Symbol* message = exception_message(this_cp, which, tag, PENDING_EXCEPTION);
+ SystemDictionary::add_resolution_error(this_cp, which, error, message);
this_cp->tag_at_put(which, error_tag);
} else {
- // some other thread has put the class in error state.
- error = SystemDictionary::find_resolution_error(this_cp, which);
- assert(error != NULL, "checking");
- CLEAR_PENDING_EXCEPTION;
- THROW_MSG(error, "");
+ // some other thread put this in error state
+ throw_resolution_error(this_cp, which, CHECK);
}
+
+ // This exits with some pending exception
+ assert(HAS_PENDING_EXCEPTION, "should not be cleared");
}
+
// Called to resolve constants in the constant pool and return an oop.
// Some constant pool entries cache their resolved oop. This is also
// called to create oops from constants to use in arguments for invokedynamic
@@ -645,9 +657,9 @@
jvalue prim_value; // temp used only in a few cases below
- int tag_value = this_cp->tag_at(index).value();
+ constantTag tag = this_cp->tag_at(index);
- switch (tag_value) {
+ switch (tag.value()) {
case JVM_CONSTANT_UnresolvedClass:
case JVM_CONSTANT_UnresolvedClassInError:
@@ -672,10 +684,7 @@
case JVM_CONSTANT_MethodHandleInError:
case JVM_CONSTANT_MethodTypeInError:
{
- Symbol* error = SystemDictionary::find_resolution_error(this_cp, index);
- guarantee(error != (Symbol*)NULL, "tag mismatch with resolution error table");
- ResourceMark rm;
- THROW_MSG_0(error, "");
+ throw_resolution_error(this_cp, index, CHECK_NULL);
break;
}
@@ -699,7 +708,8 @@
THREAD);
result_oop = value();
if (HAS_PENDING_EXCEPTION) {
- save_and_throw_exception(this_cp, index, tag_value, CHECK_NULL);
+ MonitorLockerEx ml(this_cp->lock()); // lock cpool to change tag.
+ save_and_throw_exception(this_cp, index, tag, CHECK_NULL);
}
break;
}
@@ -715,7 +725,8 @@
Handle value = SystemDictionary::find_method_handle_type(signature, klass, THREAD);
result_oop = value();
if (HAS_PENDING_EXCEPTION) {
- save_and_throw_exception(this_cp, index, tag_value, CHECK_NULL);
+ MonitorLockerEx ml(this_cp->lock()); // lock cpool to change tag.
+ save_and_throw_exception(this_cp, index, tag, CHECK_NULL);
}
break;
}
@@ -746,7 +757,7 @@
default:
DEBUG_ONLY( tty->print_cr("*** %p: tag at CP[%d/%d] = %d",
- this_cp(), index, cache_index, tag_value) );
+ this_cp(), index, cache_index, tag.value()));
assert(false, "unexpected constant tag");
break;
}
--- a/hotspot/src/share/vm/oops/constantPool.hpp Tue Apr 29 15:17:27 2014 +0200
+++ b/hotspot/src/share/vm/oops/constantPool.hpp Thu May 08 15:08:45 2014 -0700
@@ -822,9 +822,13 @@
static void resolve_string_constants_impl(constantPoolHandle this_cp, TRAPS);
static oop resolve_constant_at_impl(constantPoolHandle this_cp, int index, int cache_index, TRAPS);
- static void save_and_throw_exception(constantPoolHandle this_cp, int which, int tag_value, TRAPS);
static oop resolve_bootstrap_specifier_at_impl(constantPoolHandle this_cp, int index, TRAPS);
+ // Exception handling
+ static void throw_resolution_error(constantPoolHandle this_cp, int which, TRAPS);
+ static Symbol* exception_message(constantPoolHandle this_cp, int which, constantTag tag, oop pending_exception);
+ static void save_and_throw_exception(constantPoolHandle this_cp, int which, constantTag tag, TRAPS);
+
public:
// Merging ConstantPool* support:
bool compare_entry_to(int index1, constantPoolHandle cp2, int index2, TRAPS);
--- a/hotspot/src/share/vm/runtime/thread.cpp Tue Apr 29 15:17:27 2014 +0200
+++ b/hotspot/src/share/vm/runtime/thread.cpp Thu May 08 15:08:45 2014 -0700
@@ -1199,6 +1199,13 @@
va_end(ap);
}
+void NamedThread::print_on(outputStream* st) const {
+ st->print("\"%s\" ", name());
+ Thread::print_on(st);
+ st->cr();
+}
+
+
// ======= WatcherThread ========
// The watcher thread exists to simulate timer interrupts. It should
--- a/hotspot/src/share/vm/runtime/thread.hpp Tue Apr 29 15:17:27 2014 +0200
+++ b/hotspot/src/share/vm/runtime/thread.hpp Thu May 08 15:08:45 2014 -0700
@@ -555,7 +555,7 @@
void set_lgrp_id(int value) { _lgrp_id = value; }
// Printing
- void print_on(outputStream* st) const;
+ virtual void print_on(outputStream* st) const;
void print() const { print_on(tty); }
virtual void print_on_error(outputStream* st, char* buf, int buflen) const;
@@ -689,6 +689,7 @@
virtual char* name() const { return _name == NULL ? (char*)"Unknown Thread" : _name; }
JavaThread *processed_thread() { return _processed_thread; }
void set_processed_thread(JavaThread *thread) { _processed_thread = thread; }
+ virtual void print_on(outputStream* st) const;
};
// Worker threads are named and have an id of an assigned work.
@@ -735,7 +736,6 @@
// Printing
char* name() const { return (char*)"VM Periodic Task Thread"; }
void print_on(outputStream* st) const;
- void print() const { print_on(tty); }
void unpark();
// Returns the single instance of WatcherThread
@@ -1444,7 +1444,6 @@
// Misc. operations
char* name() const { return (char*)get_thread_name(); }
void print_on(outputStream* st) const;
- void print() const { print_on(tty); }
void print_value();
void print_thread_state_on(outputStream* ) const PRODUCT_RETURN;
void print_thread_state() const PRODUCT_RETURN;
--- a/hotspot/src/share/vm/runtime/vmThread.cpp Tue Apr 29 15:17:27 2014 +0200
+++ b/hotspot/src/share/vm/runtime/vmThread.cpp Thu May 08 15:08:45 2014 -0700
@@ -339,12 +339,6 @@
}
}
-void VMThread::print_on(outputStream* st) const {
- st->print("\"%s\" ", name());
- Thread::print_on(st);
- st->cr();
-}
-
void VMThread::evaluate_operation(VM_Operation* op) {
ResourceMark rm;
--- a/hotspot/src/share/vm/runtime/vmThread.hpp Tue Apr 29 15:17:27 2014 +0200
+++ b/hotspot/src/share/vm/runtime/vmThread.hpp Thu May 08 15:08:45 2014 -0700
@@ -128,9 +128,6 @@
// GC support
void oops_do(OopClosure* f, CLDClosure* cld_f, CodeBlobClosure* cf);
- // Debugging
- void print_on(outputStream* st) const;
- void print() const { print_on(tty); }
void verify();
// Performance measurement
--- a/hotspot/src/share/vm/utilities/constantTag.cpp Tue Apr 29 15:17:27 2014 +0200
+++ b/hotspot/src/share/vm/utilities/constantTag.cpp Thu May 08 15:08:45 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -76,6 +76,20 @@
}
+jbyte constantTag::error_value() const {
+ switch (_tag) {
+ case JVM_CONSTANT_UnresolvedClass:
+ return JVM_CONSTANT_UnresolvedClassInError;
+ case JVM_CONSTANT_MethodHandle:
+ return JVM_CONSTANT_MethodHandleInError;
+ case JVM_CONSTANT_MethodType:
+ return JVM_CONSTANT_MethodTypeInError;
+ default:
+ ShouldNotReachHere();
+ return JVM_CONSTANT_Invalid;
+ }
+}
+
const char* constantTag::internal_name() const {
switch (_tag) {
case JVM_CONSTANT_Invalid :
--- a/hotspot/src/share/vm/utilities/constantTag.hpp Tue Apr 29 15:17:27 2014 +0200
+++ b/hotspot/src/share/vm/utilities/constantTag.hpp Thu May 08 15:08:45 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -109,6 +109,7 @@
}
jbyte value() const { return _tag; }
+ jbyte error_value() const;
jbyte non_error_value() const;
BasicType basic_type() const; // if used with ldc, what kind of value gets pushed?
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/ClassResolutionFail/Property.java Thu May 08 15:08:45 2014 -0700
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+
+// Class PropertySuper is not found.
+
+public class Property extends PropertySuper {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/ClassResolutionFail/PropertySuper.java Thu May 08 15:08:45 2014 -0700
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+// Class PropertySuper should be removed.
+
+public class PropertySuper {
+ PropertySuper() { System.out.println("remove me for NoClassDefFoundError"); }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/ClassResolutionFail/TestClassResolutionFail.java Thu May 08 15:08:45 2014 -0700
@@ -0,0 +1,57 @@
+/*
+ * 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 TestClassResolutionFail
+ * @bug 8023697
+ * @summary This tests that failed class resolution doesn't report different class name in detail message for the first and subsequent times
+ */
+
+import java.io.File;
+
+public class TestClassResolutionFail {
+ static String message;
+ public static void test1() throws RuntimeException {
+ try {
+ Property p = new Property();
+ } catch (LinkageError e) {
+ message = e.getMessage();
+ }
+ try {
+ Property p = new Property();
+ } catch (LinkageError e) {
+ System.out.println(e.getMessage());
+ if (!e.getMessage().equals(message)) {
+ throw new RuntimeException("Wrong message: " + message + " != " + e.getMessage());
+ }
+ }
+ }
+ public static void main(java.lang.String[] unused) throws Exception {
+ // Remove PropertySuper class
+ String testClasses = System.getProperty("test.classes", ".");
+ File f = new File(testClasses + File.separator + "PropertySuper.class");
+ f.delete();
+ test1();
+ }
+}
+