# HG changeset patch # User doko@ubuntu.com # Date 1224061808 -7200 # Node ID bcb125b39f86c8861c8a21110d8d64d2317a6cd0 # Parent 654694c101ad509f20e6586c74845340470e44f8 2008-10-15 Matthias Klose * patches/icedtea-hotspot-6b11-7b24.patch: Remove. diff -r 654694c101ad -r bcb125b39f86 ChangeLog --- a/ChangeLog Wed Oct 15 01:36:05 2008 -0400 +++ b/ChangeLog Wed Oct 15 11:10:08 2008 +0200 @@ -1,3 +1,7 @@ +2008-10-15 Matthias Klose + + * patches/icedtea-hotspot-6b11-7b24.patch: Remove. + 2008-10-14 Ioana Ivan * pulseaudio/src/java/org/classpath/icedtea/pulseaudio/PulseAudioDataLine.java diff -r 654694c101ad -r bcb125b39f86 patches/icedtea-hotspot-6b11-7b24.patch --- a/patches/icedtea-hotspot-6b11-7b24.patch Wed Oct 15 01:36:05 2008 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56973 +0,0 @@ -diff -ruNb openjdk{6,}/hotspot/src/share -diff -ruNb openjdk{6,}/hotspot/src/os/linux - -diff -ruNb openjdk6/hotspot/src/share/tools/MakeDeps/BuildConfig.java openjdk/hotspot/src/share/tools/MakeDeps/BuildConfig.java ---- openjdk6/hotspot/src/share/tools/MakeDeps/BuildConfig.java 2008-07-10 22:04:28.000000000 +0200 -+++ openjdk/hotspot/src/share/tools/MakeDeps/BuildConfig.java 2007-12-14 08:57:02.000000000 +0100 -@@ -704,6 +704,3 @@ - receiver.add(attr); receiver.add(value); - } - } -- -- -- -diff -ruNb openjdk6/hotspot/src/share/tools/MakeDeps/Macro.java openjdk/hotspot/src/share/tools/MakeDeps/Macro.java ---- openjdk6/hotspot/src/share/tools/MakeDeps/Macro.java 2008-07-10 22:04:28.000000000 +0200 -+++ openjdk/hotspot/src/share/tools/MakeDeps/Macro.java 2007-12-14 08:57:02.000000000 +0100 -@@ -26,4 +26,3 @@ - public String name; - public String contents; - } -- -diff -ruNb openjdk6/hotspot/src/share/tools/MakeDeps/Platform.java openjdk/hotspot/src/share/tools/MakeDeps/Platform.java ---- openjdk6/hotspot/src/share/tools/MakeDeps/Platform.java 2008-07-10 22:04:28.000000000 +0200 -+++ openjdk/hotspot/src/share/tools/MakeDeps/Platform.java 2007-12-14 08:57:02.000000000 +0100 -@@ -169,7 +169,7 @@ - - /** max is 31 on mac, so warn */ - public int fileNameLengthLimit() { -- return 40; -+ return 45; - } - - public int defaultGrandIncludeThreshold() { -diff -ruNb openjdk6/hotspot/src/share/tools/MakeDeps/WinGammaPlatformVC6.java openjdk/hotspot/src/share/tools/MakeDeps/WinGammaPlatformVC6.java ---- openjdk6/hotspot/src/share/tools/MakeDeps/WinGammaPlatformVC6.java 2008-07-10 22:04:28.000000000 +0200 -+++ openjdk/hotspot/src/share/tools/MakeDeps/WinGammaPlatformVC6.java 2007-12-14 08:57:02.000000000 +0100 -@@ -236,7 +236,7 @@ - " /nologo /base:\"0x8000000\" /subsystem:windows /dll" + - " /export:JNI_GetDefaultJavaVMInitArgs /export:JNI_CreateJavaVM /export:JNI_GetCreatedJavaVMs "+ - " /export:jio_snprintf /export:jio_printf /export:jio_fprintf /export:jio_vfprintf "+ -- " /export:jio_vsnprintf /export:JVM_EnqueueOperation "); -+ " /export:jio_vsnprintf "); - rv.add("SUBTRACT LINK32 /pdb:none /map"); - - return rv; -diff -ruNb openjdk6/hotspot/src/share/tools/MakeDeps/WinGammaPlatformVC7.java openjdk/hotspot/src/share/tools/MakeDeps/WinGammaPlatformVC7.java ---- openjdk6/hotspot/src/share/tools/MakeDeps/WinGammaPlatformVC7.java 2008-07-10 22:04:28.000000000 +0200 -+++ openjdk/hotspot/src/share/tools/MakeDeps/WinGammaPlatformVC7.java 2007-12-14 08:57:02.000000000 +0100 -@@ -262,6 +262,8 @@ - - rv.add(new SpecificNameFilter("JVMTI Generated", new String[] {"^jvmti.+"})); - -+ rv.add(new SpecificNameFilter("C++ Interpreter Generated", new String[] {"^bytecodeInterpreterWithChecks.+"})); -+ - rv.add(new SpecificNameFilter("Include DBs", new String[] {"^includeDB_.+"})); - - // this one is to catch files not caught by other filters -@@ -574,8 +576,7 @@ - "/export:JNI_GetCreatedJavaVMs "+ - "/export:jio_snprintf /export:jio_printf "+ - "/export:jio_fprintf /export:jio_vfprintf "+ -- "/export:jio_vsnprintf "+ -- "/export:JVM_EnqueueOperation "); -+ "/export:jio_vsnprintf "); - addAttr(rv, "AdditionalDependencies", "Wsock32.lib winmm.lib"); - addAttr(rv, "OutputFile", outDll); - addAttr(rv, "LinkIncremental", "1"); -diff -ruNb openjdk6/hotspot/src/share/vm/adlc/adlc.hpp openjdk/hotspot/src/share/vm/adlc/adlc.hpp ---- openjdk6/hotspot/src/share/vm/adlc/adlc.hpp 2008-07-10 22:04:28.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/adlc/adlc.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)adlc.hpp 1.28 07/05/05 17:04:59 JVM" --#endif - /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/adlc/adlparse.cpp openjdk/hotspot/src/share/vm/adlc/adlparse.cpp ---- openjdk6/hotspot/src/share/vm/adlc/adlparse.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/adlc/adlparse.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)adlparse.cpp 1.205 07/05/05 17:05:00 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/adlc/adlparse.hpp openjdk/hotspot/src/share/vm/adlc/adlparse.hpp ---- openjdk6/hotspot/src/share/vm/adlc/adlparse.hpp 2008-07-10 22:04:28.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/adlc/adlparse.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)adlparse.hpp 1.79 07/05/05 17:05:00 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -273,5 +270,3 @@ - static bool is_int_token(const char* token, int& intval); - static void trim(char* &token); // trim leading & trailing spaces - }; -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/adlc/archDesc.cpp openjdk/hotspot/src/share/vm/adlc/archDesc.cpp ---- openjdk6/hotspot/src/share/vm/adlc/archDesc.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/adlc/archDesc.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -22,6 +22,7 @@ - // - // - -+ - // archDesc.cpp - Internal format for architecture definition - #include "adlc.hpp" - -diff -ruNb openjdk6/hotspot/src/share/vm/adlc/arena.cpp openjdk/hotspot/src/share/vm/adlc/arena.cpp ---- openjdk6/hotspot/src/share/vm/adlc/arena.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/adlc/arena.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)arena.cpp 1.16 07/05/05 17:05:00 JVM" --#endif - /* - * Copyright 1998-2002 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -173,4 +170,3 @@ - void CHeapObj::operator delete(void* p){ - free(p); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/adlc/arena.hpp openjdk/hotspot/src/share/vm/adlc/arena.hpp ---- openjdk6/hotspot/src/share/vm/adlc/arena.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/adlc/arena.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)arena.hpp 1.17 07/05/05 17:05:00 JVM" --#endif - /* - * Copyright 1998-2002 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -158,4 +155,3 @@ - size_t size_in_bytes() const { return _size_in_bytes; } - void set_size_in_bytes(size_t size) { _size_in_bytes = size; } - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/adlc/dfa.cpp openjdk/hotspot/src/share/vm/adlc/dfa.cpp ---- openjdk6/hotspot/src/share/vm/adlc/dfa.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/adlc/dfa.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)dfa.cpp 1.83 07/05/05 17:04:59 JVM" --#endif - /* - * Copyright 1997-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -1022,4 +1019,3 @@ - void ProductionState::print() { - _production.print(print_key, print_production); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/adlc/dict2.cpp openjdk/hotspot/src/share/vm/adlc/dict2.cpp ---- openjdk6/hotspot/src/share/vm/adlc/dict2.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/adlc/dict2.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)dict2.cpp 1.19 07/05/05 17:04:59 JVM" --#endif - /* - * Copyright 1998-2002 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -354,5 +351,3 @@ - } - _key = _value = NULL; - } -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/adlc/dict2.hpp openjdk/hotspot/src/share/vm/adlc/dict2.hpp ---- openjdk6/hotspot/src/share/vm/adlc/dict2.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/adlc/dict2.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)dict2.hpp 1.16 07/05/05 17:05:01 JVM" --#endif - /* - * Copyright 1998-2000 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -121,5 +118,3 @@ - }; - - #endif // _DICT_ -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/adlc/filebuff.cpp openjdk/hotspot/src/share/vm/adlc/filebuff.cpp ---- openjdk6/hotspot/src/share/vm/adlc/filebuff.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/adlc/filebuff.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)filebuff.cpp 1.30 07/05/05 17:05:01 JVM" --#endif - /* - * Copyright 1997-2002 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -297,4 +294,3 @@ - va_end(args); - _AD._no_output = 1; - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/adlc/filebuff.hpp openjdk/hotspot/src/share/vm/adlc/filebuff.hpp ---- openjdk6/hotspot/src/share/vm/adlc/filebuff.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/adlc/filebuff.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)filebuff.hpp 1.27 07/05/05 17:05:01 JVM" --#endif - /* - * Copyright 1997-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/adlc/forms.cpp openjdk/hotspot/src/share/vm/adlc/forms.cpp ---- openjdk6/hotspot/src/share/vm/adlc/forms.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/adlc/forms.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)forms.cpp 1.161 07/05/05 17:04:59 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -386,4 +383,3 @@ - void SourceForm::output(FILE *fp) { - fprintf(fp,"\n//%s\n%s\n",classname(),(_code?_code:"")); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/adlc/forms.hpp openjdk/hotspot/src/share/vm/adlc/forms.hpp ---- openjdk6/hotspot/src/share/vm/adlc/forms.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/adlc/forms.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)forms.hpp 1.150 07/05/05 17:05:00 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -587,6 +584,3 @@ - void print_asserts(FILE *fp); - void dump(); - }; -- -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/adlc/formsopt.cpp openjdk/hotspot/src/share/vm/adlc/formsopt.cpp ---- openjdk6/hotspot/src/share/vm/adlc/formsopt.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/adlc/formsopt.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)formsopt.cpp 1.53 07/05/05 17:05:01 JVM" --#endif - /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -725,4 +722,3 @@ - void PeepReplace::output(FILE *fp) { // Write info to output files - fprintf(fp,"PeepReplace:\n"); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/adlc/formsopt.hpp openjdk/hotspot/src/share/vm/adlc/formsopt.hpp ---- openjdk6/hotspot/src/share/vm/adlc/formsopt.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/adlc/formsopt.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)formsopt.hpp 1.54 07/05/05 17:05:01 JVM" --#endif - /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -549,4 +546,3 @@ - void dump(); - void output(FILE *fp); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/adlc/formssel.cpp openjdk/hotspot/src/share/vm/adlc/formssel.cpp ---- openjdk6/hotspot/src/share/vm/adlc/formssel.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/adlc/formssel.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)formssel.cpp 1.183 07/09/06 15:24:29 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -236,23 +233,58 @@ - return _matrule ? _matrule->is_ideal_copy() : 0; - } - --// Return 'true' if this instruction matches an ideal 'CosD' node -+// Return 'true' if this instruction is too complex to rematerialize. - int InstructForm::is_expensive() const { -- if (_matrule == NULL) return 0; - // We can prove it is cheap if it has an empty encoding. - // This helps with platform-specific nops like ThreadLocal and RoundFloat. -+ if (is_empty_encoding()) -+ return 0; -+ -+ if (is_tls_instruction()) -+ return 1; -+ -+ if (_matrule == NULL) return 0; -+ -+ return _matrule->is_expensive(); -+} -+ -+// Has an empty encoding if _size is a constant zero or there -+// are no ins_encode tokens. -+int InstructForm::is_empty_encoding() const { - if (_insencode != NULL) { - _insencode->reset(); - if (_insencode->encode_class_iter() == NULL) { -- return 0; -+ return 1; - } - } - if (_size != NULL && strcmp(_size, "0") == 0) { -+ return 1; -+ } - return 0; -+} -+ -+int InstructForm::is_tls_instruction() const { -+ if (_ident != NULL && -+ ( ! strcmp( _ident,"tlsLoadP") || -+ ! strncmp(_ident,"tlsLoadP_",9)) ) { -+ return 1; - } -- return _matrule->is_expensive(); -+ -+ if (_matrule != NULL && _insencode != NULL) { -+ const char* opType = _matrule->_opType; -+ if (strcmp(opType, "Set")==0) -+ opType = _matrule->_rChild->_opType; -+ if (strcmp(opType,"ThreadLocal")==0) { -+ fprintf(stderr, "Warning: ThreadLocal instruction %s should be named 'tlsLoadP_*'\n", -+ (_ident == NULL ? "NULL" : _ident)); -+ return 1; -+ } -+ } -+ -+ return 0; - } - -+ - // Return 'true' if this instruction matches an ideal 'Copy*' node - bool InstructForm::is_ideal_unlock() const { - return _matrule ? _matrule->is_ideal_unlock() : false; -@@ -492,6 +524,10 @@ - if( _components.count() == 1 && _components[0]->is(Component::USE_DEF) ) - rematerialize = true; - -+ // Pseudo-constants (values easily available to the runtime) -+ if (is_empty_encoding() && is_tls_instruction()) -+ rematerialize = true; -+ - // 1-input, 1-output, such as copies or increments. - if( _components.count() == 2 && - _components[0]->is(Component::DEF) && -@@ -1171,9 +1207,9 @@ - // Output the format call for this operand - fprintf(fp,"opnd_array(%d)->",idx); - if (idx == 0) -- fprintf(fp,"int_format(ra, this); // %s\n", rep_var); -+ fprintf(fp,"int_format(ra, this, st); // %s\n", rep_var); - else -- fprintf(fp,"ext_format(ra, this,idx%d); // %s\n", idx, rep_var ); -+ fprintf(fp,"ext_format(ra, this,idx%d, st); // %s\n", idx, rep_var ); - } - } - -@@ -2329,11 +2365,11 @@ - - void OperandForm::format_constant(FILE *fp, uint const_index, uint const_type) { - switch(const_type) { -- case Form::idealI: fprintf(fp,"tty->print(\"#%%d\", _c%d);\n", const_index); break; -- case Form::idealP: fprintf(fp,"_c%d->dump();\n", const_index); break; -- case Form::idealL: fprintf(fp,"tty->print(\"#%%lld\", _c%d);\n", const_index); break; -- case Form::idealF: fprintf(fp,"tty->print(\"#%%f\", _c%d);\n", const_index); break; -- case Form::idealD: fprintf(fp,"tty->print(\"#%%f\", _c%d);\n", const_index); break; -+ case Form::idealI: fprintf(fp,"st->print(\"#%%d\", _c%d);\n", const_index); break; -+ case Form::idealP: fprintf(fp,"_c%d->dump_on(st);\n", const_index); break; -+ case Form::idealL: fprintf(fp,"st->print(\"#%%lld\", _c%d);\n", const_index); break; -+ case Form::idealF: fprintf(fp,"st->print(\"#%%f\", _c%d);\n", const_index); break; -+ case Form::idealD: fprintf(fp,"st->print(\"#%%f\", _c%d);\n", const_index); break; - default: - assert( false, "ShouldNotReachHere()"); - } -@@ -3725,6 +3761,17 @@ - int MatchRule::is_ideal_copy() const { - if( _rChild ) { - const char *opType = _rChild->_opType; -+ if( strcmp(opType,"CastII")==0 ) -+ return 1; -+ // Do not treat *CastPP this way, because it -+ // may transfer a raw pointer to an oop. -+ // If the register allocator were to coalesce this -+ // into a single LRG, the GC maps would be incorrect. -+ //if( strcmp(opType,"CastPP")==0 ) -+ // return 1; -+ //if( strcmp(opType,"CheckCastPP")==0 ) -+ // return 1; -+ // - // Do not treat CastX2P or CastP2X this way, because - // raw pointers and int types are treated differently - // when saving local & stack info for safepoints in -@@ -3773,7 +3820,6 @@ - strcmp(opType,"ConvL2I")==0 || - strcmp(opType,"RoundDouble")==0 || - strcmp(opType,"RoundFloat")==0 || -- strcmp(opType,"ThreadLocal")==0 || - strcmp(opType,"ReverseBytesI")==0 || - strcmp(opType,"ReverseBytesL")==0 || - strcmp(opType,"Replicate16B")==0 || -@@ -3951,4 +3997,3 @@ - fprintf(fp,"\nFormat Rule: \n%s", (_temp?_temp:"")); - fprintf(fp,"\n"); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/adlc/formssel.hpp openjdk/hotspot/src/share/vm/adlc/formssel.hpp ---- openjdk6/hotspot/src/share/vm/adlc/formssel.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/adlc/formssel.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)formssel.hpp 1.76 07/05/17 15:49:19 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -139,6 +136,8 @@ - // ideal opcode enumeration - virtual const char *ideal_Opcode(FormDict &globals) const; - virtual int is_expensive() const; // node matches ideal 'CosD' -+ virtual int is_empty_encoding() const; // _size=0 and/or _insencode empty -+ virtual int is_tls_instruction() const; // tlsLoadP rule or ideal ThreadLocal - virtual int is_ideal_copy() const; // node matches ideal 'Copy*' - virtual bool is_ideal_unlock() const; // node matches ideal 'Unlock' - virtual bool is_ideal_call_leaf() const; // node matches ideal 'CallLeaf' -diff -ruNb openjdk6/hotspot/src/share/vm/adlc/output_c.cpp openjdk/hotspot/src/share/vm/adlc/output_c.cpp ---- openjdk6/hotspot/src/share/vm/adlc/output_c.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/adlc/output_c.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)output_c.cpp 1.184 07/05/17 15:49:23 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -2199,7 +2196,7 @@ - const char* reg_conversion(const char* rep_var) { - if (strcmp(rep_var,"$Register") == 0) return "as_Register"; - if (strcmp(rep_var,"$FloatRegister") == 0) return "as_FloatRegister"; --#if defined(IA32) -+#if defined(IA32) || defined(AMD64) - if (strcmp(rep_var,"$XMMRegister") == 0) return "as_XMMRegister"; - #endif - return NULL; -diff -ruNb openjdk6/hotspot/src/share/vm/adlc/output_h.cpp openjdk/hotspot/src/share/vm/adlc/output_h.cpp ---- openjdk6/hotspot/src/share/vm/adlc/output_h.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/adlc/output_h.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)output_h.cpp 1.178 07/05/05 17:05:03 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -345,34 +342,34 @@ - - // Generate the format rule for condition codes - static void defineCCodeDump(FILE *fp, int i) { -- fprintf(fp, " if( _c%d == BoolTest::eq ) tty->print(\"eq\");\n",i); -- fprintf(fp, " else if( _c%d == BoolTest::ne ) tty->print(\"ne\");\n",i); -- fprintf(fp, " else if( _c%d == BoolTest::le ) tty->print(\"le\");\n",i); -- fprintf(fp, " else if( _c%d == BoolTest::ge ) tty->print(\"ge\");\n",i); -- fprintf(fp, " else if( _c%d == BoolTest::lt ) tty->print(\"lt\");\n",i); -- fprintf(fp, " else if( _c%d == BoolTest::gt ) tty->print(\"gt\");\n",i); -+ fprintf(fp, " if( _c%d == BoolTest::eq ) st->print(\"eq\");\n",i); -+ fprintf(fp, " else if( _c%d == BoolTest::ne ) st->print(\"ne\");\n",i); -+ fprintf(fp, " else if( _c%d == BoolTest::le ) st->print(\"le\");\n",i); -+ fprintf(fp, " else if( _c%d == BoolTest::ge ) st->print(\"ge\");\n",i); -+ fprintf(fp, " else if( _c%d == BoolTest::lt ) st->print(\"lt\");\n",i); -+ fprintf(fp, " else if( _c%d == BoolTest::gt ) st->print(\"gt\");\n",i); - } - - // Output code that dumps constant values, increment "i" if type is constant - static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i) { - if (!strcmp(ideal_type, "ConI")) { -- fprintf(fp," tty->print(\"#%%d\", _c%d);\n", i); -+ fprintf(fp," st->print(\"#%%d\", _c%d);\n", i); - ++i; - } - else if (!strcmp(ideal_type, "ConP")) { -- fprintf(fp," _c%d->dump();\n", i); -+ fprintf(fp," _c%d->dump_on(st);\n", i); - ++i; - } - else if (!strcmp(ideal_type, "ConL")) { -- fprintf(fp," tty->print(\"#\" INT64_FORMAT, _c%d);\n", i); -+ fprintf(fp," st->print(\"#\" INT64_FORMAT, _c%d);\n", i); - ++i; - } - else if (!strcmp(ideal_type, "ConF")) { -- fprintf(fp," tty->print(\"#%%f\", _c%d);\n", i); -+ fprintf(fp," st->print(\"#%%f\", _c%d);\n", i); - ++i; - } - else if (!strcmp(ideal_type, "ConD")) { -- fprintf(fp," tty->print(\"#%%f\", _c%d);\n", i); -+ fprintf(fp," st->print(\"#%%f\", _c%d);\n", i); - ++i; - } - else if (!strcmp(ideal_type, "Bool")) { -@@ -388,8 +385,8 @@ - if (!for_c_file) { - // invoked after output #ifndef PRODUCT to ad_.hpp - // compile the bodies separately, to cut down on recompilations -- fprintf(fp," virtual void int_format(PhaseRegAlloc *ra, const MachNode *node) const;\n"); -- fprintf(fp," virtual void ext_format(PhaseRegAlloc *ra, const MachNode *node, int idx) const;\n"); -+ fprintf(fp," virtual void int_format(PhaseRegAlloc *ra, const MachNode *node, outputStream *st) const;\n"); -+ fprintf(fp," virtual void ext_format(PhaseRegAlloc *ra, const MachNode *node, int idx, outputStream *st) const;\n"); - return; - } - -@@ -398,7 +395,7 @@ - - // Generate internal format function, used when stored locally - fprintf(fp, "\n#ifndef PRODUCT\n"); -- fprintf(fp,"void %sOper::int_format(PhaseRegAlloc *ra, const MachNode *node) const {\n", oper._ident); -+ fprintf(fp,"void %sOper::int_format(PhaseRegAlloc *ra, const MachNode *node, outputStream *st) const {\n", oper._ident); - // Generate the user-defined portion of the format - if (oper._format) { - if ( oper._format->_strings.count() != 0 ) { -@@ -414,8 +411,8 @@ - // Check if this is a standard string or a replacement variable - if ( string != NameList::_signal ) { - // Normal string -- // Pass through to tty->print -- fprintf(fp,"tty->print(\"%s\");\n", string); -+ // Pass through to st->print -+ fprintf(fp,"st->print(\"%s\");\n", string); - } else { - // Replacement variable - const char *rep_var = oper._format->_rep_vars.iter(); -@@ -450,7 +447,7 @@ - } else { // oper._format == NULL - // Provide a few special case formats where the AD writer cannot. - if ( strcmp(oper._ident,"Universe")==0 ) { -- fprintf(fp, " tty->print(\"$$univ\");\n"); -+ fprintf(fp, " st->print(\"$$univ\");\n"); - } - // labelOper::int_format is defined in ad_<...>.cpp - } -@@ -461,7 +458,7 @@ - fprintf(fp,"}\n"); - - // Generate external format function, when data is stored externally -- fprintf(fp,"void %sOper::ext_format(PhaseRegAlloc *ra, const MachNode *node, int idx) const {\n", oper._ident); -+ fprintf(fp,"void %sOper::ext_format(PhaseRegAlloc *ra, const MachNode *node, int idx, outputStream *st) const {\n", oper._ident); - // Generate the user-defined portion of the format - if (oper._format) { - if ( oper._format->_strings.count() != 0 ) { -@@ -481,8 +478,8 @@ - // Check if this is a standard string or a replacement variable - if ( string != NameList::_signal ) { - // Normal string -- // Pass through to tty->print -- fprintf(fp,"tty->print(\"%s\");\n", string); -+ // Pass through to st->print -+ fprintf(fp,"st->print(\"%s\");\n", string); - } else { - // Replacement variable - const char *rep_var = oper._format->_rep_vars.iter(); -@@ -518,7 +515,7 @@ - } else { // oper._format == NULL - // Provide a few special case formats where the AD writer cannot. - if ( strcmp(oper._ident,"Universe")==0 ) { -- fprintf(fp, " tty->print(\"$$univ\");\n"); -+ fprintf(fp, " st->print(\"$$univ\");\n"); - } - // labelOper::ext_format is defined in ad_<...>.cpp - } -@@ -536,13 +533,13 @@ - if (!for_c_file) { - // compile the bodies separately, to cut down on recompilations - // #ifndef PRODUCT region generated by caller -- fprintf(fp," virtual void format(PhaseRegAlloc *ra) const;\n"); -+ fprintf(fp," virtual void format(PhaseRegAlloc *ra, outputStream *st) const;\n"); - return; - } - - // Define the format function - fprintf(fp, "#ifndef PRODUCT\n"); -- fprintf(fp, "void %sNode::format(PhaseRegAlloc *ra) const {\n", inst._ident); -+ fprintf(fp, "void %sNode::format(PhaseRegAlloc *ra, outputStream *st) const {\n", inst._ident); - - // Generate the user-defined portion of the format - if( inst._format ) { -@@ -559,7 +556,7 @@ - fprintf(fp," "); - // Check if this is a standard string or a replacement variable - if( string != NameList::_signal ) // Normal string. Pass through. -- fprintf(fp,"tty->print(\"%s\");\n", string); -+ fprintf(fp,"st->print(\"%s\");\n", string); - else // Replacement variable - inst.rep_var_format( fp, inst._format->_rep_vars.iter() ); - } // Done with all format strings -@@ -573,8 +570,8 @@ - fprintf(fp," _method->print_short_name();\n"); - break; - case Form::JAVA_STATIC: -- fprintf(fp," if( _method ) _method->print_short_name(); else tty->print(\" wrapper for: %%s\", _name);\n"); -- fprintf(fp," if( !_method ) dump_trap_args();\n"); -+ fprintf(fp," if( _method ) _method->print_short_name(st); else st->print(\" wrapper for: %%s\", _name);\n"); -+ fprintf(fp," if( !_method ) dump_trap_args(st);\n"); - break; - case Form::JAVA_COMPILED: - case Form::JAVA_INTERP: -@@ -582,38 +579,38 @@ - case Form::JAVA_RUNTIME: - case Form::JAVA_LEAF: - case Form::JAVA_NATIVE: -- fprintf(fp," tty->print(\" %%s\", _name);"); -+ fprintf(fp," st->print(\" %%s\", _name);"); - break; - default: - assert(0,"ShouldNotReacHere"); - } -- fprintf(fp, " tty->print_cr(\"\");\n" ); -- fprintf(fp, " if (_jvms) _jvms->format(ra, this); else tty->print_cr(\" No JVM State Info\");\n" ); -- fprintf(fp, " tty->print(\" # \");\n" ); -- fprintf(fp, " if( _jvms ) _oop_map->print();\n"); -+ fprintf(fp, " st->print_cr(\"\");\n" ); -+ fprintf(fp, " if (_jvms) _jvms->format(ra, this, st); else st->print_cr(\" No JVM State Info\");\n" ); -+ fprintf(fp, " st->print(\" # \");\n" ); -+ fprintf(fp, " if( _jvms ) _oop_map->print_on(st);\n"); - } - else if(inst.is_ideal_safepoint()) { -- fprintf(fp, " tty->print(\"\");\n" ); -- fprintf(fp, " if (_jvms) _jvms->format(ra, this); else tty->print_cr(\" No JVM State Info\");\n" ); -- fprintf(fp, " tty->print(\" # \");\n" ); -- fprintf(fp, " if( _jvms ) _oop_map->print();\n"); -+ fprintf(fp, " st->print(\"\");\n" ); -+ fprintf(fp, " if (_jvms) _jvms->format(ra, this, st); else st->print_cr(\" No JVM State Info\");\n" ); -+ fprintf(fp, " st->print(\" # \");\n" ); -+ fprintf(fp, " if( _jvms ) _oop_map->print_on(st);\n"); - } - else if( inst.is_ideal_if() ) { -- fprintf(fp, " tty->print(\" P=%%f C=%%f\",_prob,_fcnt);\n" ); -+ fprintf(fp, " st->print(\" P=%%f C=%%f\",_prob,_fcnt);\n" ); - } - else if( inst.is_ideal_mem() ) { - // Print out the field name if available to improve readability - fprintf(fp, " if (ra->C->alias_type(adr_type())->field() != NULL) {\n"); -- fprintf(fp, " tty->print(\" ! Field \");\n"); -+ fprintf(fp, " st->print(\" ! Field \");\n"); - fprintf(fp, " if( ra->C->alias_type(adr_type())->is_volatile() )\n"); -- fprintf(fp, " tty->print(\" Volatile\");\n"); -- fprintf(fp, " ra->C->alias_type(adr_type())->field()->holder()->name()->print_symbol_on(tty);\n"); -- fprintf(fp, " tty->print(\".\");\n"); -- fprintf(fp, " ra->C->alias_type(adr_type())->field()->name()->print_symbol_on(tty);\n"); -+ fprintf(fp, " st->print(\" Volatile\");\n"); -+ fprintf(fp, " ra->C->alias_type(adr_type())->field()->holder()->name()->print_symbol_on(st);\n"); -+ fprintf(fp, " st->print(\".\");\n"); -+ fprintf(fp, " ra->C->alias_type(adr_type())->field()->name()->print_symbol_on(st);\n"); - fprintf(fp, " } else\n"); - // Make sure 'Volatile' gets printed out - fprintf(fp, " if( ra->C->alias_type(adr_type())->is_volatile() )\n"); -- fprintf(fp, " tty->print(\" Volatile!\");\n"); -+ fprintf(fp, " st->print(\" Volatile!\");\n"); - } - - // Complete the definition of the format function -@@ -1353,15 +1350,15 @@ - // IF we have constants, create a dump_spec function for the derived class - // - // (1) virtual void dump_spec() const { -- // (2) tty->print("#%d", _c#); // Constant != ConP -- // OR _c#->dump(); // Type ConP -+ // (2) st->print("#%d", _c#); // Constant != ConP -+ // OR _c#->dump_on(st); // Type ConP - // ... - // (3) } - uint num_consts = oper->num_consts(_globalNames); - if( num_consts > 0 ) { - // line (1) -- fprintf(fp, " virtual void dump_spec() const {\n"); -- // generate format string for tty->print -+ fprintf(fp, " virtual void dump_spec(outputStream *st) const {\n"); -+ // generate format string for st->print - // Iterate over the component list & spit out the right thing - uint i = 0; - const char *type = oper->ideal_type(_globalNames); -@@ -1817,9 +1814,7 @@ - // legal base-pointer input. Otherwise it is NOT an oop. - fprintf(fp," const Type *bottom_type() const { return AddPNode::mach_bottom_type(this); } // AddP\n"); - } -- else if ( instr->_ident && ( ! strcmp(instr->_ident,"tlsLoadP") -- || ! strncmp(instr->_ident,"tlsLoadP_",9)) ) { -- // !!!!! -+ else if (instr->is_tls_instruction()) { - // Special hack for tlsLoadP - fprintf(fp," const Type *bottom_type() const { return TypeRawPtr::BOTTOM; } // tlsLoadP\n"); - } -diff -ruNb openjdk6/hotspot/src/share/vm/asm/assembler.cpp openjdk/hotspot/src/share/vm/asm/assembler.cpp ---- openjdk6/hotspot/src/share/vm/asm/assembler.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/asm/assembler.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)assembler.cpp 1.41 07/05/05 17:05:03 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/asm/assembler.hpp openjdk/hotspot/src/share/vm/asm/assembler.hpp ---- openjdk6/hotspot/src/share/vm/asm/assembler.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/asm/assembler.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)assembler.hpp 1.52 07/05/05 17:05:03 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/asm/assembler.inline.hpp openjdk/hotspot/src/share/vm/asm/assembler.inline.hpp ---- openjdk6/hotspot/src/share/vm/asm/assembler.inline.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/asm/assembler.inline.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)assembler.inline.hpp 1.27 07/05/05 17:05:03 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/asm/codeBuffer.cpp openjdk/hotspot/src/share/vm/asm/codeBuffer.cpp ---- openjdk6/hotspot/src/share/vm/asm/codeBuffer.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/asm/codeBuffer.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)codeBuffer.cpp 1.100 07/05/05 17:05:03 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/asm/codeBuffer.hpp openjdk/hotspot/src/share/vm/asm/codeBuffer.hpp ---- openjdk6/hotspot/src/share/vm/asm/codeBuffer.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/asm/codeBuffer.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)codeBuffer.hpp 1.63 07/05/17 15:49:26 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -543,4 +540,3 @@ - if (remaining() < amount) { _outer->expand(this, amount); return true; } - return false; - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/asm/register.cpp openjdk/hotspot/src/share/vm/asm/register.cpp ---- openjdk6/hotspot/src/share/vm/asm/register.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/asm/register.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)register.cpp 1.11 07/05/05 17:05:04 JVM" --#endif - /* - * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/asm/register.hpp openjdk/hotspot/src/share/vm/asm/register.hpp ---- openjdk6/hotspot/src/share/vm/asm/register.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/asm/register.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)register.hpp 1.13 07/05/05 17:05:03 JVM" --#endif - /* - * Copyright 2000-2002 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp openjdk/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp ---- openjdk6/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)c1_CFGPrinter.cpp 1.8 07/05/05 17:05:04 JVM" --#endif - /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_CFGPrinter.hpp openjdk/hotspot/src/share/vm/c1/c1_CFGPrinter.hpp ---- openjdk6/hotspot/src/share/vm/c1/c1_CFGPrinter.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_CFGPrinter.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)c1_CFGPrinter.hpp 1.7 07/05/05 17:05:05 JVM" --#endif - /* - * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -47,4 +44,3 @@ - }; - - #endif -- -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp openjdk/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp ---- openjdk6/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)c1_Canonicalizer.cpp 1.57 07/05/05 17:05:05 JVM" --#endif - /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_Canonicalizer.hpp openjdk/hotspot/src/share/vm/c1/c1_Canonicalizer.hpp ---- openjdk6/hotspot/src/share/vm/c1/c1_Canonicalizer.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_Canonicalizer.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)c1_Canonicalizer.hpp 1.29 07/05/05 17:05:05 JVM" --#endif - /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -97,4 +94,3 @@ - virtual void do_ProfileCall (ProfileCall* x); - virtual void do_ProfileCounter (ProfileCounter* x); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_CodeStubs.hpp openjdk/hotspot/src/share/vm/c1/c1_CodeStubs.hpp ---- openjdk6/hotspot/src/share/vm/c1/c1_CodeStubs.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_CodeStubs.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)c1_CodeStubs.hpp 1.86 07/05/05 17:05:06 JVM" --#endif - /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -485,4 +482,3 @@ - virtual void print_name(outputStream* out) const { out->print("ArrayCopyStub"); } - #endif // PRODUCT - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_Compilation.cpp openjdk/hotspot/src/share/vm/c1/c1_Compilation.cpp ---- openjdk6/hotspot/src/share/vm/c1/c1_Compilation.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_Compilation.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)c1_Compilation.cpp 1.159 07/05/17 15:49:28 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -290,13 +287,16 @@ - } - - void Compilation::install_code(int frame_size) { -+ // frame_size is in 32-bit words so adjust it intptr_t words -+ assert(frame_size == frame_map()->framesize(), "must match"); -+ assert(in_bytes(frame_map()->framesize_in_bytes()) % sizeof(intptr_t) == 0, "must be at least pointer aligned"); - _env->register_method( - method(), - osr_bci(), - &_offsets, - in_bytes(_frame_map->sp_offset_for_orig_pc()), - code(), -- frame_size, -+ in_bytes(frame_map()->framesize_in_bytes()) / sizeof(intptr_t), - debug_info_recorder()->_oopmaps, - exception_handler_table(), - implicit_exception_table(), -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_Compilation.hpp openjdk/hotspot/src/share/vm/c1/c1_Compilation.hpp ---- openjdk6/hotspot/src/share/vm/c1/c1_Compilation.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_Compilation.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)c1_Compilation.hpp 1.88 07/05/17 15:49:31 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_Compiler.cpp openjdk/hotspot/src/share/vm/c1/c1_Compiler.cpp ---- openjdk6/hotspot/src/share/vm/c1/c1_Compiler.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_Compiler.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)c1_Compiler.cpp 1.105 07/05/05 17:05:06 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -89,5 +86,3 @@ - void Compiler::print_timers() { - Compilation::print_timers(); - } -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_Compiler.hpp openjdk/hotspot/src/share/vm/c1/c1_Compiler.hpp ---- openjdk6/hotspot/src/share/vm/c1/c1_Compiler.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_Compiler.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)c1_Compiler.hpp 1.49 07/05/05 17:05:06 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -68,4 +65,3 @@ - // Print compilation timers and statistics - virtual void print_timers(); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_Defs.cpp openjdk/hotspot/src/share/vm/c1/c1_Defs.cpp ---- openjdk6/hotspot/src/share/vm/c1/c1_Defs.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_Defs.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)c1_Defs.cpp 1.10 07/05/05 17:05:06 JVM" --#endif - /* - * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -27,4 +24,3 @@ - - #include "incls/_precompiled.incl" - #include "incls/_c1_Defs.cpp.incl" -- -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_Defs.hpp openjdk/hotspot/src/share/vm/c1/c1_Defs.hpp ---- openjdk6/hotspot/src/share/vm/c1/c1_Defs.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_Defs.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)c1_Defs.hpp 1.22 07/05/05 17:05:05 JVM" --#endif - /* - * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_FpuStackSim.hpp openjdk/hotspot/src/share/vm/c1/c1_FpuStackSim.hpp ---- openjdk6/hotspot/src/share/vm/c1/c1_FpuStackSim.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_FpuStackSim.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)c1_FpuStackSim.hpp 1.7 07/05/05 17:05:06 JVM" --#endif - /* - * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -30,4 +27,3 @@ - class FpuStackSim; - - # include "incls/_c1_FpuStackSim_pd.hpp.incl" // platform dependent declarations -- -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_FrameMap.cpp openjdk/hotspot/src/share/vm/c1/c1_FrameMap.cpp ---- openjdk6/hotspot/src/share/vm/c1/c1_FrameMap.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_FrameMap.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)c1_FrameMap.cpp 1.37 07/05/05 17:05:06 JVM" --#endif - /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -83,7 +80,8 @@ - args->append(opr); - if (opr->is_address()) { - LIR_Address* addr = opr->as_address_ptr(); -- out_preserve = MAX2(out_preserve, addr->disp() / 4); -+ assert(addr->disp() == (int)addr->disp(), "out of range value"); -+ out_preserve = MAX2(out_preserve, (intptr_t)addr->disp() / 4); - } - i += type2size[t]; - } -@@ -128,10 +126,13 @@ - // C calls are always outgoing - bool outgoing = true; - LIR_Opr opr = map_to_opr(t, regs + i, outgoing); -+ // they might be of different types if for instance floating point -+ // values are passed in cpu registers, but the sizes must match. -+ assert(type2size[opr->type()] == type2size[t], "type mismatch"); - args->append(opr); - if (opr->is_address()) { - LIR_Address* addr = opr->as_address_ptr(); -- out_preserve = MAX2(out_preserve, addr->disp() / 4); -+ out_preserve = MAX2(out_preserve, (intptr_t)addr->disp() / 4); - } - i += type2size[t]; - } -@@ -172,7 +173,7 @@ - LIR_Opr opr = _incoming_arguments->at(i); - if (opr->is_address()) { - LIR_Address* address = opr->as_address_ptr(); -- _argument_locations->at_put(java_index, address->disp()); -+ _argument_locations->at_put(java_index, address->disp() - STACK_BIAS); - _incoming_arguments->args()->at_put(i, LIR_OprFact::stack(java_index, as_BasicType(as_ValueType(address->type())))); - } - java_index += type2size[opr->type()]; -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_FrameMap.hpp openjdk/hotspot/src/share/vm/c1/c1_FrameMap.hpp ---- openjdk6/hotspot/src/share/vm/c1/c1_FrameMap.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_FrameMap.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)c1_FrameMap.hpp 1.59 07/05/05 17:05:07 JVM" --#endif - /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp openjdk/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp ---- openjdk6/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)c1_GraphBuilder.cpp 1.255 07/05/17 15:49:34 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -88,8 +85,8 @@ - , _blocks(16) - , _bci2block(new BlockList(scope->method()->code_size(), NULL)) - , _next_block_number(0) -- , _active(NULL, 0) // size not known yet -- , _visited(NULL, 0) // size not known yet -+ , _active() // size not known yet -+ , _visited() // size not known yet - , _next_loop_index(0) - , _loop_map() // size not known yet - { -@@ -413,7 +410,7 @@ - - if (block->is_set(BlockBegin::parser_loop_header_flag)) { - int header_loop_state = _loop_map.at(block_id); -- assert(is_power_of_2(header_loop_state), "exactly one bit must be set"); -+ assert(is_power_of_2((unsigned)header_loop_state), "exactly one bit must be set"); - - // If the highest bit is set (i.e. when integer value is negative), the method - // has 32 or more loops. This bit is never cleared because it is used for multiple loops -@@ -3666,12 +3663,14 @@ - _scope_data = scope_data()->parent(); - } - -- - bool GraphBuilder::append_unsafe_get_obj(ciMethod* callee, BasicType t, bool is_volatile) { - if (InlineUnsafeOps) { - Values* args = state()->pop_arguments(callee->arg_size()); - null_check(args->at(0)); -- Instruction* offset = append(new Convert(Bytecodes::_l2i, args->at(2), as_ValueType(T_INT))); -+ Instruction* offset = args->at(2); -+#ifndef _LP64 -+ offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT))); -+#endif - Instruction* op = append(new UnsafeGetObject(t, args->at(1), offset, is_volatile)); - push(op->type(), op); - compilation()->set_has_unsafe_access(true); -@@ -3684,7 +3683,10 @@ - if (InlineUnsafeOps) { - Values* args = state()->pop_arguments(callee->arg_size()); - null_check(args->at(0)); -- Instruction* offset = append(new Convert(Bytecodes::_l2i, args->at(2), as_ValueType(T_INT))); -+ Instruction* offset = args->at(2); -+#ifndef _LP64 -+ offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT))); -+#endif - Instruction* op = append(new UnsafePutObject(t, args->at(1), offset, args->at(3), is_volatile)); - compilation()->set_has_unsafe_access(true); - kill_all(); -@@ -3725,7 +3727,10 @@ - } else { - null_check(args->at(0)); - } -- Instruction* offset = append(new Convert(Bytecodes::_l2i, args->at(obj_arg_index + 1), as_ValueType(T_INT))); -+ Instruction* offset = args->at(obj_arg_index + 1); -+#ifndef _LP64 -+ offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT))); -+#endif - Instruction* op = is_store ? append(new UnsafePrefetchWrite(args->at(obj_arg_index), offset)) - : append(new UnsafePrefetchRead (args->at(obj_arg_index), offset)); - compilation()->set_has_unsafe_access(true); -@@ -3742,7 +3747,7 @@ - // Pop off some args to speically handle, then push back - Value newval = args->pop(); - Value cmpval = args->pop(); -- Value long_offset = args->pop(); -+ Value offset = args->pop(); - Value src = args->pop(); - Value unsafe_obj = args->pop(); - -@@ -3750,7 +3755,9 @@ - // generation, but must be null checked - null_check(unsafe_obj); - -- Instruction* offset = append(new Convert(Bytecodes::_l2i, long_offset, as_ValueType(T_INT))); -+#ifndef _LP64 -+ offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT))); -+#endif - - args->push(src); - args->push(offset); -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp openjdk/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp ---- openjdk6/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)c1_GraphBuilder.hpp 1.75 07/05/17 15:49:37 JVM" --#endif - /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -391,4 +388,3 @@ - - BlockBegin* start() const { return _start; } - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_IR.cpp openjdk/hotspot/src/share/vm/c1/c1_IR.cpp ---- openjdk6/hotspot/src/share/vm/c1/c1_IR.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_IR.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)c1_IR.cpp 1.160 07/05/05 17:05:04 JVM" --#endif - /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_IR.hpp openjdk/hotspot/src/share/vm/c1/c1_IR.hpp ---- openjdk6/hotspot/src/share/vm/c1/c1_IR.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_IR.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)c1_IR.hpp 1.100 07/05/05 17:05:04 JVM" --#endif - /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_Instruction.cpp openjdk/hotspot/src/share/vm/c1/c1_Instruction.cpp ---- openjdk6/hotspot/src/share/vm/c1/c1_Instruction.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_Instruction.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)c1_Instruction.cpp 1.90 07/05/05 17:05:05 JVM" --#endif - /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_Instruction.hpp openjdk/hotspot/src/share/vm/c1/c1_Instruction.hpp ---- openjdk6/hotspot/src/share/vm/c1/c1_Instruction.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_Instruction.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)c1_Instruction.hpp 1.195 07/05/05 17:05:07 JVM" --#endif - /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -1528,16 +1525,16 @@ - , _exception_handler_pco(-1) - , _lir(NULL) - , _loop_index(-1) -- , _live_in(NULL, 0) -- , _live_out(NULL, 0) -- , _live_gen(NULL, 0) -- , _live_kill(NULL, 0) -- , _fpu_register_usage(NULL, 0) -+ , _live_in() -+ , _live_out() -+ , _live_gen() -+ , _live_kill() -+ , _fpu_register_usage() - , _fpu_stack_state(NULL) - , _first_lir_instruction_id(-1) - , _last_lir_instruction_id(-1) - , _total_preds(0) -- , _stores_to_locals(NULL, 0) -+ , _stores_to_locals() - { - set_bci(bci); - } -@@ -1962,7 +1959,11 @@ - LEAF(OsrEntry, Instruction) - public: - // creation -+#ifdef _LP64 -+ OsrEntry() : Instruction(longType, false) { pin(); } -+#else - OsrEntry() : Instruction(intType, false) { pin(); } -+#endif - - // generic - virtual void input_values_do(void f(Value*)) { } -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp openjdk/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp ---- openjdk6/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)c1_InstructionPrinter.cpp 1.125 07/05/17 15:49:39 JVM" --#endif - /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -269,6 +266,8 @@ - void InstructionPrinter::print_unsafe_object_op(UnsafeObjectOp* op, const char* name) { - print_unsafe_op(op, name); - print_value(op->object()); -+ output()->print(", "); -+ print_value(op->offset()); - } - - -@@ -849,4 +848,3 @@ - - - #endif // PRODUCT -- -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_InstructionPrinter.hpp openjdk/hotspot/src/share/vm/c1/c1_InstructionPrinter.hpp ---- openjdk6/hotspot/src/share/vm/c1/c1_InstructionPrinter.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_InstructionPrinter.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)c1_InstructionPrinter.hpp 1.65 07/05/05 17:05:07 JVM" --#endif - /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_LIR.cpp openjdk/hotspot/src/share/vm/c1/c1_LIR.cpp ---- openjdk6/hotspot/src/share/vm/c1/c1_LIR.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_LIR.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)c1_LIR.cpp 1.118 07/05/05 17:05:04 JVM" --#endif - /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -126,10 +123,17 @@ - assert(scale() == times_1, "Scaled addressing mode not available on SPARC and should not be used"); - assert(disp() == 0 || index()->is_illegal(), "can't have both"); - #endif -+#ifdef _LP64 -+ assert(base()->is_cpu_register(), "wrong base operand"); -+ assert(index()->is_illegal() || index()->is_double_cpu(), "wrong index operand"); -+ assert(base()->type() == T_OBJECT || base()->type() == T_LONG, -+ "wrong type for addresses"); -+#else - assert(base()->is_single_cpu(), "wrong base operand"); - assert(index()->is_illegal() || index()->is_single_cpu(), "wrong index operand"); - assert(base()->type() == T_OBJECT || base()->type() == T_INT, - "wrong type for addresses"); -+#endif - } - #endif - -@@ -183,7 +187,6 @@ - case T_INT: - case T_OBJECT: - case T_ARRAY: -- case T_ADDRESS: - assert((kind_field() == cpu_register || kind_field() == stack_value) && size_field() == single_size, "must match"); - break; - -@@ -216,6 +219,15 @@ - - void LIR_Op2::verify() const { - #ifdef ASSERT -+ switch (code()) { -+ case lir_cmove: -+ break; -+ -+ default: -+ assert(!result_opr()->is_register() || !result_opr()->is_oop_register(), -+ "can't produce oops from arith"); -+ } -+ - if (TwoOperandLIRForm) { - switch (code()) { - case lir_add: -@@ -229,7 +241,6 @@ - case lir_logic_or: - case lir_logic_xor: - case lir_shl: -- case lir_shlx: - case lir_shr: - assert(in_opr1() == result_opr(), "opr1 and result must match"); - assert(in_opr1()->is_valid() && in_opr2()->is_valid(), "must be valid"); -@@ -561,7 +572,6 @@ - case lir_logic_or: - case lir_logic_xor: - case lir_shl: -- case lir_shlx: - case lir_shr: - case lir_ushr: - { -@@ -1567,7 +1577,6 @@ - case lir_logic_or: s = "logic_or"; break; - case lir_logic_xor: s = "logic_xor"; break; - case lir_shl: s = "shift_left"; break; -- case lir_shlx: s = "shift_left_long";break; - case lir_shr: s = "shift_right"; break; - case lir_ushr: s = "ushift_right"; break; - case lir_alloc_array: s = "alloc_array"; break; -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_LIR.hpp openjdk/hotspot/src/share/vm/c1/c1_LIR.hpp ---- openjdk6/hotspot/src/share/vm/c1/c1_LIR.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_LIR.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)c1_LIR.hpp 1.133 07/05/05 17:05:05 JVM" --#endif - /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -95,6 +92,15 @@ - LIR_Const(jfloat f) { _value.set_type(T_FLOAT); _value.set_jfloat(f); } - LIR_Const(jdouble d) { _value.set_type(T_DOUBLE); _value.set_jdouble(d); } - LIR_Const(jobject o) { _value.set_type(T_OBJECT); _value.set_jobject(o); } -+ LIR_Const(void* p) { -+#ifdef _LP64 -+ assert(sizeof(jlong) >= sizeof(p), "too small");; -+ _value.set_type(T_LONG); _value.set_jlong((jlong)p); -+#else -+ assert(sizeof(jint) >= sizeof(p), "too small");; -+ _value.set_type(T_INT); _value.set_jint((jint)p); -+#endif -+ } - - virtual BasicType type() const { return _value.get_type(); } - virtual LIR_Const* as_constant() { return this; } -@@ -107,6 +113,13 @@ - jint as_jint_lo() const { type_check(T_LONG ); return low(_value.get_jlong()); } - jint as_jint_hi() const { type_check(T_LONG ); return high(_value.get_jlong()); } - -+#ifdef _LP64 -+ address as_pointer() const { type_check(T_LONG ); return (address)_value.get_jlong(); } -+#else -+ address as_pointer() const { type_check(T_INT ); return (address)_value.get_jint(); } -+#endif -+ -+ - jint as_jint_bits() const { type_check(T_FLOAT, T_INT); return _value.get_jint(); } - jint as_jint_lo_bits() const { - if (type() == T_DOUBLE) { -@@ -244,8 +257,6 @@ - OprKind kind_field() const { return (OprKind)(value() & kind_mask); } - OprSize size_field() const { return (OprSize)(value() & size_mask); } - -- intptr_t value_without_type() const { return is_illegal() ? value() : value() & no_type_mask; } -- - static char type_char(BasicType t); - - public: -@@ -286,7 +297,6 @@ - case T_INT: - case T_OBJECT: - case T_ARRAY: -- case T_ADDRESS: - return single_size; - break; - -@@ -296,12 +306,6 @@ - } - - -- // returns a new LIR_Opr with the OprType of from and all other information the current LIR_Opr -- LIR_Opr with_type_of(LIR_Opr from) { -- assert(!is_pointer() && !from->is_pointer(), "only simple LIR_Oprs"); -- return (LIR_Opr)(from->type_field() | value_without_type()); -- } -- - void validate_type() const PRODUCT_RETURN; - - BasicType type() const { -@@ -316,23 +320,17 @@ - - char type_char() const { return type_char((is_pointer()) ? pointer()->type() : type()); } - -- bool is_same(LIR_Opr opr) const { return this == opr; } -- // checks whether types are same or one type is unknown -- bool is_type_compatible(LIR_Opr opr) const { -- return type_field() == unknown_type || -- opr->type_field() == unknown_type || -- type_field() == opr->type_field(); -- } -- -- // is_type_compatible and equal -- bool is_equivalent(LIR_Opr opr) const { -- if (!is_pointer()) { -- if (is_type_compatible(opr) && data() == opr->data() && kind_field() == opr->kind_field() && is_xmm_register() == opr->is_xmm_register()) { -- return true; -- } -- } -- // could also do checks for other pointers types -- return is_same(opr); -+ bool is_equal(LIR_Opr opr) const { return this == opr; } -+ // checks whether types are same -+ bool is_same_type(LIR_Opr opr) const { -+ assert(type_field() != unknown_type && -+ opr->type_field() != unknown_type, "shouldn't see unknown_type"); -+ return type_field() == opr->type_field(); -+ } -+ bool is_same_register(LIR_Opr opr) { -+ return (is_register() && opr->is_register() && -+ kind_field() == opr->kind_field() && -+ (value() & no_type_mask) == (opr->value() & no_type_mask)); - } - - bool is_pointer() const { return check_value_mask(pointer_mask, pointer_value); } -@@ -409,6 +407,16 @@ - Register as_register_lo() const; - Register as_register_hi() const; - -+ Register as_pointer_register() { -+#ifdef _LP64 -+ if (is_double_cpu()) { -+ assert(as_register_lo() == as_register_hi(), "should be a single register"); -+ return as_register_lo(); -+ } -+#endif -+ return as_register(); -+ } -+ - #ifdef IA32 - XMMRegister as_xmm_float_reg() const; - XMMRegister as_xmm_double_reg() const; -@@ -606,6 +614,8 @@ - static LIR_Opr doubleConst(jdouble d) { return (LIR_Opr)(new LIR_Const(d)); } - static LIR_Opr oopConst(jobject o) { return (LIR_Opr)(new LIR_Const(o)); } - static LIR_Opr address(LIR_Address* a) { return (LIR_Opr)a; } -+ static LIR_Opr intptrConst(void* p) { return (LIR_Opr)(new LIR_Const(p)); } -+ static LIR_Opr intptrConst(intptr_t v) { return (LIR_Opr)(new LIR_Const((void*)v)); } - static LIR_Opr illegal() { return (LIR_Opr)-1; } - - static LIR_Opr value_type(ValueType* type); -@@ -713,7 +723,6 @@ - , lir_logic_or - , lir_logic_xor - , lir_shl -- , lir_shlx - , lir_shr - , lir_ushr - , lir_alloc_array -@@ -1534,7 +1543,6 @@ - virtual void print_instr(outputStream* out) const PRODUCT_RETURN; - }; - -- - // LIR_OpProfileCall - class LIR_OpProfileCall : public LIR_Op { - friend class LIR_OpVisitState; -@@ -1573,7 +1581,6 @@ - - class LIR_InsertionBuffer; - -- - //--------------------------------LIR_List--------------------------------------------------- - // Maintains a list of LIR instructions (one instance of LIR_List per basic block) - // The LIR instructions are appended by the LIR_List class itself; -@@ -2025,4 +2032,3 @@ - - - inline LIR_Opr LIR_OprDesc::illegalOpr() { return LIR_OprFact::illegalOpr; }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp openjdk/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp ---- openjdk6/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)c1_LIRAssembler.cpp 1.133 07/05/05 17:05:08 JVM" --#endif - /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -218,7 +215,7 @@ - #endif /* PRODUCT */ - - assert(block->lir() != NULL, "must have LIR"); -- IA32_ONLY(assert(_masm->esp_offset() == 0, "frame size should be fixed")); -+ IA32_ONLY(assert(_masm->rsp_offset() == 0, "frame size should be fixed")); - - #ifndef PRODUCT - if (CommentedAssembly) { -@@ -230,7 +227,7 @@ - - emit_lir_list(block->lir()); - -- IA32_ONLY(assert(_masm->esp_offset() == 0, "frame size should be fixed")); -+ IA32_ONLY(assert(_masm->rsp_offset() == 0, "frame size should be fixed")); - } - - -@@ -649,7 +646,6 @@ - break; - - case lir_shl: -- case lir_shlx: - case lir_shr: - case lir_ushr: - if (op->in_opr2()->is_constant()) { -@@ -787,7 +783,7 @@ - _masm->verify_oop(r->as_Register()); - #endif - } else { -- _masm->verify_stack_oop(r->reg2stack() * wordSize); -+ _masm->verify_stack_oop(r->reg2stack() * VMRegImpl::stack_slot_size); - } - } - s.next(); -@@ -796,6 +792,3 @@ - } - #endif - } -- -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp openjdk/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp ---- openjdk6/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)c1_LIRAssembler.hpp 1.116 07/05/05 17:05:08 JVM" --#endif - /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp openjdk/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp ---- openjdk6/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)c1_LIRGenerator.cpp 1.22 07/05/17 15:49:41 JVM" --#endif - /* - * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -810,9 +807,10 @@ - - - LIR_Opr LIRGenerator::force_to_spill(LIR_Opr value, BasicType t) { -+ assert(type2size[t] == type2size[value->type()], "size mismatch"); - if (!value->is_register()) { - // force into a register -- LIR_Opr r = new_register(t); -+ LIR_Opr r = new_register(value->type()); - __ move(value, r); - value = r; - } -@@ -991,34 +989,6 @@ - } - - --void LIRGenerator::write_barrier(LIR_Opr addr) { -- if (addr->is_address()) { -- LIR_Address* address = (LIR_Address*)addr; -- LIR_Opr ptr = new_register(T_OBJECT); -- if (!address->index()->is_valid() && address->disp() == 0) { -- __ move(address->base(), ptr); -- } else { -- __ leal(addr, ptr); -- } -- addr = ptr; -- } -- assert(addr->is_register(), "must be a register at this point"); -- -- LIR_Opr tmp = new_register(T_OBJECT); -- if (TwoOperandLIRForm) { -- __ move(addr, tmp); -- __ unsigned_shift_right(tmp, CardTableModRefBS::card_shift, tmp); -- } else { -- __ unsigned_shift_right(addr, CardTableModRefBS::card_shift, tmp); -- } -- if (can_inline_as_constant(card_table_base())) { -- __ move(LIR_OprFact::intConst(0), new LIR_Address(tmp, card_table_base()->as_jint(), T_BYTE)); -- } else { -- __ move(LIR_OprFact::intConst(0), new LIR_Address(tmp, load_constant(card_table_base()), T_BYTE)); -- } --} -- -- - void LIRGenerator::do_ExceptionObject(ExceptionObject* x) { - assert(block()->is_set(BlockBegin::exception_entry_flag), "ExceptionObject only allowed in exception handler block"); - assert(block()->next() == x, "ExceptionObject must be first instruction of block"); -@@ -1267,6 +1237,58 @@ - return result; - } - -+// Various barriers -+ -+void LIRGenerator::post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) { -+ switch (Universe::heap()->barrier_set()->kind()) { -+ case BarrierSet::CardTableModRef: -+ case BarrierSet::CardTableExtension: -+ CardTableModRef_post_barrier(addr, new_val); -+ break; -+ case BarrierSet::ModRef: -+ case BarrierSet::Other: -+ // No post barriers -+ break; -+ default : -+ ShouldNotReachHere(); -+ } -+} -+ -+void LIRGenerator::CardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val) { -+ -+ BarrierSet* bs = Universe::heap()->barrier_set(); -+ assert(sizeof(*((CardTableModRefBS*)bs)->byte_map_base) == sizeof(jbyte), "adjust this code"); -+ LIR_Const* card_table_base = new LIR_Const(((CardTableModRefBS*)bs)->byte_map_base); -+ if (addr->is_address()) { -+ LIR_Address* address = addr->as_address_ptr(); -+ LIR_Opr ptr = new_register(T_OBJECT); -+ if (!address->index()->is_valid() && address->disp() == 0) { -+ __ move(address->base(), ptr); -+ } else { -+ assert(address->disp() != max_jint, "lea doesn't support patched addresses!"); -+ __ leal(addr, ptr); -+ } -+ addr = ptr; -+ } -+ assert(addr->is_register(), "must be a register at this point"); -+ -+ LIR_Opr tmp = new_pointer_register(); -+ if (TwoOperandLIRForm) { -+ __ move(addr, tmp); -+ __ unsigned_shift_right(tmp, CardTableModRefBS::card_shift, tmp); -+ } else { -+ __ unsigned_shift_right(addr, CardTableModRefBS::card_shift, tmp); -+ } -+ if (can_inline_as_constant(card_table_base)) { -+ __ move(LIR_OprFact::intConst(0), -+ new LIR_Address(tmp, card_table_base->as_jint(), T_BYTE)); -+ } else { -+ __ move(LIR_OprFact::intConst(0), -+ new LIR_Address(tmp, load_constant(card_table_base), -+ T_BYTE)); -+ } -+} -+ - - //------------------------field access-------------------------------------- - -@@ -1302,6 +1324,7 @@ - bool needs_patching = x->needs_patching(); - bool is_volatile = x->field()->is_volatile(); - BasicType field_type = x->field_type(); -+ bool is_oop = (field_type == T_ARRAY || field_type == T_OBJECT); - - CodeEmitInfo* info = NULL; - if (needs_patching) { -@@ -1374,8 +1397,8 @@ - __ store(value.result(), address, info, patch_code); - } - -- if (field_type == T_ARRAY || field_type == T_OBJECT) { -- write_barrier(object.result()); -+ if (is_oop) { -+ post_barrier(object.result(), value.result()); - } - - if (is_volatile && os::is_MP()) { -@@ -1677,12 +1700,14 @@ - assert(!x->has_index() || idx.value() == x->index(), "should match"); - - LIR_Opr base_op = base.result(); -+#ifndef _LP64 - if (x->base()->type()->tag() == longTag) { - base_op = new_register(T_INT); - __ convert(Bytecodes::_l2i, base.result(), base_op); - } else { - assert(x->base()->type()->tag() == intTag, "must be"); - } -+#endif - - BasicType dst_type = x->basic_type(); - LIR_Opr index_op = idx.result(); -@@ -1740,8 +1765,15 @@ - - set_no_result(x); - -- LIR_Opr intBase = new_register(T_INT); -- __ convert(Bytecodes::_l2i, base.result(), intBase); -+ LIR_Opr base_op = base.result(); -+#ifndef _LP64 -+ if (x->base()->type()->tag() == longTag) { -+ base_op = new_register(T_INT); -+ __ convert(Bytecodes::_l2i, base.result(), base_op); -+ } else { -+ assert(x->base()->type()->tag() == intTag, "must be"); -+ } -+#endif - - LIR_Opr index_op = idx.result(); - if (log2_scale != 0) { -@@ -1751,7 +1783,7 @@ - __ shift_left(index_op, log2_scale, index_op); - } - -- LIR_Address* addr = new LIR_Address(intBase, index_op, x->basic_type()); -+ LIR_Address* addr = new LIR_Address(base_op, index_op, x->basic_type()); - __ move(value.result(), addr); - } - -@@ -2182,7 +2214,7 @@ - - // emit invoke code - bool optimized = x->target_is_loaded() && x->target_is_final(); -- assert(receiver->is_illegal() || receiver->is_equivalent(LIR_Assembler::receiverOpr()), "must match"); -+ assert(receiver->is_illegal() || receiver->is_equal(LIR_Assembler::receiverOpr()), "must match"); - - switch (x->code()) { - case Bytecodes::_invokestatic: -@@ -2500,5 +2532,3 @@ - } - #endif - } -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp openjdk/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp ---- openjdk6/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)c1_LIRGenerator.hpp 1.13 07/05/05 17:05:07 JVM" --#endif - /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -252,6 +249,19 @@ - LIR_Opr call_runtime(Value arg1, address entry, ValueType* result_type, CodeEmitInfo* info); - LIR_Opr call_runtime(Value arg1, Value arg2, address entry, ValueType* result_type, CodeEmitInfo* info); - -+ // GC Barriers -+ -+ // generic interface -+ -+ void post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val); -+ -+ // specific implementations -+ -+ // post barriers -+ -+ void CardTableModRef_post_barrier(LIR_OprDesc* addr, LIR_OprDesc* new_val); -+ -+ - static LIR_Opr result_register_for(ValueType* type, bool callee = false); - - ciObject* get_jobject_constant(Value value); -@@ -325,8 +335,6 @@ - } - LIR_Address* emit_array_address(LIR_Opr array_opr, LIR_Opr index_opr, BasicType type, bool needs_card_mark); - -- void write_barrier(LIR_Opr addr); -- - // machine preferences and characteristics - bool can_inline_as_constant(Value i) const; - bool can_inline_as_constant(LIR_Const* c) const; -@@ -360,6 +368,15 @@ - LIR_Opr new_register(Value value) { return new_register(as_BasicType(value->type())); } - LIR_Opr new_register(ValueType* type) { return new_register(as_BasicType(type)); } - -+ // returns a register suitable for doing pointer math -+ LIR_Opr new_pointer_register() { -+#ifdef _LP64 -+ return new_register(T_LONG); -+#else -+ return new_register(T_INT); -+#endif -+ } -+ - static LIR_Condition lir_cond(If::Condition cond) { - LIR_Condition l; - switch (cond) { -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_LinearScan.cpp openjdk/hotspot/src/share/vm/c1/c1_LinearScan.cpp ---- openjdk6/hotspot/src/share/vm/c1/c1_LinearScan.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_LinearScan.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)c1_LinearScan.cpp 1.12 07/05/05 17:05:10 JVM" --#endif - /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -2547,8 +2544,8 @@ - } else { - // double-size operands - -- LocationValue* first; -- LocationValue* second; -+ ScopeValue* first; -+ ScopeValue* second; - - if (opr->is_double_stack()) { - Location loc1, loc2; -@@ -2559,6 +2556,11 @@ - second = new LocationValue(loc2); - - } else if (opr->is_double_cpu()) { -+#ifdef _LP64 -+ VMReg rname_first = opr->as_register_lo()->as_VMReg(); -+ first = new LocationValue(Location::new_reg_loc(Location::lng, rname_first)); -+ second = &_int_0_scope_value; -+#else - VMReg rname_first = opr->as_register_lo()->as_VMReg(); - VMReg rname_second = opr->as_register_hi()->as_VMReg(); - -@@ -2571,6 +2573,7 @@ - - first = new LocationValue(Location::new_reg_loc(Location::normal, rname_first)); - second = new LocationValue(Location::new_reg_loc(Location::normal, rname_second)); -+#endif - - #ifdef IA32 - } else if (opr->is_double_xmm()) { -@@ -2862,15 +2865,21 @@ - op->verify(); - #endif - -+#ifndef _LP64 - // remove useless moves - if (op->code() == lir_move) { - assert(op->as_Op1() != NULL, "move must be LIR_Op1"); - LIR_Op1* move = (LIR_Op1*)op; -- if (!move->result_opr()->is_pointer() && !move->in_opr()->is_pointer() && move->in_opr()->is_equivalent(move->result_opr()->with_type_of(move->in_opr()))) { -+ LIR_Opr src = move->in_opr(); -+ LIR_Opr dst = move->result_opr(); -+ if (dst == src || -+ !dst->is_pointer() && !src->is_pointer() && -+ src->is_same_register(dst)) { - instructions->at_put(j, NULL); - has_dead = true; - } - } -+#endif - } - - if (has_dead) { -@@ -6187,6 +6196,7 @@ - case counter_move_reg_reg: return "register->register"; - case counter_move_reg_stack: return "register->stack"; - case counter_move_stack_reg: return "stack->register"; -+ case counter_move_stack_stack:return "stack->stack"; - case counter_move_reg_mem: return "register->memory"; - case counter_move_mem_reg: return "memory->register"; - case counter_move_const_any: return "constant->any"; -@@ -6333,8 +6343,11 @@ - ShouldNotReachHere(); - } - } else if (in->is_stack()) { -- assert(res->is_register(), "must be"); -+ if (res->is_register()) { - inc_counter(counter_move_stack_reg); -+ } else { -+ inc_counter(counter_move_stack_stack); -+ } - } else if (in->is_address()) { - assert(res->is_register(), "must be"); - inc_counter(counter_move_mem_reg); -@@ -6379,7 +6392,6 @@ - case lir_logic_or: - case lir_logic_xor: - case lir_shl: -- case lir_shlx: - case lir_shr: - case lir_ushr: inc_counter(counter_alu); break; - -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_LinearScan.hpp openjdk/hotspot/src/share/vm/c1/c1_LinearScan.hpp ---- openjdk6/hotspot/src/share/vm/c1/c1_LinearScan.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_LinearScan.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)c1_LinearScan.hpp 1.12 07/05/05 17:05:09 JVM" --#endif - /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -890,6 +887,7 @@ - counter_move_reg_reg, - counter_move_reg_stack, - counter_move_stack_reg, -+ counter_move_stack_stack, - counter_move_reg_mem, - counter_move_mem_reg, - counter_move_const_any, -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_MacroAssembler.hpp openjdk/hotspot/src/share/vm/c1/c1_MacroAssembler.hpp ---- openjdk6/hotspot/src/share/vm/c1/c1_MacroAssembler.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_MacroAssembler.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)c1_MacroAssembler.hpp 1.23 07/05/05 17:05:08 JVM" --#endif - /* - * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -83,5 +80,3 @@ - int call_RT(Register oop_result1, Register oop_result2, address entry, Register arg1, Register arg2); - int call_RT(Register oop_result1, Register oop_result2, address entry, Register arg1, Register arg2, Register arg3); - }; -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_Optimizer.cpp openjdk/hotspot/src/share/vm/c1/c1_Optimizer.cpp ---- openjdk6/hotspot/src/share/vm/c1/c1_Optimizer.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_Optimizer.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)c1_Optimizer.cpp 1.71 07/05/05 17:05:09 JVM" --#endif - /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_Optimizer.hpp openjdk/hotspot/src/share/vm/c1/c1_Optimizer.hpp ---- openjdk6/hotspot/src/share/vm/c1/c1_Optimizer.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_Optimizer.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)c1_Optimizer.hpp 1.16 07/05/05 17:05:09 JVM" --#endif - /* - * Copyright 1999-2001 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -38,4 +35,3 @@ - void eliminate_blocks(); - void eliminate_null_checks(); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_Runtime1.cpp openjdk/hotspot/src/share/vm/c1/c1_Runtime1.cpp ---- openjdk6/hotspot/src/share/vm/c1/c1_Runtime1.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_Runtime1.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)c1_Runtime1.cpp 1.244 07/06/01 13:28:38 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_Runtime1.hpp openjdk/hotspot/src/share/vm/c1/c1_Runtime1.hpp ---- openjdk6/hotspot/src/share/vm/c1/c1_Runtime1.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_Runtime1.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)c1_Runtime1.hpp 1.140 07/05/17 15:49:48 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_ValueMap.cpp openjdk/hotspot/src/share/vm/c1/c1_ValueMap.cpp ---- openjdk6/hotspot/src/share/vm/c1/c1_ValueMap.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_ValueMap.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)c1_ValueMap.cpp 1.29 07/05/05 17:05:08 JVM" --#endif - /* - * Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_ValueMap.hpp openjdk/hotspot/src/share/vm/c1/c1_ValueMap.hpp ---- openjdk6/hotspot/src/share/vm/c1/c1_ValueMap.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_ValueMap.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)c1_ValueMap.hpp 1.22 07/05/05 17:05:07 JVM" --#endif - /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_ValueSet.cpp openjdk/hotspot/src/share/vm/c1/c1_ValueSet.cpp ---- openjdk6/hotspot/src/share/vm/c1/c1_ValueSet.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_ValueSet.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)c1_ValueSet.cpp 1.12 07/05/05 17:05:09 JVM" --#endif - /* - * Copyright 2001-2002 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_ValueSet.hpp openjdk/hotspot/src/share/vm/c1/c1_ValueSet.hpp ---- openjdk6/hotspot/src/share/vm/c1/c1_ValueSet.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_ValueSet.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)c1_ValueSet.hpp 1.15 07/05/05 17:05:09 JVM" --#endif - /* - * Copyright 2001-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_ValueStack.cpp openjdk/hotspot/src/share/vm/c1/c1_ValueStack.cpp ---- openjdk6/hotspot/src/share/vm/c1/c1_ValueStack.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_ValueStack.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)c1_ValueStack.cpp 1.65 07/05/05 17:05:09 JVM" --#endif - /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -286,4 +283,3 @@ - Unimplemented(); - } - #endif // PRODUCT -- -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_ValueStack.hpp openjdk/hotspot/src/share/vm/c1/c1_ValueStack.hpp ---- openjdk6/hotspot/src/share/vm/c1/c1_ValueStack.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_ValueStack.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)c1_ValueStack.hpp 1.51 07/05/05 17:05:10 JVM" --#endif - /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_ValueType.cpp openjdk/hotspot/src/share/vm/c1/c1_ValueType.cpp ---- openjdk6/hotspot/src/share/vm/c1/c1_ValueType.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_ValueType.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)c1_ValueType.cpp 1.22 07/05/05 17:05:10 JVM" --#endif - /* - * Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_ValueType.hpp openjdk/hotspot/src/share/vm/c1/c1_ValueType.hpp ---- openjdk6/hotspot/src/share/vm/c1/c1_ValueType.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_ValueType.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)c1_ValueType.hpp 1.35 07/05/05 17:05:10 JVM" --#endif - /* - * Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_globals.cpp openjdk/hotspot/src/share/vm/c1/c1_globals.cpp ---- openjdk6/hotspot/src/share/vm/c1/c1_globals.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_globals.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)c1_globals.cpp 1.11 07/05/05 17:05:09 JVM" --#endif - /* - * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/c1/c1_globals.hpp openjdk/hotspot/src/share/vm/c1/c1_globals.hpp ---- openjdk6/hotspot/src/share/vm/c1/c1_globals.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/c1/c1_globals.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)c1_globals.hpp 1.104 07/05/05 17:05:10 JVM" --#endif - /* - * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -333,4 +330,3 @@ - // #include "incls/_c1_globals_pd.hpp.incl" - - C1_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_NOTPRODUCT_FLAG) -- -diff -ruNb openjdk6/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp openjdk/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp ---- openjdk6/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)bcEscapeAnalyzer.cpp 1.7 07/05/17 15:49:50 JVM" --#endif - /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -1322,4 +1319,3 @@ - deps->assert_unique_concrete_method(k, m); - } - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/ci/bcEscapeAnalyzer.hpp openjdk/hotspot/src/share/vm/ci/bcEscapeAnalyzer.hpp ---- openjdk6/hotspot/src/share/vm/ci/bcEscapeAnalyzer.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/bcEscapeAnalyzer.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)bcEscapeAnalyzer.hpp 1.6 07/05/05 17:05:11 JVM" --#endif - /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciArray.cpp openjdk/hotspot/src/share/vm/ci/ciArray.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciArray.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciArray.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciArray.cpp 1.12 07/05/05 17:05:11 JVM" --#endif - /* - * Copyright 1999-2000 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -37,7 +34,7 @@ - // ciArray::print_impl - // - // Implementation of the print method. --void ciArray::print_impl() { -- tty->print(" length=%d type=", length()); -- klass()->print(); -+void ciArray::print_impl(outputStream* st) { -+ st->print(" length=%d type=", length()); -+ klass()->print(st); - } -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciArray.hpp openjdk/hotspot/src/share/vm/ci/ciArray.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciArray.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciArray.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciArray.hpp 1.12 07/05/05 17:05:11 JVM" --#endif - /* - * Copyright 1999-2001 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -44,7 +41,7 @@ - - const char* type_string() { return "ciArray"; } - -- void print_impl(); -+ void print_impl(outputStream* st); - - public: - int length() { return _length; } -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciArrayKlass.cpp openjdk/hotspot/src/share/vm/ci/ciArrayKlass.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciArrayKlass.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciArrayKlass.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciArrayKlass.cpp 1.14 07/05/05 17:05:12 JVM" --#endif - /* - * Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciArrayKlass.hpp openjdk/hotspot/src/share/vm/ci/ciArrayKlass.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciArrayKlass.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciArrayKlass.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciArrayKlass.hpp 1.15 07/05/05 17:05:12 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciArrayKlassKlass.hpp openjdk/hotspot/src/share/vm/ci/ciArrayKlassKlass.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciArrayKlassKlass.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciArrayKlassKlass.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciArrayKlassKlass.hpp 1.12 07/05/05 17:05:12 JVM" --#endif - /* - * Copyright 1999-2001 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciCallProfile.hpp openjdk/hotspot/src/share/vm/ci/ciCallProfile.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciCallProfile.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciCallProfile.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciCallProfile.hpp 1.17 07/05/05 17:05:12 JVM" --#endif - /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciClassList.hpp openjdk/hotspot/src/share/vm/ci/ciClassList.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciClassList.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciClassList.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciClassList.hpp 1.21 07/05/05 17:05:11 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciConstant.cpp openjdk/hotspot/src/share/vm/ci/ciConstant.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciConstant.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciConstant.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciConstant.cpp 1.13 07/05/05 17:05:12 JVM" --#endif - /* - * Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciConstant.hpp openjdk/hotspot/src/share/vm/ci/ciConstant.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciConstant.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciConstant.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciConstant.hpp 1.17 07/05/05 17:05:12 JVM" --#endif - /* - * Copyright 1999-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -44,7 +41,7 @@ - } _value; - - // Implementation of the print method. -- void print_impl(); -+ void print_impl(outputStream* st); - - public: - -@@ -113,4 +110,3 @@ - // Debugging output - void print(); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciConstantPoolCache.cpp openjdk/hotspot/src/share/vm/ci/ciConstantPoolCache.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciConstantPoolCache.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciConstantPoolCache.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciConstantPoolCache.cpp 1.12 07/05/05 17:05:12 JVM" --#endif - /* - * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciConstantPoolCache.hpp openjdk/hotspot/src/share/vm/ci/ciConstantPoolCache.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciConstantPoolCache.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciConstantPoolCache.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciConstantPoolCache.hpp 1.11 07/05/05 17:05:11 JVM" --#endif - /* - * Copyright 1999-2000 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -48,4 +45,3 @@ - - void print(); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciEnv.cpp openjdk/hotspot/src/share/vm/ci/ciEnv.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciEnv.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciEnv.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciEnv.cpp 1.128 07/05/17 15:49:53 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciEnv.hpp openjdk/hotspot/src/share/vm/ci/ciEnv.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciEnv.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciEnv.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciEnv.hpp 1.70 07/05/05 17:05:11 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -360,5 +357,3 @@ - void record_method_not_compilable(const char* reason, bool all_tiers = true); - void record_out_of_memory_failure(); - }; -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciExceptionHandler.cpp openjdk/hotspot/src/share/vm/ci/ciExceptionHandler.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciExceptionHandler.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciExceptionHandler.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciExceptionHandler.cpp 1.12 07/05/05 17:05:13 JVM" --#endif - /* - * Copyright 1999-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciExceptionHandler.hpp openjdk/hotspot/src/share/vm/ci/ciExceptionHandler.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciExceptionHandler.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciExceptionHandler.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciExceptionHandler.hpp 1.12 07/05/05 17:05:13 JVM" --#endif - /* - * Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -76,4 +73,3 @@ - - void print(); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciField.cpp openjdk/hotspot/src/share/vm/ci/ciField.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciField.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciField.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciField.cpp 1.33 07/05/05 17:05:13 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -143,12 +140,9 @@ - _cp_index = -1; - - // Get the field's name, signature, and type. -- symbolOop name = fd->name(); -- symbolOop signature = fd->signature(); -- - ciEnv* env = CURRENT_ENV; -- _name = env->get_object(name)->as_symbol(); -- _signature = env->get_object(signature)->as_symbol(); -+ _name = env->get_object(fd->name())->as_symbol(); -+ _signature = env->get_object(fd->signature())->as_symbol(); - - BasicType field_type = fd->field_type(); - -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciField.hpp openjdk/hotspot/src/share/vm/ci/ciField.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciField.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciField.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciField.hpp 1.21 07/05/05 17:05:12 JVM" --#endif - /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -34,6 +31,7 @@ - CI_PACKAGE_ACCESS - friend class ciEnv; - friend class ciInstanceKlass; -+ friend class NonStaticFieldFiller; - - private: - ciFlags _flags; -@@ -59,7 +57,7 @@ - void initialize_from(fieldDescriptor* fd); - - // The implementation of the print method. -- void print_impl(); -+ void print_impl(outputStream* st); - - public: - ciFlags flags() { return _flags; } -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciFlags.cpp openjdk/hotspot/src/share/vm/ci/ciFlags.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciFlags.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciFlags.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciFlags.cpp 1.11 07/05/05 17:05:13 JVM" --#endif - /* - * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -34,69 +31,69 @@ - - // ------------------------------------------------------------------ - // ciFlags::print_klass_flags --void ciFlags::print_klass_flags() { -+void ciFlags::print_klass_flags(outputStream* st) { - if (is_public()) { -- tty->print("public"); -+ st->print("public"); - } else { -- tty->print("DEFAULT_ACCESS"); -+ st->print("DEFAULT_ACCESS"); - } - - if (is_final()) { -- tty->print(",final"); -+ st->print(",final"); - } - if (is_super()) { -- tty->print(",super"); -+ st->print(",super"); - } - if (is_interface()) { -- tty->print(",interface"); -+ st->print(",interface"); - } - if (is_abstract()) { -- tty->print(",abstract"); -+ st->print(",abstract"); - } - } - - // ------------------------------------------------------------------ - // ciFlags::print_member_flags --void ciFlags::print_member_flags() { -+void ciFlags::print_member_flags(outputStream* st) { - if (is_public()) { -- tty->print("public"); -+ st->print("public"); - } else if (is_private()) { -- tty->print("private"); -+ st->print("private"); - } else if (is_protected()) { -- tty->print("protected"); -+ st->print("protected"); - } else { -- tty->print("DEFAULT_ACCESS"); -+ st->print("DEFAULT_ACCESS"); - } - - if (is_static()) { -- tty->print(",static"); -+ st->print(",static"); - } - if (is_final()) { -- tty->print(",final"); -+ st->print(",final"); - } - if (is_synchronized()) { -- tty->print(",synchronized"); -+ st->print(",synchronized"); - } - if (is_volatile()) { -- tty->print(",volatile"); -+ st->print(",volatile"); - } - if (is_transient()) { -- tty->print(",transient"); -+ st->print(",transient"); - } - if (is_native()) { -- tty->print(",native"); -+ st->print(",native"); - } - if (is_abstract()) { -- tty->print(",abstract"); -+ st->print(",abstract"); - } - if (is_strict()) { -- tty->print(",strict"); -+ st->print(",strict"); - } - - } - - // ------------------------------------------------------------------ - // ciFlags::print --void ciFlags::print() { -- tty->print(" flags=%x", _flags); -+void ciFlags::print(outputStream* st) { -+ st->print(" flags=%x", _flags); - } -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciFlags.hpp openjdk/hotspot/src/share/vm/ci/ciFlags.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciFlags.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciFlags.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciFlags.hpp 1.14 07/05/05 17:05:13 JVM" --#endif - /* - * Copyright 1999-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -58,7 +55,7 @@ - // Conversion - jint as_int() { return _flags; } - -- void print_klass_flags(); -- void print_member_flags(); -- void print(); -+ void print_klass_flags(outputStream* st = tty); -+ void print_member_flags(outputStream* st = tty); -+ void print(outputStream* st = tty); - }; -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciInstance.cpp openjdk/hotspot/src/share/vm/ci/ciInstance.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciInstance.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciInstance.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciInstance.cpp 1.16 07/05/05 17:05:13 JVM" --#endif - /* - * Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -131,7 +128,7 @@ - // ciInstance::print_impl - // - // Implementation of the print method. --void ciInstance::print_impl() { -- tty->print(" type="); -- klass()->print(); -+void ciInstance::print_impl(outputStream* st) { -+ st->print(" type="); -+ klass()->print(st); - } -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciInstance.hpp openjdk/hotspot/src/share/vm/ci/ciInstance.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciInstance.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciInstance.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciInstance.hpp 1.14 07/05/05 17:05:13 JVM" --#endif - /* - * Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -44,7 +41,7 @@ - - const char* type_string() { return "ciInstance"; } - -- void print_impl(); -+ void print_impl(outputStream* st); - - public: - // If this object is a java mirror, return the corresponding type. -@@ -62,4 +59,3 @@ - // Constant value of a field at the specified offset. - ciConstant field_value_by_offset(int field_offset); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciInstanceKlass.cpp openjdk/hotspot/src/share/vm/ci/ciInstanceKlass.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciInstanceKlass.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciInstanceKlass.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciInstanceKlass.cpp 1.44 07/05/17 15:49:55 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -238,11 +235,11 @@ - // ciInstanceKlass::print_impl - // - // Implementation of the print method. --void ciInstanceKlass::print_impl() { -- ciKlass::print_impl(); -- GUARDED_VM_ENTRY(tty->print(" loader=0x%x", (address)loader());) -+void ciInstanceKlass::print_impl(outputStream* st) { -+ ciKlass::print_impl(st); -+ GUARDED_VM_ENTRY(st->print(" loader=0x%x", (address)loader());) - if (is_loaded()) { -- tty->print(" loaded=true initialized=%s finalized=%s subklass=%s size=%d flags=", -+ st->print(" loaded=true initialized=%s finalized=%s subklass=%s size=%d flags=", - bool_to_str(is_initialized()), - bool_to_str(has_finalizer()), - bool_to_str(has_subklass()), -@@ -251,14 +248,14 @@ - _flags.print_klass_flags(); - - if (_super) { -- tty->print(" super="); -+ st->print(" super="); - _super->print_name(); - } - if (_java_mirror) { -- tty->print(" mirror=PRESENT"); -+ st->print(" mirror=PRESENT"); - } - } else { -- tty->print(" loaded=false"); -+ st->print(" loaded=false"); - } - } - -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciInstanceKlass.hpp openjdk/hotspot/src/share/vm/ci/ciInstanceKlass.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciInstanceKlass.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciInstanceKlass.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciInstanceKlass.hpp 1.35 07/05/05 17:05:13 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -77,7 +74,7 @@ - - const char* type_string() { return "ciInstanceKlass"; } - -- void print_impl(); -+ void print_impl(outputStream* st); - - ciConstantPoolCache* field_cache(); - -@@ -190,4 +187,3 @@ - bool is_instance_klass() { return true; } - bool is_java_klass() { return true; } - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciInstanceKlassKlass.cpp openjdk/hotspot/src/share/vm/ci/ciInstanceKlassKlass.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciInstanceKlassKlass.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciInstanceKlassKlass.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciInstanceKlassKlass.cpp 1.10 07/05/05 17:05:14 JVM" --#endif - /* - * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciInstanceKlassKlass.hpp openjdk/hotspot/src/share/vm/ci/ciInstanceKlassKlass.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciInstanceKlassKlass.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciInstanceKlassKlass.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciInstanceKlassKlass.hpp 1.12 07/05/05 17:05:14 JVM" --#endif - /* - * Copyright 1999-2001 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciKlass.cpp openjdk/hotspot/src/share/vm/ci/ciKlass.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciKlass.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciKlass.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciKlass.cpp 1.30 07/05/05 17:05:11 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -224,9 +221,9 @@ - // ciKlass::print_impl - // - // Implementation of the print method --void ciKlass::print_impl() { -- tty->print(" name="); -- print_name(); -+void ciKlass::print_impl(outputStream* st) { -+ st->print(" name="); -+ print_name_on(st); - } - - // ------------------------------------------------------------------ -@@ -236,4 +233,3 @@ - void ciKlass::print_name_on(outputStream* st) { - name()->print_symbol_on(st); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciKlass.hpp openjdk/hotspot/src/share/vm/ci/ciKlass.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciKlass.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciKlass.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciKlass.hpp 1.26 07/05/05 17:05:11 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -66,7 +63,7 @@ - - const char* type_string() { return "ciKlass"; } - -- void print_impl(); -+ void print_impl(outputStream* st); - - public: - ciKlass(KlassHandle k_h); -@@ -119,8 +116,4 @@ - bool is_klass() { return true; } - - void print_name_on(outputStream* st); -- void print_name() { -- print_name_on(tty); -- } - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciKlassKlass.cpp openjdk/hotspot/src/share/vm/ci/ciKlassKlass.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciKlassKlass.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciKlassKlass.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciKlassKlass.cpp 1.10 07/05/05 17:05:14 JVM" --#endif - /* - * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciKlassKlass.hpp openjdk/hotspot/src/share/vm/ci/ciKlassKlass.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciKlassKlass.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciKlassKlass.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciKlassKlass.hpp 1.13 07/05/05 17:05:14 JVM" --#endif - /* - * Copyright 1999-2001 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -52,4 +49,3 @@ - // Return the distinguished ciKlassKlass instance. - static ciKlassKlass* make(); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciMethod.cpp openjdk/hotspot/src/share/vm/ci/ciMethod.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciMethod.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciMethod.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciMethod.cpp 1.104 07/05/05 17:05:15 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -255,7 +252,7 @@ - check_is_loaded(); - VM_ENTRY_MARK; - methodHandle mh(THREAD, get_methodOop()); -- return AbstractInterpreter::entry_for_method(mh); -+ return Interpreter::entry_for_method(mh); - } - - -@@ -408,7 +405,6 @@ - if (data != NULL && data->is_CounterData()) { - // Every profiled call site has a counter. - int count = data->as_CounterData()->count(); -- result._count = count; - - if (!data->is_ReceiverTypeData()) { - result._receiver_count[0] = 0; // that's a definite zero -@@ -421,8 +417,6 @@ - ciKlass* receiver = call->receiver(i); - if (receiver == NULL) continue; - morphism += 1; -- // we don't support array klasses this way -- if (!receiver->is_instance_klass()) continue; - int rcount = call->receiver_count(i); - if (rcount == 0) rcount = 1; // Should be valid value - receivers_count_total += rcount; -@@ -444,8 +438,18 @@ - result._morphism = morphism; - } - } -+ // Make the count consistent if this is a call profile. If count is -+ // zero or less, presume that this is a typecheck profile and -+ // do nothing. Otherwise, increase count to be the sum of all -+ // receiver's counts. -+ if (count > 0) { -+ if (count < receivers_count_total) { -+ count = receivers_count_total; -+ } - } - } -+ result._count = count; -+ } - } - return result; - } -@@ -526,60 +530,6 @@ - } - - #ifndef PRODUCT -- if (VerifyDependencies || TraceDependencies) { -- // The CHA module is going to be honorably retired. -- // This is the only place where it is used. -- // For a while, test equivalence between old and new methods. -- KlassHandle caller_klass (THREAD, caller->get_klassOop()); -- KlassHandle callee_klass (THREAD, callee_holder->get_klassOop()); -- KlassHandle h_recv (THREAD, actual_recv->get_klassOop()); -- symbolHandle h_name (THREAD, name()->get_symbolOop()); -- symbolHandle h_signature (THREAD, signature()->get_symbolOop()); -- methodHandle cha_target; -- CHAResult* result = -- CHA::analyze_call(caller_klass, callee_klass, h_recv, h_name, h_signature); -- if (TraceTypeProfile && Verbose) { -- result->print(); -- } -- if (result->is_monomorphic()) { -- cha_target = result->monomorphic_target(); -- } -- -- if (target() != NULL && cha_target() == NULL) { -- ResourceMark rm; -- ttyLocker ttyl; -- if (xtty != NULL) { -- xtty->begin_elem("missed_by_CHA"); -- xtty->method(target()); -- xtty->klass(actual_recv->get_klassOop()); -- xtty->end_elem(""); -- } -- if (TraceDependencies) { -- tty->print_cr("found unique method missed by CHA:"); -- tty->print_cr(" context = %s", instanceKlass::cast(actual_recv->get_klassOop())->external_name()); -- tty->print(" method = "); -- target->print_short_name(tty); -- tty->cr(); -- } -- } -- if (cha_target() != NULL && target() == NULL) { -- ResourceMark rm; -- ttyLocker ttyl; -- if (xtty != NULL) { -- xtty->begin_elem("missed_by_deps_found_by_CHA"); -- xtty->method(cha_target()); -- xtty->klass(actual_recv->get_klassOop()); -- xtty->end_elem(""); -- } -- if (TraceDependencies) { -- tty->print_cr("missed unique method found by CHA:"); -- tty->print_cr(" context = %s", instanceKlass::cast(actual_recv->get_klassOop())->external_name()); -- tty->print(" method = "); -- cha_target->print_short_name(tty); -- tty->cr(); -- } -- } -- } - if (TraceDependencies && target() != NULL && target() != root_m->get_methodOop()) { - tty->print("found a non-root unique target method"); - tty->print_cr(" context = %s", instanceKlass::cast(actual_recv->get_klassOop())->external_name()); -@@ -627,7 +577,9 @@ - methodHandle m; - // Only do exact lookup if receiver klass has been linked. Otherwise, - // the vtable has not been setup, and the LinkResolver will fail. -- if (instanceKlass::cast(h_recv())->is_linked() && !exact_receiver->is_interface()) { -+ if (h_recv->oop_is_javaArray() -+ || -+ instanceKlass::cast(h_recv())->is_linked() && !exact_receiver->is_interface()) { - if (holder()->is_interface()) { - m = LinkResolver::resolve_interface_call_or_null(h_recv, h_resolved, h_name, h_signature, caller_klass); - } else { -@@ -760,7 +712,6 @@ - if (_method_data != NULL) { - return _method_data; - } -- if (ProfileInterpreter || Tier1UpdateMethodData) { - VM_ENTRY_MARK; - ciEnv* env = CURRENT_ENV; - Thread* my_thread = JavaThread::current(); -@@ -777,9 +728,7 @@ - _method_data = CURRENT_ENV->get_empty_methodData(); - } - return _method_data; -- } - -- return NULL; - } - - -@@ -949,7 +898,7 @@ - bool ciMethod::is_not_reached(int bci) { - check_is_loaded(); - VM_ENTRY_MARK; -- return AbstractInterpreter::is_not_reached( -+ return Interpreter::is_not_reached( - methodHandle(THREAD, get_methodOop()), bci); - } - -@@ -1008,9 +957,9 @@ - // ciMethod::print_codes - // - // Print the bytecodes for this method. --void ciMethod::print_codes() { -+void ciMethod::print_codes_on(outputStream* st) { - check_is_loaded(); -- GUARDED_VM_ENTRY(get_methodOop()->print_codes();) -+ GUARDED_VM_ENTRY(get_methodOop()->print_codes_on(st);) - } - - -@@ -1049,9 +998,9 @@ - // ciMethod::print_codes - // - // Print a range of the bytecodes for this method. --void ciMethod::print_codes(int from, int to) { -+void ciMethod::print_codes_on(int from, int to, outputStream* st) { - check_is_loaded(); -- GUARDED_VM_ENTRY(get_methodOop()->print_codes(from, to);) -+ GUARDED_VM_ENTRY(get_methodOop()->print_codes_on(from, to, st);) - } - - // ------------------------------------------------------------------ -@@ -1076,20 +1025,18 @@ - // ciMethod::print_impl - // - // Implementation of the print method. --void ciMethod::print_impl() { -- ciObject::print_impl(); -- tty->print(" name="); -- name()->print_symbol(); -- tty->print(" holder="); -- holder()->print_name(); -- tty->print(" signature="); -- signature()->print_signature(); -+void ciMethod::print_impl(outputStream* st) { -+ ciObject::print_impl(st); -+ st->print(" name="); -+ name()->print_symbol_on(st); -+ st->print(" holder="); -+ holder()->print_name_on(st); -+ st->print(" signature="); -+ signature()->as_symbol()->print_symbol_on(st); - if (is_loaded()) { -- tty->print(" loaded=true flags="); -- flags().print_member_flags(); -+ st->print(" loaded=true flags="); -+ flags().print_member_flags(st); - } else { -- tty->print(" loaded=false"); -+ st->print(" loaded=false"); - } - } -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciMethod.hpp openjdk/hotspot/src/share/vm/ci/ciMethod.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciMethod.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciMethod.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciMethod.hpp 1.63 07/06/08 15:21:44 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -89,7 +86,7 @@ - - const char* type_string() { return "ciMethod"; } - -- void print_impl(); -+ void print_impl(outputStream* st); - - void load_code(); - -@@ -237,11 +234,13 @@ - bool can_be_statically_bound() const { return _can_be_statically_bound; } - - // Print the bytecodes of this method. -- void print_codes(); -- void print_codes(int from, int to); -+ void print_codes_on(outputStream* st); -+ void print_codes() { -+ print_codes_on(tty); -+ } -+ void print_codes_on(int from, int to, outputStream* st); - - // Print the name of this method in various incarnations. - void print_name(outputStream* st = tty); - void print_short_name(outputStream* st = tty); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciMethodBlocks.cpp openjdk/hotspot/src/share/vm/ci/ciMethodBlocks.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciMethodBlocks.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciMethodBlocks.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciMethodBlocks.cpp 1.5 07/05/05 17:05:13 JVM" --#endif - /* - * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -357,7 +354,7 @@ - } - - if (Verbose || WizardMode) { -- method()->print_codes(start_bci(), limit_bci()); -+ method()->print_codes_on(start_bci(), limit_bci(), st); - } - } - #endif -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciMethodBlocks.hpp openjdk/hotspot/src/share/vm/ci/ciMethodBlocks.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciMethodBlocks.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciMethodBlocks.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciMethodBlocks.hpp 1.5 07/05/05 17:05:14 JVM" --#endif - /* - * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciMethodData.cpp openjdk/hotspot/src/share/vm/ci/ciMethodData.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciMethodData.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciMethodData.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciMethodData.cpp 1.28 07/05/05 17:05:15 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -291,8 +288,8 @@ - } - - // Implementation of the print method. --void ciMethodData::print_impl() { -- ciObject::print_impl(); -+void ciMethodData::print_impl(outputStream* st) { -+ ciObject::print_impl(st); - } - - #ifndef PRODUCT -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciMethodData.hpp openjdk/hotspot/src/share/vm/ci/ciMethodData.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciMethodData.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciMethodData.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciMethodData.hpp 1.27 07/05/05 17:05:14 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -179,7 +176,7 @@ - - const char* type_string() { return "ciMethodData"; } - -- void print_impl(); -+ void print_impl(outputStream* st); - - DataLayout* data_layout_at(int data_index) { - assert(data_index % sizeof(intptr_t) == 0, "unaligned"); -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciMethodKlass.cpp openjdk/hotspot/src/share/vm/ci/ciMethodKlass.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciMethodKlass.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciMethodKlass.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciMethodKlass.cpp 1.10 07/05/05 17:05:15 JVM" --#endif - /* - * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciMethodKlass.hpp openjdk/hotspot/src/share/vm/ci/ciMethodKlass.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciMethodKlass.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciMethodKlass.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciMethodKlass.hpp 1.13 07/05/05 17:05:15 JVM" --#endif - /* - * Copyright 1999-2001 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -49,4 +46,3 @@ - // Return the distinguished ciMethodKlass instance. - static ciMethodKlass* make(); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciNullObject.cpp openjdk/hotspot/src/share/vm/ci/ciNullObject.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciNullObject.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciNullObject.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciNullObject.cpp 1.11 07/05/05 17:05:15 JVM" --#endif - /* - * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -37,9 +34,9 @@ - // ciNullObject::print_impl - // - // Implementation of the print method. --void ciNullObject::print_impl() { -- ciObject::print_impl(); -- tty->print(" unique"); -+void ciNullObject::print_impl(outputStream* st) { -+ ciObject::print_impl(st); -+ st->print(" unique"); - } - - // ------------------------------------------------------------------ -@@ -49,4 +46,3 @@ - ciNullObject* ciNullObject::make() { - return CURRENT_ENV->_null_object_instance->as_null_object(); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciNullObject.hpp openjdk/hotspot/src/share/vm/ci/ciNullObject.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciNullObject.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciNullObject.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciNullObject.hpp 1.12 07/05/05 17:05:14 JVM" --#endif - /* - * Copyright 1999-2000 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -36,7 +33,7 @@ - - const char* type_string() { return "ciNullObject"; } - -- void print_impl(); -+ void print_impl(outputStream* st); - - public: - // Is this ciObject a Java Language Object? That is, -@@ -50,5 +47,3 @@ - // Get the distinguished instance of this klass. - static ciNullObject* make(); - }; -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciObjArray.hpp openjdk/hotspot/src/share/vm/ci/ciObjArray.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciObjArray.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciObjArray.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciObjArray.hpp 1.12 07/05/05 17:05:15 JVM" --#endif - /* - * Copyright 1999-2001 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciObjArrayKlass.cpp openjdk/hotspot/src/share/vm/ci/ciObjArrayKlass.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciObjArrayKlass.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciObjArrayKlass.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciObjArrayKlass.cpp 1.23 07/05/05 17:05:15 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciObjArrayKlass.hpp openjdk/hotspot/src/share/vm/ci/ciObjArrayKlass.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciObjArrayKlass.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciObjArrayKlass.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciObjArrayKlass.hpp 1.14 07/05/05 17:05:16 JVM" --#endif - /* - * Copyright 1999-2001 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -72,4 +69,3 @@ - - static ciObjArrayKlass* make(ciKlass* element_klass); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciObjArrayKlassKlass.cpp openjdk/hotspot/src/share/vm/ci/ciObjArrayKlassKlass.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciObjArrayKlassKlass.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciObjArrayKlassKlass.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciObjArrayKlassKlass.cpp 1.10 07/05/05 17:05:15 JVM" --#endif - /* - * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciObjArrayKlassKlass.hpp openjdk/hotspot/src/share/vm/ci/ciObjArrayKlassKlass.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciObjArrayKlassKlass.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciObjArrayKlassKlass.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciObjArrayKlassKlass.hpp 1.12 07/05/05 17:05:16 JVM" --#endif - /* - * Copyright 1999-2001 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -51,4 +48,3 @@ - // Return the distinguished ciObjArrayKlassKlass instance. - static ciObjArrayKlassKlass* make(); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciObject.cpp openjdk/hotspot/src/share/vm/ci/ciObject.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciObject.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciObject.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciObject.cpp 1.28 07/05/17 15:49:59 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -195,10 +192,10 @@ - // - // Implementation note: dispatch to the virtual print_impl behavior - // for this ciObject. --void ciObject::print() { -- tty->print("<%s", type_string()); -- GUARDED_VM_ENTRY(print_impl();) -- tty->print(" ident=%d %s address=0x%x>", ident(), -+void ciObject::print(outputStream* st) { -+ st->print("<%s", type_string()); -+ GUARDED_VM_ENTRY(print_impl(st);) -+ st->print(" ident=%d %s address=0x%x>", ident(), - is_perm() ? "PERM" : "", - (address)this); - } -@@ -207,13 +204,12 @@ - // ciObject::print_oop - // - // Print debugging output about the oop this ciObject represents. --void ciObject::print_oop() { -+void ciObject::print_oop(outputStream* st) { - if (is_null_object()) { -- tty->print_cr("NULL"); -+ st->print_cr("NULL"); - } else if (!is_loaded()) { -- tty->print_cr("UNLOADED"); -+ st->print_cr("UNLOADED"); - } else { -- GUARDED_VM_ENTRY(get_oop()->print();) -+ GUARDED_VM_ENTRY(get_oop()->print_on(st);) - } - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciObject.hpp openjdk/hotspot/src/share/vm/ci/ciObject.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciObject.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciObject.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciObject.hpp 1.24 07/05/05 17:05:16 JVM" --#endif - /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -71,13 +68,12 @@ - return JNIHandles::resolve_non_null(_handle); - } - -- bool is_perm() { return (_ident & PERM_FLAG) != 0; } - void set_perm() { - _ident |= PERM_FLAG; - } - - // Virtual behavior of the print() method. -- virtual void print_impl() {} -+ virtual void print_impl(outputStream* st) {} - - virtual const char* type_string() { return "ciObject"; } - -@@ -101,6 +97,11 @@ - // See ciEnv::make_perm_array - bool has_encoding(); - -+ // Is this object guaranteed to be in the permanent part of the heap? -+ // If so, CollectedHeap::can_elide_permanent_oop_store_barriers is relevant. -+ // If the answer is false, no guarantees are made. -+ bool is_perm() { return (_ident & PERM_FLAG) != 0; } -+ - // The address which the compiler should embed into the - // generated code to represent this oop. This address - // is not the true address of the oop -- it will get patched -@@ -252,9 +253,8 @@ - } - - // Print debugging output about this ciObject. -- void print(); -+ void print(outputStream* st = tty); - - // Print debugging output about the oop this ciObject represents. -- void print_oop(); -+ void print_oop(outputStream* st = tty); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciObjectFactory.cpp openjdk/hotspot/src/share/vm/ci/ciObjectFactory.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciObjectFactory.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciObjectFactory.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciObjectFactory.cpp 1.39 07/05/17 15:50:05 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -648,4 +645,3 @@ - _ci_objects->length(), _unloaded_methods->length(), - _unloaded_klasses->length()); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciObjectFactory.hpp openjdk/hotspot/src/share/vm/ci/ciObjectFactory.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciObjectFactory.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciObjectFactory.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciObjectFactory.hpp 1.20 07/05/17 15:50:07 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -111,5 +108,3 @@ - void print_contents(); - void print(); - }; -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciSignature.cpp openjdk/hotspot/src/share/vm/ci/ciSignature.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciSignature.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciSignature.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciSignature.cpp 1.21 07/05/05 17:05:16 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -111,4 +108,3 @@ - _accessing_klass->print(); - tty->print(" address=0x%x>", (address)this); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciSignature.hpp openjdk/hotspot/src/share/vm/ci/ciSignature.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciSignature.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciSignature.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciSignature.hpp 1.16 07/05/05 17:05:14 JVM" --#endif - /* - * Copyright 1999-2000 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -57,6 +54,3 @@ - void print_signature(); - void print(); - }; -- -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciStreams.cpp openjdk/hotspot/src/share/vm/ci/ciStreams.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciStreams.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciStreams.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciStreams.cpp 1.30 07/05/05 17:05:16 JVM" --#endif - /* - * Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -368,5 +365,3 @@ - int name_and_type_index = cpool->name_and_type_ref_index_at(method_index); - return cpool->signature_ref_index_at(name_and_type_index); - } -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciStreams.hpp openjdk/hotspot/src/share/vm/ci/ciStreams.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciStreams.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciStreams.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciStreams.hpp 1.36 07/05/05 17:05:14 JVM" --#endif - /* - * Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -370,7 +367,3 @@ - return _method->_exception_handlers[_pos]; - } - }; -- -- -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciSymbol.cpp openjdk/hotspot/src/share/vm/ci/ciSymbol.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciSymbol.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciSymbol.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciSymbol.cpp 1.22 07/05/05 17:05:16 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -72,9 +69,9 @@ - // ciSymbol::print_impl - // - // Implementation of the print method --void ciSymbol::print_impl() { -- tty->print(" value="); -- print_symbol(); -+void ciSymbol::print_impl(outputStream* st) { -+ st->print(" value="); -+ print_symbol_on(st); - } - - // ------------------------------------------------------------------ -@@ -109,4 +106,3 @@ - ciSymbol* ciSymbol::make(const char* s) { - GUARDED_VM_ENTRY(return make_impl(s);) - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciSymbol.hpp openjdk/hotspot/src/share/vm/ci/ciSymbol.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciSymbol.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciSymbol.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciSymbol.hpp 1.15 07/05/17 15:50:09 JVM" --#endif - /* - * Copyright 1999-2001 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -45,7 +42,7 @@ - - const char* type_string() { return "ciSymbol"; } - -- void print_impl(); -+ void print_impl(outputStream* st); - - int byte_at(int i); - jbyte* base(); -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciSymbolKlass.cpp openjdk/hotspot/src/share/vm/ci/ciSymbolKlass.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciSymbolKlass.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciSymbolKlass.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciSymbolKlass.cpp 1.10 07/05/05 17:05:16 JVM" --#endif - /* - * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciSymbolKlass.hpp openjdk/hotspot/src/share/vm/ci/ciSymbolKlass.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciSymbolKlass.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciSymbolKlass.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciSymbolKlass.hpp 1.13 07/05/05 17:05:17 JVM" --#endif - /* - * Copyright 1999-2001 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -53,4 +50,3 @@ - // Return the distinguished ciSymbolKlass instance. - static ciSymbolKlass* make(); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciType.cpp openjdk/hotspot/src/share/vm/ci/ciType.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciType.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciType.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciType.cpp 1.16 07/05/05 17:05:16 JVM" --#endif - /* - * Copyright 2000-2002 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -67,17 +64,17 @@ - // ciType::print_impl - // - // Implementation of the print method. --void ciType::print_impl() { -- tty->print(" type="); -- print_name(); -+void ciType::print_impl(outputStream* st) { -+ st->print(" type="); -+ print_name_on(st); - } - - // ------------------------------------------------------------------ - // ciType::print_name - // - // Print the name of this type --void ciType::print_name() { -- tty->print(type2name(basic_type())); -+void ciType::print_name_on(outputStream* st) { -+ st->print(type2name(basic_type())); - } - - -@@ -87,7 +84,7 @@ - // - ciInstance* ciType::java_mirror() { - VM_ENTRY_MARK; -- return CURRENT_THREAD_ENV->get_object(SystemDictionary::java_mirror(basic_type()))->as_instance(); -+ return CURRENT_THREAD_ENV->get_object(Universe::java_mirror(basic_type()))->as_instance(); - } - - // ------------------------------------------------------------------ -@@ -136,8 +133,8 @@ - // ciReturnAddress::print_impl - // - // Implementation of the print method. --void ciReturnAddress::print_impl() { -- tty->print(" bci=%d", _bci); -+void ciReturnAddress::print_impl(outputStream* st) { -+ st->print(" bci=%d", _bci); - } - - // ------------------------------------------------------------------ -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciType.hpp openjdk/hotspot/src/share/vm/ci/ciType.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciType.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciType.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciType.hpp 1.14 07/05/05 17:05:16 JVM" --#endif - /* - * Copyright 2000-2001 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -43,7 +40,7 @@ - - const char* type_string() { return "ciType"; } - -- void print_impl(); -+ void print_impl(outputStream* st); - - // Distinguished instances of primitive ciTypes.. - static ciType* _basic_types[T_CONFLICT+1]; -@@ -76,7 +73,10 @@ - bool is_type() { return true; } - bool is_classless() const { return is_primitive_type(); } - -- virtual void print_name(); -+ virtual void print_name_on(outputStream* st); -+ void print_name() { -+ print_name_on(tty); -+ } - - static ciType* make(BasicType t); - }; -@@ -97,7 +97,7 @@ - - const char* type_string() { return "ciReturnAddress"; } - -- void print_impl(); -+ void print_impl(outputStream* st); - - public: - bool is_return_address() { return true; } -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciTypeArray.cpp openjdk/hotspot/src/share/vm/ci/ciTypeArray.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciTypeArray.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciTypeArray.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciTypeArray.cpp 1.6 07/05/05 17:05:17 JVM" --#endif - /* - * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciTypeArray.hpp openjdk/hotspot/src/share/vm/ci/ciTypeArray.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciTypeArray.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciTypeArray.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciTypeArray.hpp 1.13 07/05/05 17:05:17 JVM" --#endif - /* - * Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciTypeArrayKlass.cpp openjdk/hotspot/src/share/vm/ci/ciTypeArrayKlass.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciTypeArrayKlass.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciTypeArrayKlass.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciTypeArrayKlass.cpp 1.14 07/05/05 17:05:17 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -56,4 +53,3 @@ - ciTypeArrayKlass* ciTypeArrayKlass::make(BasicType t) { - GUARDED_VM_ENTRY(return make_impl(t);) - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciTypeArrayKlass.hpp openjdk/hotspot/src/share/vm/ci/ciTypeArrayKlass.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciTypeArrayKlass.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciTypeArrayKlass.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciTypeArrayKlass.hpp 1.13 07/05/05 17:05:17 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciTypeArrayKlassKlass.cpp openjdk/hotspot/src/share/vm/ci/ciTypeArrayKlassKlass.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciTypeArrayKlassKlass.cpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciTypeArrayKlassKlass.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciTypeArrayKlassKlass.cpp 1.10 07/05/05 17:05:17 JVM" --#endif - /* - * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciTypeArrayKlassKlass.hpp openjdk/hotspot/src/share/vm/ci/ciTypeArrayKlassKlass.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciTypeArrayKlassKlass.hpp 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciTypeArrayKlassKlass.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciTypeArrayKlassKlass.hpp 1.12 07/05/05 17:05:18 JVM" --#endif - /* - * Copyright 1999-2001 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciTypeFlow.cpp openjdk/hotspot/src/share/vm/ci/ciTypeFlow.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciTypeFlow.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciTypeFlow.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciTypeFlow.cpp 1.46 07/05/05 17:05:17 JVM" --#endif - /* - * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -1869,7 +1866,7 @@ - // ciTypeFlow::Block::print_on - void ciTypeFlow::Block::print_on(outputStream* st) const { - if ((Verbose || WizardMode)) { -- outer()->method()->print_codes(start(), limit()); -+ outer()->method()->print_codes_on(start(), limit(), st); - } - st->print_cr(" ==================================================== "); - st->print (" "); -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciTypeFlow.hpp openjdk/hotspot/src/share/vm/ci/ciTypeFlow.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciTypeFlow.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciTypeFlow.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciTypeFlow.hpp 1.24 07/05/05 17:05:17 JVM" --#endif - /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciUtilities.cpp openjdk/hotspot/src/share/vm/ci/ciUtilities.cpp ---- openjdk6/hotspot/src/share/vm/ci/ciUtilities.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciUtilities.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ciUtilities.cpp 1.11 07/05/05 17:05:18 JVM" --#endif - /* - * Copyright 1999-2000 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/ci/ciUtilities.hpp openjdk/hotspot/src/share/vm/ci/ciUtilities.hpp ---- openjdk6/hotspot/src/share/vm/ci/ciUtilities.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/ciUtilities.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ciUtilities.hpp 1.20 07/05/05 17:05:18 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -107,4 +104,3 @@ - - const char* basictype_to_str(BasicType t); - const char basictype_to_char(BasicType t); -- -diff -ruNb openjdk6/hotspot/src/share/vm/ci/compilerInterface.hpp openjdk/hotspot/src/share/vm/ci/compilerInterface.hpp ---- openjdk6/hotspot/src/share/vm/ci/compilerInterface.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/ci/compilerInterface.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)compilerInterface.hpp 1.11 07/05/05 17:05:18 JVM" --#endif - /* - * Copyright 1999 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/classFileError.cpp openjdk/hotspot/src/share/vm/classfile/classFileError.cpp ---- openjdk6/hotspot/src/share/vm/classfile/classFileError.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/classFileError.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)classFileError.cpp 1.12 07/05/05 17:06:44 JVM" --#endif - /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/classFileParser.cpp openjdk/hotspot/src/share/vm/classfile/classFileParser.cpp ---- openjdk6/hotspot/src/share/vm/classfile/classFileParser.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/classFileParser.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)classFileParser.cpp 1.279 07/05/25 15:14:21 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -892,44 +889,38 @@ - return exception_handlers; - } - --u_char* ClassFileParser::parse_linenumber_table(u4 code_attribute_length, -- u4 code_length, -- int* compressed_linenumber_table_size, -- TRAPS) { -+void ClassFileParser::parse_linenumber_table( -+ u4 code_attribute_length, u4 code_length, -+ CompressedLineNumberWriteStream** write_stream, TRAPS) { - ClassFileStream* cfs = stream(); -- cfs->guarantee_more(2, CHECK_NULL); // linenumber_table_length -- unsigned int linenumber_table_length = cfs->get_u2_fast(); -+ unsigned int num_entries = cfs->get_u2(CHECK); -+ -+ // Each entry is a u2 start_pc, and a u2 line_number -+ unsigned int length_in_bytes = num_entries * (sizeof(u2) + sizeof(u2)); - - // Verify line number attribute and table length -- if (_need_verify) { -- guarantee_property(code_attribute_length == -- (sizeof(u2) /* linenumber table length */ + -- linenumber_table_length*(sizeof(u2) /* start_pc */ + -- sizeof(u2) /* line_number */)), -- "LineNumberTable attribute has wrong length in class file %s", CHECK_NULL); -- } -- -- u_char* compressed_linenumber_table = NULL; -- if (linenumber_table_length > 0) { -- // initial_size large enough -- int initial_size = linenumber_table_length * sizeof(u2) * 2; -- CompressedLineNumberWriteStream c_stream = -- (initial_size <= fixed_buffer_size) ? -- CompressedLineNumberWriteStream(_fixed_buffer, fixed_buffer_size) : -- CompressedLineNumberWriteStream(initial_size); -- cfs->guarantee_more(4 * linenumber_table_length, CHECK_NULL); // bci, line -- while (linenumber_table_length-- > 0) { -+ check_property( -+ code_attribute_length == sizeof(u2) + length_in_bytes, -+ "LineNumberTable attribute has wrong length in class file %s", CHECK); -+ -+ cfs->guarantee_more(length_in_bytes, CHECK); -+ -+ if ((*write_stream) == NULL) { -+ if (length_in_bytes > fixed_buffer_size) { -+ (*write_stream) = new CompressedLineNumberWriteStream(length_in_bytes); -+ } else { -+ (*write_stream) = new CompressedLineNumberWriteStream( -+ linenumbertable_buffer, fixed_buffer_size); -+ } -+ } -+ -+ while (num_entries-- > 0) { - u2 bci = cfs->get_u2_fast(); // start_pc - u2 line = cfs->get_u2_fast(); // line_number - guarantee_property(bci < code_length, -- "Invalid pc in LineNumberTable in class file %s", CHECK_NULL); -- c_stream.write_pair(bci, line); -- } -- c_stream.write_terminator(); -- *compressed_linenumber_table_size = c_stream.position(); -- compressed_linenumber_table = c_stream.buffer(); -+ "Invalid pc in LineNumberTable in class file %s", CHECK); -+ (*write_stream)->write_pair(bci, line); - } -- return compressed_linenumber_table; - } - - -@@ -1278,8 +1269,8 @@ - typeArrayHandle exception_handlers(THREAD, Universe::the_empty_int_array()); - u2 checked_exceptions_length = 0; - u2* checked_exceptions_start = NULL; -- int compressed_linenumber_table_size = 0; -- u_char* compressed_linenumber_table = NULL; -+ CompressedLineNumberWriteStream* linenumber_table = NULL; -+ int linenumber_table_length = 0; - int total_lvt_length = 0; - u2 lvt_cnt = 0; - u2 lvtt_cnt = 0; -@@ -1394,10 +1385,8 @@ - if (LoadLineNumberTables && - cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_line_number_table()) { - // Parse and compress line number table -- compressed_linenumber_table = parse_linenumber_table(code_attribute_length, -- code_length, -- &compressed_linenumber_table_size, -- CHECK_(nullHandle)); -+ parse_linenumber_table(code_attribute_length, code_length, -+ &linenumber_table, CHECK_(nullHandle)); - - } else if (LoadLocalVariableTables && - cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_local_variable_table()) { -@@ -1545,6 +1534,12 @@ - cfs->skip_u1(method_attribute_length, CHECK_(nullHandle)); - } - } -+ -+ if (linenumber_table != NULL) { -+ linenumber_table->write_terminator(); -+ linenumber_table_length = linenumber_table->position(); -+ } -+ - // Make sure there's at least one Code attribute in non-native/non-abstract method - if (_need_verify) { - guarantee_property(access_flags.is_native() || access_flags.is_abstract() || parsed_code_attribute, -@@ -1552,11 +1547,9 @@ - } - - // All sizing information for a methodOop is finally available, now create it -- methodOop m_oop = oopFactory::new_method(code_length, access_flags, -- compressed_linenumber_table_size, -- total_lvt_length, -- checked_exceptions_length, -- CHECK_(nullHandle)); -+ methodOop m_oop = oopFactory::new_method( -+ code_length, access_flags, linenumber_table_length, -+ total_lvt_length, checked_exceptions_length, CHECK_(nullHandle)); - methodHandle m (THREAD, m_oop); - - ClassLoadingService::add_class_method_size(m_oop->size()*HeapWordSize); -@@ -1602,10 +1595,13 @@ - if (code_length > 0) { - memcpy(m->code_base(), code_start, code_length); - } -+ - // Copy line number table -- if (compressed_linenumber_table_size > 0) { -- memcpy(m->compressed_linenumber_table(), compressed_linenumber_table, compressed_linenumber_table_size); -+ if (linenumber_table != NULL) { -+ memcpy(m->compressed_linenumber_table(), -+ linenumber_table->buffer(), linenumber_table_length); - } -+ - // Copy checked exceptions - if (checked_exceptions_length > 0) { - int size = checked_exceptions_length * sizeof(CheckedExceptionElement) / sizeof(u2); -@@ -4016,4 +4012,3 @@ - } - return NULL; - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/classFileParser.hpp openjdk/hotspot/src/share/vm/classfile/classFileParser.hpp ---- openjdk6/hotspot/src/share/vm/classfile/classFileParser.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/classFileParser.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)classFileParser.hpp 1.84 07/05/05 17:06:45 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -42,7 +39,7 @@ - bool _has_vanilla_constructor; - - enum { fixed_buffer_size = 128 }; -- u_char _fixed_buffer[fixed_buffer_size]; -+ u_char linenumbertable_buffer[fixed_buffer_size]; - - ClassFileStream* _stream; // Actual input stream - -@@ -98,8 +95,9 @@ - TRAPS); - typeArrayHandle parse_exception_table(u4 code_length, u4 exception_table_length, - constantPoolHandle cp, TRAPS); -- u_char* parse_linenumber_table(u4 code_attribute_length, u4 code_length, -- int* compressed_linenumber_table_size, TRAPS); -+ void parse_linenumber_table( -+ u4 code_attribute_length, u4 code_length, -+ CompressedLineNumberWriteStream** write_stream, TRAPS); - u2* parse_localvariable_table(u4 code_length, u2 max_locals, u4 code_attribute_length, - constantPoolHandle cp, u2* localvariable_table_length, - bool isLVTT, TRAPS); -@@ -169,6 +167,15 @@ - assert_property(property, msg, CHECK); - } - } -+ -+ inline void check_property(bool property, const char* msg, TRAPS) { -+ if (_need_verify) { -+ guarantee_property(property, msg, CHECK); -+ } else { -+ assert_property(property, msg, CHECK); -+ } -+ } -+ - inline void guarantee_property(bool b, const char* msg, int index, TRAPS) { - if (!b) { classfile_parse_error(msg, index, CHECK); } - } -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/classFileStream.cpp openjdk/hotspot/src/share/vm/classfile/classFileStream.cpp ---- openjdk6/hotspot/src/share/vm/classfile/classFileStream.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/classFileStream.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)classFileStream.cpp 1.41 07/05/31 14:29:24 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/classFileStream.hpp openjdk/hotspot/src/share/vm/classfile/classFileStream.hpp ---- openjdk6/hotspot/src/share/vm/classfile/classFileStream.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/classFileStream.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)classFileStream.hpp 1.33 07/05/31 14:29:25 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/classLoader.cpp openjdk/hotspot/src/share/vm/classfile/classLoader.cpp ---- openjdk6/hotspot/src/share/vm/classfile/classLoader.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/classLoader.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)classLoader.cpp 1.186 07/05/05 17:06:44 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -390,7 +387,7 @@ - char* path = NEW_C_HEAP_ARRAY(char, end-start+1); - strncpy(path, &sys_class_path[start], end-start); - path[end-start] = '\0'; -- update_class_path_entry_list(path); -+ update_class_path_entry_list(path, false); - FREE_C_HEAP_ARRAY(char, path); - while (sys_class_path[end] == os::path_separator()[0]) { - end++; -@@ -505,15 +502,31 @@ - } - } - --void ClassLoader::update_class_path_entry_list(const char *path) { -+void ClassLoader::update_class_path_entry_list(const char *path, -+ bool check_for_duplicates) { - struct stat st; - if (os::stat((char *)path, &st) == 0) { - // File or directory found - ClassPathEntry* new_entry = NULL; - create_class_path_entry((char *)path, st, &new_entry, LazyBootClassLoader); -+ // The kernel VM adds dynamically to the end of the classloader path and -+ // doesn't reorder the bootclasspath which would break java.lang.Package -+ // (see PackageInfo). - // Add new entry to linked list -+ if (!check_for_duplicates || !contains_entry(new_entry)) { - add_to_list(new_entry); - } -+ } -+} -+ -+void ClassLoader::print_bootclasspath() { -+ ClassPathEntry* e = _first_entry; -+ tty->print("[bootclasspath= "); -+ while (e != NULL) { -+ tty->print("%s ;", e->name()); -+ e = e->next(); -+ } -+ tty->print_cr("]"); - } - - void ClassLoader::load_zip_library() { -@@ -866,7 +879,8 @@ - - // Initialize the class loader's access to methods in libzip. Parse and - // process the boot classpath into a list ClassPathEntry objects. Once --// this list has been created, it must not change (see class PackageInfo). -+// this list has been created, it must not change order (see class PackageInfo) -+// it can be appended to and is by jvmti and the kernel vm. - - void ClassLoader::initialize() { - assert(_package_hash_table == NULL, "should have been initialized by now."); -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/classLoader.hpp openjdk/hotspot/src/share/vm/classfile/classLoader.hpp ---- openjdk6/hotspot/src/share/vm/classfile/classLoader.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/classLoader.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)classLoader.hpp 1.64 07/05/05 17:06:45 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -49,7 +46,10 @@ - public: - // Next entry in class path - ClassPathEntry* next() { return _next; } -- void set_next(ClassPathEntry* next) { _next = next; } -+ void set_next(ClassPathEntry* next) { -+ // may have unlocked readers, so write atomically. -+ OrderAccess::release_store_ptr(&_next, next); -+ } - virtual bool is_jar_file() = 0; - virtual const char* name() = 0; - virtual bool is_lazy(); -@@ -185,12 +185,16 @@ - static void setup_bootstrap_search_path(); - static void load_zip_library(); - static void create_class_path_entry(char *path, struct stat st, ClassPathEntry **new_entry, bool lazy); -- static void update_class_path_entry_list(const char *path); - - // Canonicalizes path names, so strcmp will work properly. This is mainly - // to avoid confusing the zip library - static bool get_canonical_path(char* orig, char* out, int len); - public: -+ // Used by the kernel jvm. -+ static void update_class_path_entry_list(const char *path, -+ bool check_for_duplicates); -+ static void print_bootclasspath(); -+ - // Timing - static PerfCounter* perf_accumulated_time() { return _perf_accumulated_time; } - static PerfCounter* perf_classes_inited() { return _perf_classes_inited; } -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/dictionary.cpp openjdk/hotspot/src/share/vm/classfile/dictionary.cpp ---- openjdk6/hotspot/src/share/vm/classfile/dictionary.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/dictionary.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)dictionary.cpp 1.27 08/06/19 10:32:36 JVM" --#endif - /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -158,8 +155,8 @@ - for (int i = ik->previous_versions()->length() - 1; i >= 0; i--) { - // check the previous versions array for GC'ed weak refs - PreviousVersionNode * pv_node = ik->previous_versions()->at(i); -- jobject cp_ref = pv_node->prev_constant_pool(); -- assert(cp_ref != NULL, "cp ref was unexpectedly cleared"); -+ jweak cp_ref = pv_node->prev_constant_pool(); -+ assert(cp_ref != NULL, "weak cp ref was unexpectedly cleared"); - if (cp_ref == NULL) { - delete pv_node; - ik->previous_versions()->remove_at(i); -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/dictionary.hpp openjdk/hotspot/src/share/vm/classfile/dictionary.hpp ---- openjdk6/hotspot/src/share/vm/classfile/dictionary.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/dictionary.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)dictionary.hpp 1.15 07/05/05 17:05:47 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -220,4 +217,3 @@ - tty->print_cr("pd set = #%d", count); - } - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/javaAssertions.cpp openjdk/hotspot/src/share/vm/classfile/javaAssertions.cpp ---- openjdk6/hotspot/src/share/vm/classfile/javaAssertions.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/javaAssertions.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)javaAssertions.cpp 1.14 07/05/05 17:06:50 JVM" --#endif - /* - * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/javaAssertions.hpp openjdk/hotspot/src/share/vm/classfile/javaAssertions.hpp ---- openjdk6/hotspot/src/share/vm/classfile/javaAssertions.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/javaAssertions.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)javaAssertions.hpp 1.11 07/05/05 17:06:50 JVM" --#endif - /* - * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/javaClasses.cpp openjdk/hotspot/src/share/vm/classfile/javaClasses.cpp ---- openjdk6/hotspot/src/share/vm/classfile/javaClasses.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/javaClasses.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)javaClasses.cpp 1.247 07/05/17 15:50:20 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -308,7 +305,7 @@ - Handle comp_mirror; - if (k->oop_is_typeArray()) { - BasicType type = typeArrayKlass::cast(k->as_klassOop())->element_type(); -- comp_mirror = SystemDictionary::java_mirror(type); -+ comp_mirror = Universe::java_mirror(type); - assert(comp_mirror.not_null(), "must have primitive mirror"); - } else if (k->oop_is_objArray()) { - klassOop element_klass = objArrayKlass::cast(k->as_klassOop())->element_klass(); -@@ -394,15 +391,15 @@ - // Note: create_basic_type_mirror above initializes ak to a non-null value. - type = arrayKlass::cast(ak)->element_type(); - } else { -- assert(java_class == SystemDictionary::void_mirror(), "only valid non-array primitive"); -+ assert(java_class == Universe::void_mirror(), "only valid non-array primitive"); - } -- assert(SystemDictionary::java_mirror(type) == java_class, "must be consistent"); -+ assert(Universe::java_mirror(type) == java_class, "must be consistent"); - return type; - } - - - oop java_lang_Class::primitive_mirror(BasicType t) { -- oop mirror = SystemDictionary::java_mirror(t); -+ oop mirror = Universe::java_mirror(t); - assert(mirror != NULL && mirror->is_a(SystemDictionary::class_klass()), "must be a Class"); - assert(java_lang_Class::is_primitive(mirror), "must be primitive"); - return mirror; -@@ -1125,7 +1122,7 @@ - } else { - if (fr.is_first_frame()) break; - address pc = fr.pc(); -- if (AbstractInterpreter::contains(pc)) { -+ if (fr.is_interpreted_frame()) { - intptr_t bcx = fr.interpreter_frame_bcx(); - method = fr.interpreter_frame_method(); - bci = fr.is_bci(bcx) ? bcx : method->bci_from((address)bcx); -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/javaClasses.hpp openjdk/hotspot/src/share/vm/classfile/javaClasses.hpp ---- openjdk6/hotspot/src/share/vm/classfile/javaClasses.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/javaClasses.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)javaClasses.hpp 1.157 07/05/05 17:05:52 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/loaderConstraints.cpp openjdk/hotspot/src/share/vm/classfile/loaderConstraints.cpp ---- openjdk6/hotspot/src/share/vm/classfile/loaderConstraints.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/loaderConstraints.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)loaderConstraints.cpp 1.19 07/05/17 15:50:23 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/loaderConstraints.hpp openjdk/hotspot/src/share/vm/classfile/loaderConstraints.hpp ---- openjdk6/hotspot/src/share/vm/classfile/loaderConstraints.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/loaderConstraints.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)loaderConstraints.hpp 1.14 07/05/05 17:05:52 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/placeholders.cpp openjdk/hotspot/src/share/vm/classfile/placeholders.cpp ---- openjdk6/hotspot/src/share/vm/classfile/placeholders.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/placeholders.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)placeholders.cpp 1.20 07/05/17 15:50:29 JVM" --#endif - /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -270,5 +267,3 @@ - } - } - #endif -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/placeholders.hpp openjdk/hotspot/src/share/vm/classfile/placeholders.hpp ---- openjdk6/hotspot/src/share/vm/classfile/placeholders.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/placeholders.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)placeholders.hpp 1.21 07/05/05 17:05:54 JVM" --#endif - /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -332,5 +329,3 @@ - void print() const PRODUCT_RETURN; - void verify() const; - }; -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/resolutionErrors.cpp openjdk/hotspot/src/share/vm/classfile/resolutionErrors.cpp ---- openjdk6/hotspot/src/share/vm/classfile/resolutionErrors.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/resolutionErrors.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)resolutionErrors.cpp 1.6 07/05/05 17:05:54 JVM" --#endif - /* - * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -120,5 +117,3 @@ - } - } - } -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/resolutionErrors.hpp openjdk/hotspot/src/share/vm/classfile/resolutionErrors.hpp ---- openjdk6/hotspot/src/share/vm/classfile/resolutionErrors.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/resolutionErrors.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)resolutionErrors.hpp 1.6 07/05/05 17:05:54 JVM" --#endif - /* - * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -100,4 +97,3 @@ - // GC support - void oops_do(OopClosure* blk); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/stackMapFrame.cpp openjdk/hotspot/src/share/vm/classfile/stackMapFrame.cpp ---- openjdk6/hotspot/src/share/vm/classfile/stackMapFrame.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/stackMapFrame.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)stackMapFrame.cpp 1.24 07/05/05 17:06:57 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -304,4 +301,3 @@ - } - - #endif -- -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/stackMapFrame.hpp openjdk/hotspot/src/share/vm/classfile/stackMapFrame.hpp ---- openjdk6/hotspot/src/share/vm/classfile/stackMapFrame.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/stackMapFrame.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)stackMapFrame.hpp 1.20 07/05/05 17:06:57 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -227,4 +224,3 @@ - // Debugging - void print() const PRODUCT_RETURN; - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/stackMapTable.cpp openjdk/hotspot/src/share/vm/classfile/stackMapTable.cpp ---- openjdk6/hotspot/src/share/vm/classfile/stackMapTable.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/stackMapTable.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)stackMapTable.cpp 1.28 07/05/05 17:06:53 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -428,4 +425,3 @@ - "reserved frame type", CHECK_VERIFY_(pre_frame->verifier(), NULL)); - return NULL; - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/stackMapTable.hpp openjdk/hotspot/src/share/vm/classfile/stackMapTable.hpp ---- openjdk6/hotspot/src/share/vm/classfile/stackMapTable.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/stackMapTable.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)stackMapTable.hpp 1.21 07/05/05 17:06:57 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/symbolTable.cpp openjdk/hotspot/src/share/vm/classfile/symbolTable.cpp ---- openjdk6/hotspot/src/share/vm/classfile/symbolTable.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/symbolTable.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)symbolTable.cpp 1.69 07/05/05 17:05:55 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/symbolTable.hpp openjdk/hotspot/src/share/vm/classfile/symbolTable.hpp ---- openjdk6/hotspot/src/share/vm/classfile/symbolTable.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/symbolTable.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)symbolTable.hpp 1.48 07/05/05 17:05:56 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/systemDictionary.cpp openjdk/hotspot/src/share/vm/classfile/systemDictionary.cpp ---- openjdk6/hotspot/src/share/vm/classfile/systemDictionary.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/systemDictionary.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)systemDictionary.cpp 1.361 07/09/01 18:23:02 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -95,6 +92,7 @@ - klassOop SystemDictionary::_java_nio_Buffer_klass = NULL; - - klassOop SystemDictionary::_sun_misc_AtomicLongCSImpl_klass = NULL; -+klassOop SystemDictionary::_sun_jkernel_DownloadManager_klass = NULL; - - klassOop SystemDictionary::_boolean_klass = NULL; - klassOop SystemDictionary::_char_klass = NULL; -@@ -106,17 +104,6 @@ - klassOop SystemDictionary::_long_klass = NULL; - klassOop SystemDictionary::_box_klasses[T_VOID+1] = { NULL /*, NULL...*/ }; - --oop SystemDictionary::_int_mirror = NULL; --oop SystemDictionary::_float_mirror = NULL; --oop SystemDictionary::_double_mirror = NULL; --oop SystemDictionary::_byte_mirror = NULL; --oop SystemDictionary::_bool_mirror = NULL; --oop SystemDictionary::_char_mirror = NULL; --oop SystemDictionary::_long_mirror = NULL; --oop SystemDictionary::_short_mirror = NULL; --oop SystemDictionary::_void_mirror = NULL; --oop SystemDictionary::_mirrors[T_VOID+1] = { NULL /*, NULL...*/ }; -- - oop SystemDictionary::_java_system_loader = NULL; - - bool SystemDictionary::_has_loadClassInternal = false; -@@ -1215,6 +1202,63 @@ - return ik; - } - -+#ifdef KERNEL -+// Some classes on the bootstrap class path haven't been installed on the -+// system yet. Call the DownloadManager method to make them appear in the -+// bootstrap class path and try again to load the named class. -+// Note that with delegation class loaders all classes in another loader will -+// first try to call this so it'd better be fast!! -+static instanceKlassHandle download_and_retry_class_load( -+ symbolHandle class_name, -+ TRAPS) { -+ -+ klassOop dlm = SystemDictionary::sun_jkernel_DownloadManager_klass(); -+ instanceKlassHandle nk; -+ -+ // If download manager class isn't loaded just return. -+ if (dlm == NULL) return nk; -+ -+ { HandleMark hm(THREAD); -+ ResourceMark rm(THREAD); -+ Handle s = java_lang_String::create_from_symbol(class_name, CHECK_(nk)); -+ Handle class_string = java_lang_String::externalize_classname(s, CHECK_(nk)); -+ -+ // return value -+ JavaValue result(T_OBJECT); -+ -+ // Call the DownloadManager. We assume that it has a lock because -+ // multiple classes could be not found and downloaded at the same time. -+ // class sun.misc.DownloadManager; -+ // public static String getBootClassPathEntryForClass(String className); -+ JavaCalls::call_static(&result, -+ KlassHandle(THREAD, dlm), -+ vmSymbolHandles::getBootClassPathEntryForClass_name(), -+ vmSymbolHandles::string_string_signature(), -+ class_string, -+ CHECK_(nk)); -+ -+ // Get result.string and add to bootclasspath -+ assert(result.get_type() == T_OBJECT, "just checking"); -+ oop obj = (oop) result.get_jobject(); -+ if (obj == NULL) { return nk; } -+ -+ char* new_class_name = java_lang_String::as_utf8_string(obj); -+ -+ // lock the loader -+ // we use this lock because JVMTI does. -+ Handle loader_lock(THREAD, SystemDictionary::system_loader_lock()); -+ -+ ObjectLocker ol(loader_lock, THREAD); -+ // add the file to the bootclasspath -+ ClassLoader::update_class_path_entry_list(new_class_name, true); -+ } // end HandleMark -+ -+ if (TraceClassLoading) { -+ ClassLoader::print_bootclasspath(); -+ } -+ return ClassLoader::load_classfile(class_name, CHECK_(nk)); -+} -+#endif // KERNEL - - - instanceKlassHandle SystemDictionary::load_instance_class(symbolHandle class_name, Handle class_loader, TRAPS) { -@@ -1230,6 +1274,15 @@ - k = ClassLoader::load_classfile(class_name, CHECK_(nh)); - } - -+#ifdef KERNEL -+ // If the VM class loader has failed to load the class, call the -+ // DownloadManager class to make it magically appear on the classpath -+ // and try again. This is only configured with the Kernel VM. -+ if (k.is_null()) { -+ k = download_and_retry_class_load(class_name, CHECK_(nh)); -+ } -+#endif // KERNEL -+ - // find_or_define_instance_class may return a different k - if (!k.is_null()) { - k = find_or_define_instance_class(class_name, class_loader, k, CHECK_(nh)); -@@ -1605,7 +1658,7 @@ - - // The mirrors are scanned by shared_oops_do() which is - // not called by oops_do(). In order to process oops in --// a necessary order, shared_oops_do() is called by -+// a necessary order, shared_oops_do() is call by - // Universe::oops_do(). - void SystemDictionary::oops_do(OopClosure* f) { - // Adjust preloaded classes and system loader object -@@ -1684,6 +1737,7 @@ - f->do_oop((oop*) &_java_nio_Buffer_klass); - - f->do_oop((oop*) &_sun_misc_AtomicLongCSImpl_klass); -+ f->do_oop((oop*) &_sun_jkernel_DownloadManager_klass); - - f->do_oop((oop*) &_boolean_klass); - f->do_oop((oop*) &_char_klass); -@@ -1710,29 +1764,6 @@ - FilteredFieldsMap::klasses_oops_do(f); - } - --// These *_mirror objects in the system dictionary need to be processed --// early on when class data sharing is enabled, and are therefore treated --// as part of Universe::oops_do() rather than in SystemDictionary::oops_do() --// as one would normally expect. --void SystemDictionary::shared_oops_do(OopClosure* f) { -- f->do_oop((oop*) &_int_mirror); -- f->do_oop((oop*) &_float_mirror); -- f->do_oop((oop*) &_double_mirror); -- f->do_oop((oop*) &_byte_mirror); -- f->do_oop((oop*) &_bool_mirror); -- f->do_oop((oop*) &_char_mirror); -- f->do_oop((oop*) &_long_mirror); -- f->do_oop((oop*) &_short_mirror); -- f->do_oop((oop*) &_void_mirror); -- -- // It's important to iterate over these guys even if they are null, -- // since that's how shared heaps are restored. -- for (int i = T_BOOLEAN; i < T_VOID+1; i++) { -- f->do_oop((oop*) &_mirrors[i]); -- } -- assert(_mirrors[0] == NULL && _mirrors[T_BOOLEAN - 1] == NULL, "checking"); --} -- - void SystemDictionary::lazily_loaded_oops_do(OopClosure* f) { - f->do_oop((oop*) &_abstract_ownable_synchronizer_klass); - } -@@ -1816,9 +1847,12 @@ - _string_klass = resolve_or_fail(vmSymbolHandles::java_lang_String(), true, CHECK); - _class_klass = resolve_or_fail(vmSymbolHandles::java_lang_Class(), true, CHECK); - debug_only(instanceKlass::verify_class_klass_nonstatic_oop_maps(_class_klass)); -- -- // Fixup mirrors for classes loaded before java.lang.Class -- initialize_basic_type_mirrors(CHECK); -+ // Fixup mirrors for classes loaded before java.lang.Class. -+ // These calls iterate over the objects currently in the perm gen -+ // so calling them at this point is matters (not before when there -+ // are fewer objects and not later after there are more objects -+ // in the perm gen. -+ Universe::initialize_basic_type_mirrors(CHECK); - Universe::fixup_mirrors(CHECK); - - _cloneable_klass = resolve_or_fail(vmSymbolHandles::java_lang_Cloneable(), true, CHECK); -@@ -1887,6 +1921,12 @@ - - // If this class isn't present, it won't be referenced. - _sun_misc_AtomicLongCSImpl_klass = resolve_or_null(vmSymbolHandles::sun_misc_AtomicLongCSImpl(), CHECK); -+#ifdef KERNEL -+ _sun_jkernel_DownloadManager_klass = resolve_or_null(vmSymbolHandles::sun_jkernel_DownloadManager(), CHECK); -+ if (_sun_jkernel_DownloadManager_klass == NULL) { -+ warning("Cannot find sun/jkernel/DownloadManager"); -+ } -+#endif // KERNEL - - // Preload boxing klasses - _boolean_klass = resolve_or_fail(vmSymbolHandles::java_lang_Boolean(), true, CHECK); -@@ -1920,39 +1960,6 @@ - } - } - --void SystemDictionary::initialize_basic_type_mirrors(TRAPS) { -- if (UseSharedSpaces) { -- assert(_int_mirror != NULL, "already loaded"); -- assert(_void_mirror == _mirrors[T_VOID], "consistently loaded"); -- return; -- } -- -- assert(_int_mirror==NULL, "basic type mirrors already initialized"); -- -- _int_mirror = java_lang_Class::create_basic_type_mirror("int", T_INT, CHECK); -- _float_mirror = java_lang_Class::create_basic_type_mirror("float", T_FLOAT, CHECK); -- _double_mirror = java_lang_Class::create_basic_type_mirror("double", T_DOUBLE, CHECK); -- _byte_mirror = java_lang_Class::create_basic_type_mirror("byte", T_BYTE, CHECK); -- _bool_mirror = java_lang_Class::create_basic_type_mirror("boolean",T_BOOLEAN, CHECK); -- _char_mirror = java_lang_Class::create_basic_type_mirror("char", T_CHAR, CHECK); -- _long_mirror = java_lang_Class::create_basic_type_mirror("long", T_LONG, CHECK); -- _short_mirror = java_lang_Class::create_basic_type_mirror("short", T_SHORT, CHECK); -- _void_mirror = java_lang_Class::create_basic_type_mirror("void", T_VOID, CHECK); -- -- _mirrors[T_INT] = _int_mirror; -- _mirrors[T_FLOAT] = _float_mirror; -- _mirrors[T_DOUBLE] = _double_mirror; -- _mirrors[T_BYTE] = _byte_mirror; -- _mirrors[T_BOOLEAN] = _bool_mirror; -- _mirrors[T_CHAR] = _char_mirror; -- _mirrors[T_LONG] = _long_mirror; -- _mirrors[T_SHORT] = _short_mirror; -- _mirrors[T_VOID] = _void_mirror; -- //_mirrors[T_OBJECT] = instanceKlass::cast(_object_klass)->java_mirror(); -- //_mirrors[T_ARRAY] = instanceKlass::cast(_object_klass)->java_mirror(); --} -- -- - // Tells if a given klass is a box (wrapper class, such as java.lang.Integer). - // If so, returns the basic type it holds. If not, returns T_OBJECT. - BasicType SystemDictionary::box_klass_type(klassOop k) { -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/systemDictionary.hpp openjdk/hotspot/src/share/vm/classfile/systemDictionary.hpp ---- openjdk6/hotspot/src/share/vm/classfile/systemDictionary.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/systemDictionary.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)systemDictionary.hpp 1.153 07/05/05 17:05:56 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -183,9 +180,6 @@ - // Applies "f->do_oop" to all root oops in the system dictionary. - static void oops_do(OopClosure* f); - -- // Applies "f->do_oop" to root oops that are loaded from a shared heap. -- static void shared_oops_do(OopClosure* f); -- - // System loader lock - static oop system_loader_lock() { return _system_loader_lock_obj; } - -@@ -309,6 +303,9 @@ - - static klassOop sun_misc_AtomicLongCSImpl_klass() { return _sun_misc_AtomicLongCSImpl_klass; } - -+ // To support incremental JRE downloads (KERNEL JRE). Null if not present. -+ static klassOop sun_jkernel_DownloadManager_klass() { return _sun_jkernel_DownloadManager_klass; } -+ - static klassOop boolean_klass() { return check_klass(_boolean_klass); } - static klassOop char_klass() { return check_klass(_char_klass); } - static klassOop float_klass() { return check_klass(_float_klass); } -@@ -355,20 +352,6 @@ - } - - public: -- static oop int_mirror() { return check_mirror(_int_mirror); } -- static oop float_mirror() { return check_mirror(_float_mirror); } -- static oop double_mirror() { return check_mirror(_double_mirror); } -- static oop byte_mirror() { return check_mirror(_byte_mirror); } -- static oop bool_mirror() { return check_mirror(_bool_mirror); } -- static oop char_mirror() { return check_mirror(_char_mirror); } -- static oop long_mirror() { return check_mirror(_long_mirror); } -- static oop short_mirror() { return check_mirror(_short_mirror); } -- static oop void_mirror() { return check_mirror(_void_mirror); } -- -- static oop java_mirror(BasicType t) { -- assert((uint)t < T_VOID+1, "range check"); -- return check_mirror(_mirrors[t]); -- } - // Note: java_lang_Class::primitive_type is the inverse of java_mirror - - // Check class loader constraints -@@ -505,7 +488,6 @@ - - // Initialization - static void initialize_preloaded_classes(TRAPS); -- static void initialize_basic_type_mirrors(TRAPS); - - // Class loader constraints - static void check_constraints(int index, unsigned int hash, -@@ -573,6 +555,9 @@ - - static klassOop _sun_misc_AtomicLongCSImpl_klass; - -+ // KERNEL JRE support. -+ static klassOop _sun_jkernel_DownloadManager_klass; -+ - // Lazily loaded klasses - static volatile klassOop _abstract_ownable_synchronizer_klass; - -@@ -593,18 +578,4 @@ - - static bool _has_loadClassInternal; - static bool _has_checkPackageAccess; -- -- // Primitive classes -- static oop _int_mirror; -- static oop _float_mirror; -- static oop _double_mirror; -- static oop _byte_mirror; -- static oop _bool_mirror; -- static oop _char_mirror; -- static oop _long_mirror; -- static oop _short_mirror; -- static oop _void_mirror; -- -- // table of same -- static oop _mirrors[T_VOID+1]; - }; -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/verificationType.cpp openjdk/hotspot/src/share/vm/classfile/verificationType.cpp ---- openjdk6/hotspot/src/share/vm/classfile/verificationType.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/verificationType.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)verificationType.cpp 1.16 07/05/05 17:07:01 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/verificationType.hpp openjdk/hotspot/src/share/vm/classfile/verificationType.hpp ---- openjdk6/hotspot/src/share/vm/classfile/verificationType.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/verificationType.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)verificationType.hpp 1.17 07/05/05 17:07:01 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/verifier.cpp openjdk/hotspot/src/share/vm/classfile/verifier.cpp ---- openjdk6/hotspot/src/share/vm/classfile/verifier.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/verifier.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)verifier.cpp 1.113 07/05/23 10:53:19 JVM" --#endif - /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/verifier.hpp openjdk/hotspot/src/share/vm/classfile/verifier.hpp ---- openjdk6/hotspot/src/share/vm/classfile/verifier.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/verifier.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)verifier.hpp 1.41 07/05/05 17:07:02 JVM" --#endif - /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/vmSymbols.cpp openjdk/hotspot/src/share/vm/classfile/vmSymbols.cpp ---- openjdk6/hotspot/src/share/vm/classfile/vmSymbols.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/vmSymbols.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)vmSymbols.cpp 1.28 07/05/17 15:50:36 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -35,7 +32,8 @@ - - inline int compare_symbol(symbolOop a, symbolOop b) { - if (a == b) return 0; -- return (intptr_t)a > (intptr_t)b ? +1 : -1; -+ // follow the natural address order: -+ return (address)a > (address)b ? +1 : -1; - } - - static vmSymbols::SID vm_symbol_index[vmSymbols::SID_LIMIT]; -diff -ruNb openjdk6/hotspot/src/share/vm/classfile/vmSymbols.hpp openjdk/hotspot/src/share/vm/classfile/vmSymbols.hpp ---- openjdk6/hotspot/src/share/vm/classfile/vmSymbols.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/classfile/vmSymbols.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)vmSymbols.hpp 1.162 07/05/17 15:50:40 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -97,6 +94,8 @@ - template(java_lang_Compiler, "java/lang/Compiler") \ - template(sun_misc_Signal, "sun/misc/Signal") \ - template(java_lang_AssertionStatusDirectives, "java/lang/AssertionStatusDirectives") \ -+ template(sun_jkernel_DownloadManager, "sun/jkernel/DownloadManager") \ -+ template(getBootClassPathEntryForClass_name, "getBootClassPathEntryForClass") \ - \ - /* class file format tags */ \ - template(tag_source_file, "SourceFile") \ -diff -ruNb openjdk6/hotspot/src/share/vm/code/codeBlob.cpp openjdk/hotspot/src/share/vm/code/codeBlob.cpp ---- openjdk6/hotspot/src/share/vm/code/codeBlob.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/codeBlob.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)codeBlob.cpp 1.128 07/05/05 17:05:19 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/code/codeBlob.hpp openjdk/hotspot/src/share/vm/code/codeBlob.hpp ---- openjdk6/hotspot/src/share/vm/code/codeBlob.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/codeBlob.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)codeBlob.hpp 1.125 07/05/05 17:05:18 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/code/codeCache.cpp openjdk/hotspot/src/share/vm/code/codeCache.cpp ---- openjdk6/hotspot/src/share/vm/code/codeCache.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/codeCache.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)codeCache.cpp 1.132 07/05/05 17:05:19 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -358,7 +355,7 @@ - #endif // PRODUCT - - --int CodeCache::mark_for_deoptimization(klassOop dependee) { -+int CodeCache::mark_for_deoptimization(DepChange& changes) { - MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - - #ifndef PRODUCT -@@ -369,26 +366,27 @@ - int number_of_marked_CodeBlobs = 0; - - // search the hierarchy looking for nmethods which are affected by the loading of this class -- for (klassOop d = dependee; d != NULL; d = instanceKlass::cast(d)->super()) { -- number_of_marked_CodeBlobs += instanceKlass::cast(d)->mark_dependent_nmethods(dependee); -- } -+ - // then search the interfaces this class implements looking for nmethods - // which might be dependent of the fact that an interface only had one - // implementor. -- objArrayOop interfaces = instanceKlass::cast(dependee)->transitive_interfaces(); -- int number_of_interfaces = interfaces->length(); -- for (int interface_index = 0; interface_index < number_of_interfaces; interface_index += 1) { -- klassOop d = klassOop(interfaces->obj_at(interface_index)); -- number_of_marked_CodeBlobs += instanceKlass::cast(d)->mark_dependent_nmethods(dependee); -+ -+ { No_Safepoint_Verifier nsv; -+ for (DepChange::ContextStream str(changes, nsv); str.next(); ) { -+ klassOop d = str.klass(); -+ number_of_marked_CodeBlobs += instanceKlass::cast(d)->mark_dependent_nmethods(changes); -+ } - } - - if (VerifyDependencies) { -+ // Turn off dependency tracing while actually testing deps. -+ NOT_PRODUCT( FlagSetting fs(TraceDependencies, false) ); - FOR_ALL_ALIVE_NMETHODS(nm) { - if (!nm->is_marked_for_deoptimization() && -- nm->is_dependent_on(NULL)) { -+ nm->check_all_dependencies()) { - ResourceMark rm; - tty->print_cr("Should have been marked for deoptimization:"); -- tty->print_cr(" dependee = %s", instanceKlass::cast(dependee)->external_name()); -+ changes.print(); - nm->print(); - nm->print_dependencies(); - } -diff -ruNb openjdk6/hotspot/src/share/vm/code/codeCache.hpp openjdk/hotspot/src/share/vm/code/codeCache.hpp ---- openjdk6/hotspot/src/share/vm/code/codeCache.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/codeCache.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)codeCache.hpp 1.67 07/05/05 17:05:18 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -35,6 +32,7 @@ - // locating a method given a addess of an instruction. - - class OopClosure; -+class DepChange; - - class CodeCache : AllStatic { - friend class VMStructs; -@@ -116,7 +114,7 @@ - static void clear_inline_caches(); // clear all inline caches - - // Deoptimization -- static int mark_for_deoptimization(klassOop dependee); -+ static int mark_for_deoptimization(DepChange& changes); - #ifdef HOTSWAP - static int mark_for_evol_deoptimization(instanceKlassHandle dependee); - #endif // HOTSWAP -diff -ruNb openjdk6/hotspot/src/share/vm/code/compiledIC.cpp openjdk/hotspot/src/share/vm/code/compiledIC.cpp ---- openjdk6/hotspot/src/share/vm/code/compiledIC.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/compiledIC.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)compiledIC.cpp 1.157 07/05/05 17:05:18 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/code/compiledIC.hpp openjdk/hotspot/src/share/vm/code/compiledIC.hpp ---- openjdk6/hotspot/src/share/vm/code/compiledIC.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/compiledIC.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)compiledIC.hpp 1.52 07/05/05 17:05:19 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -242,5 +239,3 @@ - inline CompiledStaticCall* compiledStaticCall_at(Relocation* call_site) { - return compiledStaticCall_at(call_site->addr()); - } -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/code/compressedStream.cpp openjdk/hotspot/src/share/vm/code/compressedStream.cpp ---- openjdk6/hotspot/src/share/vm/code/compressedStream.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/compressedStream.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)compressedStream.cpp 1.27 07/05/05 17:05:20 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/code/compressedStream.hpp openjdk/hotspot/src/share/vm/code/compressedStream.hpp ---- openjdk6/hotspot/src/share/vm/code/compressedStream.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/compressedStream.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)compressedStream.hpp 1.27 07/05/05 17:05:20 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/code/debugInfo.cpp openjdk/hotspot/src/share/vm/code/debugInfo.cpp ---- openjdk6/hotspot/src/share/vm/code/debugInfo.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/debugInfo.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)debugInfo.cpp 1.34 07/05/05 17:05:19 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -36,14 +33,43 @@ - } - - // Serializing oops -+ - void DebugInfoWriteStream::write_handle(jobject h) { - write_int(recorder()->oop_recorder()->find_index(h)); - } - -+ScopeValue* DebugInfoReadStream::read_object_value() { -+ int id = read_int(); -+#ifdef ASSERT -+ assert(_obj_pool != NULL, "object pool does not exist"); -+ for (int i = _obj_pool->length() - 1; i >= 0; i--) { -+ assert(((ObjectValue*) _obj_pool->at(i))->id() != id, "should not be read twice"); -+ } -+#endif -+ ObjectValue* result = new ObjectValue(id); -+ _obj_pool->append(result); -+ result->read_object(this); -+ return result; -+} -+ -+ScopeValue* DebugInfoReadStream::get_cached_object() { -+ int id = read_int(); -+ assert(_obj_pool != NULL, "object pool does not exist"); -+ for (int i = _obj_pool->length() - 1; i >= 0; i--) { -+ ObjectValue* sv = (ObjectValue*) _obj_pool->at(i); -+ if (sv->id() == id) { -+ return sv; -+ } -+ } -+ ShouldNotReachHere(); -+ return NULL; -+} -+ - // Serializing scope values - - enum { LOCATION_CODE = 0, CONSTANT_INT_CODE = 1, CONSTANT_OOP_CODE = 2, -- CONSTANT_LONG_CODE = 3, CONSTANT_DOUBLE_CODE = 4 }; -+ CONSTANT_LONG_CODE = 3, CONSTANT_DOUBLE_CODE = 4, -+ OBJECT_CODE = 5, OBJECT_ID_CODE = 6 }; - - ScopeValue* ScopeValue::read_from(DebugInfoReadStream* stream) { - ScopeValue* result = NULL; -@@ -53,6 +79,8 @@ - case CONSTANT_OOP_CODE: result = new ConstantOopReadValue(stream); break; - case CONSTANT_LONG_CODE: result = new ConstantLongValue(stream); break; - case CONSTANT_DOUBLE_CODE: result = new ConstantDoubleValue(stream); break; -+ case OBJECT_CODE: result = stream->read_object_value(); break; -+ case OBJECT_ID_CODE: result = stream->get_cached_object(); break; - default: ShouldNotReachHere(); - } - return result; -@@ -73,6 +101,51 @@ - location().print_on(st); - } - -+// ObjectValue -+ -+void ObjectValue::read_object(DebugInfoReadStream* stream) { -+ _klass = read_from(stream); -+ assert(_klass->is_constant_oop(), "should be constant klass oop"); -+ int length = stream->read_int(); -+ for (int i = 0; i < length; i++) { -+ ScopeValue* val = read_from(stream); -+ _field_values.append(val); -+ } -+} -+ -+void ObjectValue::write_on(DebugInfoWriteStream* stream) { -+ if (_visited) { -+ stream->write_int(OBJECT_ID_CODE); -+ stream->write_int(_id); -+ } else { -+ _visited = true; -+ stream->write_int(OBJECT_CODE); -+ stream->write_int(_id); -+ _klass->write_on(stream); -+ int length = _field_values.length(); -+ stream->write_int(length); -+ for (int i = 0; i < length; i++) { -+ _field_values.at(i)->write_on(stream); -+ } -+ } -+} -+ -+void ObjectValue::print_on(outputStream* st) const { -+ st->print("obj[%d]", _id); -+} -+ -+void ObjectValue::print_fields_on(outputStream* st) const { -+#ifndef PRODUCT -+ if (_field_values.length() > 0) { -+ _field_values.at(0)->print_on(st); -+ } -+ for (int i = 1; i < _field_values.length(); i++) { -+ st->print(", "); -+ _field_values.at(i)->print_on(st); -+ } -+#endif -+} -+ - // ConstantIntValue - - ConstantIntValue::ConstantIntValue(DebugInfoReadStream* stream) { -@@ -147,19 +220,22 @@ - - // MonitorValue - --MonitorValue::MonitorValue(ScopeValue* owner, Location basic_lock) { -+MonitorValue::MonitorValue(ScopeValue* owner, Location basic_lock, bool eliminated) { - _owner = owner; - _basic_lock = basic_lock; -+ _eliminated = eliminated; - } - - MonitorValue::MonitorValue(DebugInfoReadStream* stream) { - _basic_lock = Location(stream); - _owner = ScopeValue::read_from(stream); -+ _eliminated = (stream->read_bool() != 0); - } - - void MonitorValue::write_on(DebugInfoWriteStream* stream) { - _basic_lock.write_on(stream); - _owner->write_on(stream); -+ stream->write_bool(_eliminated); - } - - #ifndef PRODUCT -@@ -169,6 +245,8 @@ - st->print(","); - basic_lock().print_on(st); - st->print("}"); -+ if (_eliminated) { -+ st->print(" (eliminated)"); -+ } - } - #endif -- -diff -ruNb openjdk6/hotspot/src/share/vm/code/debugInfo.hpp openjdk/hotspot/src/share/vm/code/debugInfo.hpp ---- openjdk6/hotspot/src/share/vm/code/debugInfo.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/debugInfo.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)debugInfo.hpp 1.34 07/05/05 17:05:20 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -37,6 +34,7 @@ - public: - // Testers - virtual bool is_location() const { return false; } -+ virtual bool is_object() const { return false; } - virtual bool is_constant_int() const { return false; } - virtual bool is_constant_double() const { return false; } - virtual bool is_constant_long() const { return false; } -@@ -68,6 +66,57 @@ - void print_on(outputStream* st) const; - }; - -+ -+// An ObjectValue describes an object eliminated by escape analysis. -+ -+class ObjectValue: public ScopeValue { -+ private: -+ int _id; -+ ScopeValue* _klass; -+ GrowableArray _field_values; -+ Handle _value; -+ bool _visited; -+ -+ public: -+ ObjectValue(int id, ScopeValue* klass) -+ : _id(id) -+ , _klass(klass) -+ , _field_values() -+ , _value() -+ , _visited(false) { -+ assert(klass->is_constant_oop(), "should be constant klass oop"); -+ } -+ -+ ObjectValue(int id) -+ : _id(id) -+ , _klass(NULL) -+ , _field_values() -+ , _value() -+ , _visited(false) {} -+ -+ // Accessors -+ bool is_object() const { return true; } -+ int id() const { return _id; } -+ ScopeValue* klass() const { return _klass; } -+ GrowableArray* field_values() { return &_field_values; } -+ ScopeValue* field_at(int i) const { return _field_values.at(i); } -+ int field_size() { return _field_values.length(); } -+ Handle value() const { return _value; } -+ bool is_visited() const { return _visited; } -+ -+ void set_value(oop value) { _value = Handle(value); } -+ void set_visited(bool visited) { _visited = false; } -+ -+ // Serialization of debugging information -+ void read_object(DebugInfoReadStream* stream); -+ void write_on(DebugInfoWriteStream* stream); -+ -+ // Printing -+ void print_on(outputStream* st) const; -+ void print_fields_on(outputStream* st) const; -+}; -+ -+ - // A ConstantIntValue describes a constant int; i.e., the corresponding logical entity - // is either a source constant or its computation has been constant-folded. - -@@ -166,13 +215,15 @@ - private: - ScopeValue* _owner; - Location _basic_lock; -+ bool _eliminated; - public: - // Constructor -- MonitorValue(ScopeValue* owner, Location basic_lock); -+ MonitorValue(ScopeValue* owner, Location basic_lock, bool eliminated = false); - - // Accessors - ScopeValue* owner() const { return _owner; } - Location basic_lock() const { return _basic_lock; } -+ bool eliminated() const { return _eliminated; } - - // Serialization of debugging information - MonitorValue(DebugInfoReadStream* stream); -@@ -189,15 +240,20 @@ - private: - const nmethod* _code; - const nmethod* code() const { return _code; } -+ GrowableArray* _obj_pool; - public: -- DebugInfoReadStream(const nmethod* code, int offset) : -+ DebugInfoReadStream(const nmethod* code, int offset, GrowableArray* obj_pool = NULL) : - CompressedReadStream(code->scopes_data_begin(), offset) { - _code = code; -+ _obj_pool = obj_pool; -+ - } ; - - oop read_oop() { - return code()->oop_at(read_int()); - } -+ ScopeValue* read_object_value(); -+ ScopeValue* get_cached_object(); - // BCI encoding is mostly unsigned, but -1 is a distinguished value - int read_bci() { return read_int() + InvocationEntryBci; } - }; -@@ -214,4 +270,3 @@ - void write_handle(jobject h); - void write_bci(int bci) { write_int(bci - InvocationEntryBci); } - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/code/debugInfoRec.cpp openjdk/hotspot/src/share/vm/code/debugInfoRec.cpp ---- openjdk6/hotspot/src/share/vm/code/debugInfoRec.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/debugInfoRec.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)debugInfoRec.cpp 1.54 07/05/05 17:05:20 JVM" --#endif - /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -168,7 +165,8 @@ - } - assert(_pcs_size > _pcs_length, "There must be room for after expanding"); - -- _pcs[_pcs_length++] = PcDesc(pc_offset, DebugInformationRecorder::serialized_null); -+ _pcs[_pcs_length++] = PcDesc(pc_offset, DebugInformationRecorder::serialized_null, -+ DebugInformationRecorder::serialized_null); - } - - -@@ -324,6 +322,18 @@ - } - } - -+void DebugInformationRecorder::dump_object_pool(GrowableArray* objects) { -+ guarantee( _pcs_length > 0, "safepoint must exist before describing scopes"); -+ PcDesc* last_pd = &_pcs[_pcs_length-1]; -+ if (objects != NULL) { -+ for (int i = objects->length() - 1; i >= 0; i--) { -+ ((ObjectValue*) objects->at(i))->set_visited(false); -+ } -+ } -+ int offset = serialize_scope_values(objects); -+ last_pd->set_obj_decode_offset(offset); -+} -+ - void DebugInformationRecorder::end_scopes(int pc_offset, bool is_safepoint) { - assert(_recording_state == (is_safepoint? rs_safepoint: rs_non_safepoint), - "nesting of recording calls"); -diff -ruNb openjdk6/hotspot/src/share/vm/code/debugInfoRec.hpp openjdk/hotspot/src/share/vm/code/debugInfoRec.hpp ---- openjdk6/hotspot/src/share/vm/code/debugInfoRec.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/debugInfoRec.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)debugInfoRec.hpp 1.37 07/05/05 17:05:20 JVM" --#endif - /* - * Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -94,6 +91,9 @@ - DebugToken* expressions = NULL, - DebugToken* monitors = NULL); - -+ -+ void dump_object_pool(GrowableArray* objects); -+ - // This call must follow every add_safepoint, - // after any intervening describe_scope calls. - void end_safepoint(int pc_offset) { end_scopes(pc_offset, true); } -@@ -180,4 +180,3 @@ - public: - enum { serialized_null = 0 }; - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/code/dependencies.cpp openjdk/hotspot/src/share/vm/code/dependencies.cpp ---- openjdk6/hotspot/src/share/vm/code/dependencies.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/dependencies.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)dependencies.cpp 1.16 07/05/05 17:05:20 JVM" --#endif - /* - * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -791,53 +788,147 @@ - - private: - // the actual search method: -- klassOop find_witness(klassOop context_type, -- bool search_under_participants, -- bool test_context_type); -+ klassOop find_witness_anywhere(klassOop context_type, -+ bool participants_hide_witnesses, -+ bool top_level_call = true); -+ // the spot-checking version: -+ klassOop find_witness_in(DepChange& changes, -+ klassOop context_type, -+ bool participants_hide_witnesses); - public: -- klassOop find_witness_subtype(klassOop context_type) { -+ klassOop find_witness_subtype(klassOop context_type, DepChange* changes = NULL) { - assert(doing_subtype_search(), "must set up a subtype search"); - // When looking for unexpected concrete types, - // do not look beneath expected ones. -+ const bool participants_hide_witnesses = true; - // CX > CC > C' is OK, even if C' is new. - // CX > { CC, C' } is not OK if C' is new, and C' is the witness. -- return find_witness(context_type, false, true); -+ if (changes != NULL) { -+ return find_witness_in(*changes, context_type, participants_hide_witnesses); -+ } else { -+ return find_witness_anywhere(context_type, participants_hide_witnesses); -+ } - } -- klassOop find_witness_definer(klassOop context_type) { -+ klassOop find_witness_definer(klassOop context_type, DepChange* changes = NULL) { - assert(!doing_subtype_search(), "must set up a method definer search"); - // When looking for unexpected concrete methods, - // look beneath expected ones, to see if there are overrides. -+ const bool participants_hide_witnesses = true; - // CX.m > CC.m > C'.m is not OK, if C'.m is new, and C' is the witness. -- return find_witness(context_type, true, true); -+ if (changes != NULL) { -+ return find_witness_in(*changes, context_type, !participants_hide_witnesses); -+ } else { -+ return find_witness_anywhere(context_type, !participants_hide_witnesses); -+ } - } - }; - --#ifdef ASSERT -+#ifndef PRODUCT - static int deps_find_witness_calls = 0; - static int deps_find_witness_steps = 0; - static int deps_find_witness_recursions = 0; --#endif //ASSERT -+static int deps_find_witness_singles = 0; -+static int deps_find_witness_print = 0; // set to -1 to force a final print -+static bool count_find_witness_calls() { -+ if (TraceDependencies || LogCompilation) { -+ int pcount = deps_find_witness_print + 1; -+ bool final_stats = (pcount == 0); -+ bool initial_call = (pcount == 1); -+ bool occasional_print = ((pcount & ((1<<10) - 1)) == 0); -+ if (pcount < 0) pcount = 1; // crude overflow protection -+ deps_find_witness_print = pcount; -+ if (VerifyDependencies && initial_call) { -+ tty->print_cr("Warning: TraceDependencies results may be inflated by VerifyDependencies"); -+ } -+ if (occasional_print || final_stats) { -+ // Every now and then dump a little info about dependency searching. -+ if (xtty != NULL) { -+ xtty->elem("deps_find_witness calls='%d' steps='%d' recursions='%d' singles='%d'", -+ deps_find_witness_calls, -+ deps_find_witness_steps, -+ deps_find_witness_recursions, -+ deps_find_witness_singles); -+ } -+ if (final_stats || (TraceDependencies && WizardMode)) { -+ tty->print_cr("Dependency check (find_witness) " -+ "calls=%d, steps=%d (avg=%.1f), recursions=%d, singles=%d", -+ deps_find_witness_calls, -+ deps_find_witness_steps, -+ (double)deps_find_witness_steps / deps_find_witness_calls, -+ deps_find_witness_recursions, -+ deps_find_witness_singles); -+ } -+ } -+ return true; -+ } -+ return false; -+} -+#else -+#define count_find_witness_calls() (0) -+#endif //PRODUCT -+ -+ -+klassOop ClassHierarchyWalker::find_witness_in(DepChange& changes, -+ klassOop context_type, -+ bool participants_hide_witnesses) { -+ assert(changes.involves_context(context_type), "irrelevant dependency"); -+ klassOop new_type = changes.new_type(); -+ -+ count_find_witness_calls(); -+ NOT_PRODUCT(deps_find_witness_singles++); -+ -+ // Current thread must be in VM (not native mode, as in CI): -+ assert(must_be_in_vm(), "raw oops here"); -+ // Must not move the class hierarchy during this check: -+ assert_locked_or_safepoint(Compile_lock); -+ -+ assert(!is_participant(new_type), "only old classes are participants"); -+ if (participants_hide_witnesses) { -+ // If the new type is a subtype of a participant, we are done. -+ for (int i = 0; i < num_participants(); i++) { -+ klassOop part = participant(i); -+ if (part == NULL) continue; -+ assert(changes.involves_context(part) == Klass::cast(new_type)->is_subtype_of(part), -+ "correct marking of participants, b/c new_type is unique"); -+ if (changes.involves_context(part)) { -+ // new guy is protected from this check by previous participant -+ return NULL; -+ } -+ } -+ } -+ -+ if (is_witness(new_type) && -+ !ignore_witness(new_type)) { -+ return new_type; -+ } -+ -+ return NULL; -+} -+ - - // Walk hierarchy under a context type, looking for unexpected types. - // Do not report participant types, and recursively walk beneath --// them only if search_under_participants is true. --// If test_context_type is false, skip testing the context type, -+// them only if participants_hide_witnesses is false. -+// If top_level_call is false, skip testing the context type, - // because the caller has already considered it. --klassOop ClassHierarchyWalker::find_witness(klassOop context_type, -- bool search_under_participants, -- bool test_context_type) { -- DEBUG_ONLY(deps_find_witness_calls++); -- -+klassOop ClassHierarchyWalker::find_witness_anywhere(klassOop context_type, -+ bool participants_hide_witnesses, -+ bool top_level_call) { - // Current thread must be in VM (not native mode, as in CI): - assert(must_be_in_vm(), "raw oops here"); - // Must not move the class hierarchy during this check: - assert_locked_or_safepoint(Compile_lock); - -+ bool do_counts = count_find_witness_calls(); -+ - // Check the root of the sub-hierarchy first. -- if (test_context_type) { -- DEBUG_ONLY(deps_find_witness_steps++); -+ if (top_level_call) { -+ if (do_counts) { -+ NOT_PRODUCT(deps_find_witness_calls++); -+ NOT_PRODUCT(deps_find_witness_steps++); -+ } - if (is_participant(context_type)) { -- if (!search_under_participants) return NULL; -+ if (participants_hide_witnesses) return NULL; - // else fall through to search loop... - } else if (is_witness(context_type) && !ignore_witness(context_type)) { - // The context is an abstract class or interface, to start with. -@@ -882,9 +973,10 @@ - // implementors array overflowed => no exact info. - return context_type; // report an inexact witness to this sad affair - } -- DEBUG_ONLY(deps_find_witness_steps++); -+ if (do_counts) -+ { NOT_PRODUCT(deps_find_witness_steps++); } - if (is_participant(impl)) { -- if (!search_under_participants) continue; -+ if (participants_hide_witnesses) continue; - // else fall through to process this guy's subclasses - } else if (is_witness(impl) && !ignore_witness(impl)) { - return impl; -@@ -897,9 +989,9 @@ - Klass* chain = chains[--chaini]; - for (Klass* subk = chain; subk != NULL; subk = subk->next_sibling()) { - klassOop sub = subk->as_klassOop(); -- DEBUG_ONLY(deps_find_witness_steps++); -+ if (do_counts) { NOT_PRODUCT(deps_find_witness_steps++); } - if (is_participant(sub)) { -- if (!search_under_participants) continue; -+ if (participants_hide_witnesses) continue; - // else fall through to process this guy's subclasses - } else if (is_witness(sub) && !ignore_witness(sub)) { - return sub; -@@ -913,8 +1005,10 @@ - // (Note that sub has already been tested, so that there is - // no need for the recursive call to re-test. That's handy, - // since the recursive call sees sub as the context_type.) -- DEBUG_ONLY(deps_find_witness_recursions++); -- klassOop witness = find_witness(sub, search_under_participants, false); -+ if (do_counts) { NOT_PRODUCT(deps_find_witness_recursions++); } -+ klassOop witness = find_witness_anywhere(sub, -+ participants_hide_witnesses, -+ /*top_level_call=*/ false); - if (witness != NULL) return witness; - } - } -@@ -925,6 +1019,7 @@ - #undef ADD_SUBCLASS_CHAIN - } - -+ - bool Dependencies::is_concrete_klass(klassOop k) { - if (Klass::cast(k)->is_abstract()) return false; - // %%% We could treat classes which are concrete but -@@ -1023,27 +1118,30 @@ - // This allows the compiler to narrow occurrences of ctxk by conck, - // when dealing with the types of actual instances. - klassOop Dependencies::check_abstract_with_unique_concrete_subtype(klassOop ctxk, -- klassOop conck) { -+ klassOop conck, -+ DepChange* changes) { - ClassHierarchyWalker wf(conck); -- return wf.find_witness_subtype(ctxk); -+ return wf.find_witness_subtype(ctxk, changes); - } - - // If a non-concrete class has no concrete subtypes, it is not (yet) - // instantiatable. This can allow the compiler to make some paths go - // dead, if they are gated by a test of the type. --klassOop Dependencies::check_abstract_with_no_concrete_subtype(klassOop ctxk) { -+klassOop Dependencies::check_abstract_with_no_concrete_subtype(klassOop ctxk, -+ DepChange* changes) { - // Find any concrete subtype, with no participants: - ClassHierarchyWalker wf; -- return wf.find_witness_subtype(ctxk); -+ return wf.find_witness_subtype(ctxk, changes); - } - - - // If a concrete class has no concrete subtypes, it can always be - // exactly typed. This allows the use of a cheaper type test. --klassOop Dependencies::check_concrete_with_no_concrete_subtype(klassOop ctxk) { -+klassOop Dependencies::check_concrete_with_no_concrete_subtype(klassOop ctxk, -+ DepChange* changes) { - // Find any concrete subtype, with only the ctxk as participant: - ClassHierarchyWalker wf(ctxk); -- return wf.find_witness_subtype(ctxk); -+ return wf.find_witness_subtype(ctxk, changes); - } - - -@@ -1062,6 +1160,8 @@ - #ifndef PRODUCT - // Make sure the dependency mechanism will pass this discovery: - if (VerifyDependencies) { -+ // Turn off dependency tracing while actually testing deps. -+ FlagSetting fs(TraceDependencies, false); - if (!Dependencies::is_concrete_klass(ctxk)) { - guarantee(NULL == - (void *)check_abstract_with_no_concrete_subtype(ctxk), -@@ -1078,6 +1178,8 @@ - #ifndef PRODUCT - // Make sure the dependency mechanism will pass this discovery: - if (VerifyDependencies) { -+ // Turn off dependency tracing while actually testing deps. -+ FlagSetting fs(TraceDependencies, false); - if (!Dependencies::is_concrete_klass(ctxk)) { - guarantee(NULL == (void *) - check_abstract_with_unique_concrete_subtype(ctxk, conck), -@@ -1096,11 +1198,12 @@ - klassOop Dependencies::check_abstract_with_exclusive_concrete_subtypes( - klassOop ctxk, - klassOop k1, -- klassOop k2) { -+ klassOop k2, -+ DepChange* changes) { - ClassHierarchyWalker wf; - wf.add_participant(k1); - wf.add_participant(k2); -- return wf.find_witness_subtype(ctxk); -+ return wf.find_witness_subtype(ctxk, changes); - } - - // Search ctxk for concrete implementations. If there are klen or fewer, -@@ -1124,6 +1227,8 @@ - #ifndef PRODUCT - // Make sure the dependency mechanism will pass this discovery: - if (VerifyDependencies) { -+ // Turn off dependency tracing while actually testing deps. -+ FlagSetting fs(TraceDependencies, false); - switch (Dependencies::is_concrete_klass(ctxk)? -1: num) { - case -1: // ctxk was itself concrete - guarantee(num == 1 && karray[0] == ctxk, "verify dep."); -@@ -1154,13 +1259,14 @@ - - // If a class (or interface) has a unique concrete method uniqm, return NULL. - // Otherwise, return a class that contains an interfering method. --klassOop Dependencies::check_unique_concrete_method(klassOop ctxk, methodOop uniqm) { -+klassOop Dependencies::check_unique_concrete_method(klassOop ctxk, methodOop uniqm, -+ DepChange* changes) { - // Here is a missing optimization: If uniqm->is_final(), - // we don't really need to search beneath it for overrides. - // This is probably not important, since we don't use dependencies - // to track final methods. (They can't be "definalized".) - ClassHierarchyWalker wf(uniqm->method_holder(), uniqm); -- return wf.find_witness_definer(ctxk); -+ return wf.find_witness_definer(ctxk, changes); - } - - // Find the set of all non-abstract methods under ctxk that match m. -@@ -1196,11 +1302,12 @@ - - klassOop Dependencies::check_exclusive_concrete_methods(klassOop ctxk, - methodOop m1, -- methodOop m2) { -+ methodOop m2, -+ DepChange* changes) { - ClassHierarchyWalker wf(m1); - wf.add_participant(m1->method_holder()); - wf.add_participant(m2->method_holder()); -- return wf.find_witness_definer(ctxk); -+ return wf.find_witness_definer(ctxk, changes); - } - - // Find the set of all non-abstract methods under ctxk that match m[0]. -@@ -1216,6 +1323,7 @@ - ClassHierarchyWalker wf(m0); - assert(wf.check_method_context(ctxk, m0), "proper context"); - wf.record_witnesses(mlen); -+ bool participants_hide_witnesses = true; - klassOop wit = wf.find_witness_definer(ctxk); - if (wit != NULL) return -1; // Too many witnesses. - int num = wf.num_participants(); -@@ -1236,6 +1344,8 @@ - #ifndef PRODUCT - // Make sure the dependency mechanism will pass this discovery: - if (VerifyDependencies) { -+ // Turn off dependency tracing while actually testing deps. -+ FlagSetting fs(TraceDependencies, false); - switch (mfill) { - case 1: - guarantee(NULL == (void *)check_unique_concrete_method(ctxk, marray[0]), -@@ -1255,8 +1365,11 @@ - } - - --klassOop Dependencies::check_has_no_finalizable_subclasses(klassOop ctxk) { -- Klass* result = find_finalizable_subclass(ctxk->klass_part()); -+klassOop Dependencies::check_has_no_finalizable_subclasses(klassOop ctxk, DepChange* changes) { -+ Klass* search_at = ctxk->klass_part(); -+ if (changes != NULL) -+ search_at = changes->new_type()->klass_part(); // just look at the new bit -+ Klass* result = find_finalizable_subclass(search_at); - if (result == NULL) { - return NULL; - } -@@ -1264,7 +1377,7 @@ - } - - --klassOop Dependencies::DepStream::check_dependency() { -+klassOop Dependencies::DepStream::check_dependency_impl(DepChange* changes) { - assert_locked_or_safepoint(Compile_lock); - - klassOop witness = NULL; -@@ -1277,30 +1390,37 @@ - break; - case abstract_with_unique_concrete_subtype: - witness = check_abstract_with_unique_concrete_subtype(context_type(), -- type_argument(1)); -+ type_argument(1), -+ changes); - break; - case abstract_with_no_concrete_subtype: -- witness = check_abstract_with_no_concrete_subtype(context_type()); -+ witness = check_abstract_with_no_concrete_subtype(context_type(), -+ changes); - break; - case concrete_with_no_concrete_subtype: -- witness = check_concrete_with_no_concrete_subtype(context_type()); -+ witness = check_concrete_with_no_concrete_subtype(context_type(), -+ changes); - break; - case unique_concrete_method: - witness = check_unique_concrete_method(context_type(), -- method_argument(1)); -+ method_argument(1), -+ changes); - break; - case abstract_with_exclusive_concrete_subtypes_2: - witness = check_abstract_with_exclusive_concrete_subtypes(context_type(), - type_argument(1), -- type_argument(2)); -+ type_argument(2), -+ changes); - break; - case exclusive_concrete_methods_2: - witness = check_exclusive_concrete_methods(context_type(), - method_argument(1), -- method_argument(2)); -+ method_argument(2), -+ changes); - break; - case no_finalizable_subclasses: -- witness = check_has_no_finalizable_subclasses(context_type()); -+ witness = check_has_no_finalizable_subclasses(context_type(), -+ changes); - break; - default: - witness = NULL; -@@ -1316,3 +1436,114 @@ - } - return witness; - } -+ -+ -+klassOop Dependencies::DepStream::spot_check_dependency_at(DepChange& changes) { -+ if (!changes.involves_context(context_type())) -+ // irrelevant dependency; skip it -+ return NULL; -+ -+ return check_dependency_impl(&changes); -+} -+ -+ -+void DepChange::initialize() { -+ // entire transaction must be under this lock: -+ assert_lock_strong(Compile_lock); -+ -+ // Mark all dependee and all its superclasses -+ // Mark transitive interfaces -+ for (ContextStream str(*this); str.next(); ) { -+ klassOop d = str.klass(); -+ assert(!instanceKlass::cast(d)->is_marked_dependent(), "checking"); -+ instanceKlass::cast(d)->set_is_marked_dependent(true); -+ } -+} -+ -+DepChange::~DepChange() { -+ // Unmark all dependee and all its superclasses -+ // Unmark transitive interfaces -+ for (ContextStream str(*this); str.next(); ) { -+ klassOop d = str.klass(); -+ instanceKlass::cast(d)->set_is_marked_dependent(false); -+ } -+} -+ -+bool DepChange::involves_context(klassOop k) { -+ if (k == NULL || !Klass::cast(k)->oop_is_instance()) { -+ return false; -+ } -+ instanceKlass* ik = instanceKlass::cast(k); -+ bool is_contained = ik->is_marked_dependent(); -+ assert(is_contained == Klass::cast(new_type())->is_subtype_of(k), -+ "correct marking of potential context types"); -+ return is_contained; -+} -+ -+bool DepChange::ContextStream::next() { -+ switch (_change_type) { -+ case Start_Klass: // initial state; _klass is the new type -+ _ti_base = instanceKlass::cast(_klass)->transitive_interfaces(); -+ _ti_index = 0; -+ _change_type = Change_new_type; -+ return true; -+ case Change_new_type: -+ // fall through: -+ _change_type = Change_new_sub; -+ case Change_new_sub: -+ _klass = instanceKlass::cast(_klass)->super(); -+ if (_klass != NULL) { -+ return true; -+ } -+ // else set up _ti_limit and fall through: -+ _ti_limit = (_ti_base == NULL) ? 0 : _ti_base->length(); -+ _change_type = Change_new_impl; -+ case Change_new_impl: -+ if (_ti_index < _ti_limit) { -+ _klass = klassOop( _ti_base->obj_at(_ti_index++) ); -+ return true; -+ } -+ // fall through: -+ _change_type = NO_CHANGE; // iterator is exhausted -+ case NO_CHANGE: -+ break; -+ default: -+ ShouldNotReachHere(); -+ } -+ return false; -+} -+ -+void DepChange::print() { -+ int nsup = 0, nint = 0; -+ for (ContextStream str(*this); str.next(); ) { -+ klassOop k = str.klass(); -+ switch (str._change_type) { -+ case Change_new_type: -+ tty->print_cr(" dependee = %s", instanceKlass::cast(k)->external_name()); -+ break; -+ case Change_new_sub: -+ if (!WizardMode) -+ ++nsup; -+ else tty->print_cr(" context super = %s", instanceKlass::cast(k)->external_name()); -+ break; -+ case Change_new_impl: -+ if (!WizardMode) -+ ++nint; -+ else tty->print_cr(" context interface = %s", instanceKlass::cast(k)->external_name()); -+ break; -+ } -+ } -+ if (nsup + nint != 0) { -+ tty->print_cr(" context supers = %d, interfaces = %d", nsup, nint); -+ } -+} -+ -+#ifndef PRODUCT -+void Dependencies::print_statistics() { -+ if (deps_find_witness_print != 0) { -+ // Call one final time, to flush out the data. -+ deps_find_witness_print = -1; -+ count_find_witness_calls(); -+ } -+} -+#endif -diff -ruNb openjdk6/hotspot/src/share/vm/code/dependencies.hpp openjdk/hotspot/src/share/vm/code/dependencies.hpp ---- openjdk6/hotspot/src/share/vm/code/dependencies.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/dependencies.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)dependencies.hpp 1.11 07/05/05 17:05:18 JVM" --#endif - /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -46,6 +43,8 @@ - class OopRecorder; - class xmlStream; - class CompileLog; -+class DepChange; -+class No_Safepoint_Verifier; - - class Dependencies: public ResourceObj { - public: -@@ -288,13 +287,20 @@ - // Checking old assertions at run-time (in the VM only): - static klassOop check_evol_method(methodOop m); - static klassOop check_leaf_type(klassOop ctxk); -- static klassOop check_abstract_with_unique_concrete_subtype(klassOop ctxk, klassOop conck); -- static klassOop check_abstract_with_no_concrete_subtype(klassOop ctxk); -- static klassOop check_concrete_with_no_concrete_subtype(klassOop ctxk); -- static klassOop check_unique_concrete_method(klassOop ctxk, methodOop uniqm); -- static klassOop check_abstract_with_exclusive_concrete_subtypes(klassOop ctxk, klassOop k1, klassOop k2); -- static klassOop check_exclusive_concrete_methods(klassOop ctxk, methodOop m1, methodOop m2); -- static klassOop check_has_no_finalizable_subclasses(klassOop ctxk); -+ static klassOop check_abstract_with_unique_concrete_subtype(klassOop ctxk, klassOop conck, -+ DepChange* changes = NULL); -+ static klassOop check_abstract_with_no_concrete_subtype(klassOop ctxk, -+ DepChange* changes = NULL); -+ static klassOop check_concrete_with_no_concrete_subtype(klassOop ctxk, -+ DepChange* changes = NULL); -+ static klassOop check_unique_concrete_method(klassOop ctxk, methodOop uniqm, -+ DepChange* changes = NULL); -+ static klassOop check_abstract_with_exclusive_concrete_subtypes(klassOop ctxk, klassOop k1, klassOop k2, -+ DepChange* changes = NULL); -+ static klassOop check_exclusive_concrete_methods(klassOop ctxk, methodOop m1, methodOop m2, -+ DepChange* changes = NULL); -+ static klassOop check_has_no_finalizable_subclasses(klassOop ctxk, -+ DepChange* changes = NULL); - // A returned klassOop is NULL if the dependency assertion is still - // valid. A non-NULL klassOop is a 'witness' to the assertion - // failure, a point in the class hierarchy where the assertion has -@@ -305,6 +311,10 @@ - // witnesses to the failure. The value returned from the check_foo - // method is chosen arbitrarily. - -+ // The 'changes' value, if non-null, requests a limited spot-check -+ // near the indicated recent changes in the class hierarchy. -+ // It is used by DepStream::spot_check_dependency_at. -+ - // Detecting possible new assertions: - static klassOop find_unique_concrete_subtype(klassOop ctxk); - static methodOop find_unique_concrete_method(klassOop ctxk, methodOop m); -@@ -397,6 +407,8 @@ - inline oop recorded_oop_at(int i); - // => _code? _code->oop_at(i): *_deps->_oop_recorder->handle_at(i) - -+ klassOop check_dependency_impl(DepChange* changes); -+ - public: - DepStream(Dependencies* deps) - : _deps(deps), -@@ -434,7 +446,12 @@ - } - - // The point of the whole exercise: Is this dep is still OK? -- klassOop check_dependency(); -+ klassOop check_dependency() { -+ return check_dependency_impl(NULL); -+ } -+ // A lighter version: Checks only around recent changes in a class -+ // hierarchy. (See Universe::flush_dependents_on.) -+ klassOop spot_check_dependency_at(DepChange& changes); - - // Log the current dependency to xtty or compilation log. - void log_dependency(klassOop witness = NULL); -@@ -443,4 +460,91 @@ - void print_dependency(klassOop witness = NULL, bool verbose = false); - }; - friend class Dependencies::DepStream; -+ -+ static void print_statistics() PRODUCT_RETURN; -+}; -+ -+// A class hierarchy change coming through the VM (under the Compile_lock). -+// The change is structured as a single new type with any number of supers -+// and implemented interface types. Other than the new type, any of the -+// super types can be context types for a relevant dependency, which the -+// new type could invalidate. -+class DepChange : public StackObj { -+ private: -+ enum ChangeType { -+ NO_CHANGE = 0, // an uninvolved klass -+ Change_new_type, // a newly loaded type -+ Change_new_sub, // a super with a new subtype -+ Change_new_impl, // an interface with a new implementation -+ CHANGE_LIMIT, -+ Start_Klass = CHANGE_LIMIT // internal indicator for ContextStream -+ }; -+ -+ // each change set is rooted in exactly one new type (at present): -+ KlassHandle _new_type; -+ -+ void initialize(); -+ -+ public: -+ // notes the new type, marks it and all its super-types -+ DepChange(KlassHandle new_type) -+ : _new_type(new_type) -+ { -+ initialize(); -+ } -+ -+ // cleans up the marks -+ ~DepChange(); -+ -+ klassOop new_type() { return _new_type(); } -+ -+ // involves_context(k) is true if k is new_type or any of the super types -+ bool involves_context(klassOop k); -+ -+ // Usage: -+ // for (DepChange::ContextStream str(changes); str.next(); ) { -+ // klassOop k = str.klass(); -+ // switch (str.change_type()) { -+ // ... -+ // } -+ // } -+ class ContextStream : public StackObj { -+ private: -+ DepChange& _changes; -+ friend class DepChange; -+ -+ // iteration variables: -+ ChangeType _change_type; -+ klassOop _klass; -+ objArrayOop _ti_base; // i.e., transitive_interfaces -+ int _ti_index; -+ int _ti_limit; -+ -+ // start at the beginning: -+ void start() { -+ klassOop new_type = _changes.new_type(); -+ _change_type = (new_type == NULL ? NO_CHANGE: Start_Klass); -+ _klass = new_type; -+ _ti_base = NULL; -+ _ti_index = 0; -+ _ti_limit = 0; -+ } -+ -+ ContextStream(DepChange& changes) -+ : _changes(changes) -+ { start(); } -+ -+ public: -+ ContextStream(DepChange& changes, No_Safepoint_Verifier& nsv) -+ : _changes(changes) -+ // the nsv argument makes it safe to hold oops like _klass -+ { start(); } -+ -+ bool next(); -+ -+ klassOop klass() { return _klass; } -+ }; -+ friend class DepChange::ContextStream; -+ -+ void print(); - }; -diff -ruNb openjdk6/hotspot/src/share/vm/code/exceptionHandlerTable.cpp openjdk/hotspot/src/share/vm/code/exceptionHandlerTable.cpp ---- openjdk6/hotspot/src/share/vm/code/exceptionHandlerTable.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/exceptionHandlerTable.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)exceptionHandlerTable.cpp 1.33 07/05/05 17:05:20 JVM" --#endif - /* - * Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/code/exceptionHandlerTable.hpp openjdk/hotspot/src/share/vm/code/exceptionHandlerTable.hpp ---- openjdk6/hotspot/src/share/vm/code/exceptionHandlerTable.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/exceptionHandlerTable.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)exceptionHandlerTable.hpp 1.30 07/05/05 17:05:21 JVM" --#endif - /* - * Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/code/icBuffer.cpp openjdk/hotspot/src/share/vm/code/icBuffer.cpp ---- openjdk6/hotspot/src/share/vm/code/icBuffer.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/icBuffer.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)icBuffer.cpp 1.70 07/05/05 17:05:21 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -187,6 +184,3 @@ - ICStub* stub = ICStub_from_destination_address(ic->stub_address()); - return stub->cached_oop(); - } -- -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/code/icBuffer.hpp openjdk/hotspot/src/share/vm/code/icBuffer.hpp ---- openjdk6/hotspot/src/share/vm/code/icBuffer.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/icBuffer.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)icBuffer.hpp 1.30 07/05/05 17:05:21 JVM" --#endif - /* - * Copyright 1997-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/code/location.cpp openjdk/hotspot/src/share/vm/code/location.cpp ---- openjdk6/hotspot/src/share/vm/code/location.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/location.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)location.cpp 1.40 07/05/05 17:05:21 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -70,4 +67,3 @@ - if ((offset_in_bytes % BytesPerInt) != 0) return false; - return (offset_in_bytes / BytesPerInt) < (OFFSET_MASK >> OFFSET_SHIFT); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/code/location.hpp openjdk/hotspot/src/share/vm/code/location.hpp ---- openjdk6/hotspot/src/share/vm/code/location.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/location.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)location.hpp 1.47 07/05/05 17:05:21 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/code/nmethod.cpp openjdk/hotspot/src/share/vm/code/nmethod.cpp ---- openjdk6/hotspot/src/share/vm/code/nmethod.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/nmethod.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)nmethod.cpp 1.366 07/06/08 15:21:44 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -316,6 +313,18 @@ - // Note: Do not update _last_pc_desc. It fronts for the LRU cache. - } - -+// adjust pcs_size so that it is a multiple of both oopSize and -+// sizeof(PcDesc) (assumes that if sizeof(PcDesc) is not a multiple -+// of oopSize, then 2*sizeof(PcDesc) is) -+static int adjust_pcs_size(int pcs_size) { -+ int nsize = round_to(pcs_size, oopSize); -+ if ((nsize % sizeof(PcDesc)) != 0) { -+ nsize = pcs_size + sizeof(PcDesc); -+ } -+ assert((nsize % oopSize) == 0, "correct alignment"); -+ return nsize; -+} -+ - //----------------------------------------------------------------------------- - - -@@ -473,7 +482,7 @@ - { MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); - int nmethod_size = - allocation_size(code_buffer, sizeof(nmethod)) -- + round_to(debug_info->pcs_size() , oopSize) -+ + adjust_pcs_size(debug_info->pcs_size()) - + round_to(dependencies->size_in_bytes() , oopSize) - + round_to(handler_table->size_in_bytes(), oopSize) - + round_to(nul_chk_table->size_in_bytes(), oopSize) -@@ -596,6 +605,9 @@ - print_code(); - oop_maps->print(); - } -+ if (PrintRelocations) { -+ print_relocations(); -+ } - if (xtty != NULL) { - xtty->tail("print_native_nmethod"); - } -@@ -654,7 +666,7 @@ - _consts_offset = instructions_offset() + code_buffer->total_offset_of(code_buffer->consts()->start()); - _scopes_data_offset = data_offset(); - _scopes_pcs_offset = _scopes_data_offset + round_to(debug_info->data_size (), oopSize); -- _dependencies_offset = _scopes_pcs_offset + round_to(debug_info->pcs_size (), oopSize); -+ _dependencies_offset = _scopes_pcs_offset + adjust_pcs_size(debug_info->pcs_size()); - _handler_table_offset = _dependencies_offset + round_to(dependencies->size_in_bytes (), oopSize); - _nul_chk_table_offset = _handler_table_offset + round_to(handler_table->size_in_bytes(), oopSize); - _nmethod_end_offset = _nul_chk_table_offset + round_to(nul_chk_table->size_in_bytes(), oopSize); -@@ -830,7 +842,8 @@ - ScopeDesc* nmethod::scope_desc_at(address pc) { - PcDesc* pd = pc_desc_at(pc); - guarantee(pd != NULL, "scope must be present"); -- return new ScopeDesc(this, pd->scope_decode_offset()); -+ return new ScopeDesc(this, pd->scope_decode_offset(), -+ pd->obj_decode_offset()); - } - - -@@ -1605,9 +1618,8 @@ - } - - --bool nmethod::is_dependent_on(klassOop dependee) { -+bool nmethod::check_all_dependencies() { - bool found_check = false; -- if (dependee == NULL) { - // wholesale check of all dependencies - for (Dependencies::DepStream deps(this); deps.next(); ) { - if (deps.check_dependency() != NULL) { -@@ -1615,23 +1627,21 @@ - NOT_DEBUG(break); - } - } -- } else { -+ return found_check; // tell caller if we found anything -+} -+ -+bool nmethod::check_dependency_on(DepChange& changes) { - // What has happened: - // 1) a new class dependee has been added - // 2) dependee and all its super classes have been marked -+ bool found_check = false; // set true if we are upset - for (Dependencies::DepStream deps(this); deps.next(); ) { - // Evaluate only relevant dependencies. -- klassOop ctxk = deps.context_type(); -- if (ctxk == NULL) continue; // e.g., evol_method -- bool ctxk_is_marked = instanceKlass::cast(ctxk)->is_marked_dependent(); -- assert(ctxk_is_marked == Klass::cast(dependee)->is_subtype_of(ctxk), -- "correct marking of potential context types"); -- if (ctxk_is_marked && deps.check_dependency() != NULL) { -+ if (deps.spot_check_dependency_at(changes) != NULL) { - found_check = true; - NOT_DEBUG(break); - } - } -- } - return found_check; - } - -@@ -1802,7 +1812,8 @@ - } - PcDesc* pd = pc_desc_at(ic->end_of_call()); - assert(pd != NULL, "PcDesc must exist"); -- for (ScopeDesc* sd = new ScopeDesc(this, pd->scope_decode_offset()); -+ for (ScopeDesc* sd = new ScopeDesc(this, pd->scope_decode_offset(), -+ pd->obj_decode_offset()); - !sd->is_top(); sd = sd->sender()) { - sd->verify(); - } -@@ -1867,14 +1878,16 @@ - ttyLocker ttyl; // keep the following output all in one block - - tty->print("Compiled "); --#ifdef TIERED -- if (compiler()->is_c1()) { -+ -+ if (is_compiled_by_c1()) { - tty->print("(c1) "); -- } else { -- assert(compiler()->is_c2(), "Who else?"); -+ } else if (is_compiled_by_c2()) { - tty->print("(c2) "); -+ } else { -+ assert(is_native_method(), "Who else?"); -+ tty->print("(nm) "); - } --#endif // TIERED -+ - print_on(tty, "nmethod"); - tty->cr(); - if (WizardMode) { -@@ -1954,6 +1967,13 @@ - tty->print_cr("Dependencies:"); - for (Dependencies::DepStream deps(this); deps.next(); ) { - deps.print_dependency(); -+ klassOop ctxk = deps.context_type(); -+ if (ctxk != NULL) { -+ Klass* k = Klass::cast(ctxk); -+ if (k->oop_is_instance() && ((instanceKlass*)k)->is_dependent_nmethod(this)) { -+ tty->print(" [nmethod<=klass]%s", k->external_name()); -+ } -+ } - deps.log_dependency(); // put it into the xml log also - } - } -@@ -2040,7 +2060,8 @@ - ScopeDesc* nmethod::scope_desc_in(address begin, address end) { - PcDesc* p = pc_desc_near(begin+1); - if (p != NULL && p->real_pc(this) <= end) { -- return new ScopeDesc(this, p->scope_decode_offset()); -+ return new ScopeDesc(this, p->scope_decode_offset(), -+ p->obj_decode_offset()); - } - return NULL; - } -@@ -2188,6 +2209,7 @@ - nmethod_stats.print_nmethod_stats(); - DebugInformationRecorder::print_statistics(); - nmethod_stats.print_pc_stats(); -+ Dependencies::print_statistics(); - if (xtty != NULL) xtty->tail("statistics"); - } - -diff -ruNb openjdk6/hotspot/src/share/vm/code/nmethod.hpp openjdk/hotspot/src/share/vm/code/nmethod.hpp ---- openjdk6/hotspot/src/share/vm/code/nmethod.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/nmethod.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)nmethod.hpp 1.170 07/05/17 15:50:48 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -523,8 +520,13 @@ - // PrimitiveIC* primitiveIC_at(char* p) const; - oop embeddedOop_at(address p); - -- // tells if this compiled method is dependent on -- bool is_dependent_on(klassOop dependee); -+ // tells if any of this method's dependencies have been invalidated -+ // (this is expensive!) -+ bool check_all_dependencies(); -+ -+ // tells if this compiled method is dependent on the given changes, -+ // and the changes have invalidated it -+ bool check_dependency_on(DepChange& changes); - - // Evolution support. Tells if this compiled method is dependent on any of - // methods m() of class dependee, such that if m() in dependee is replaced, -@@ -574,5 +576,3 @@ - lock_nmethod(_nm); - } - }; -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/code/oopRecorder.cpp openjdk/hotspot/src/share/vm/code/oopRecorder.cpp ---- openjdk6/hotspot/src/share/vm/code/oopRecorder.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/oopRecorder.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)oopRecorder.cpp 1.22 07/05/05 17:05:22 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -157,5 +154,3 @@ - } - return -1; - } -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/code/oopRecorder.hpp openjdk/hotspot/src/share/vm/code/oopRecorder.hpp ---- openjdk6/hotspot/src/share/vm/code/oopRecorder.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/oopRecorder.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)oopRecorder.hpp 1.22 07/05/05 17:05:21 JVM" --#endif - /* - * Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/code/pcDesc.cpp openjdk/hotspot/src/share/vm/code/pcDesc.cpp ---- openjdk6/hotspot/src/share/vm/code/pcDesc.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/pcDesc.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)pcDesc.cpp 1.30 07/05/05 17:05:18 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -28,9 +25,10 @@ - # include "incls/_precompiled.incl" - # include "incls/_pcDesc.cpp.incl" - --PcDesc::PcDesc(int pc_offset, int scope_decode_offset) { -+PcDesc::PcDesc(int pc_offset, int scope_decode_offset, int obj_decode_offset) { - _pc_offset = pc_offset; - _scope_decode_offset = scope_decode_offset; -+ _obj_decode_offset = obj_decode_offset; - } - - address PcDesc::real_pc(const nmethod* code) const { -@@ -61,4 +59,3 @@ - //Unimplemented(); - return true; - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/code/pcDesc.hpp openjdk/hotspot/src/share/vm/code/pcDesc.hpp ---- openjdk6/hotspot/src/share/vm/code/pcDesc.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/pcDesc.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)pcDesc.hpp 1.36 07/05/05 17:05:20 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -35,17 +32,20 @@ - private: - int _pc_offset; // offset from start of nmethod - int _scope_decode_offset; // offset for scope in nmethod -+ int _obj_decode_offset; - - public: - int pc_offset() const { return _pc_offset; } - int scope_decode_offset() const { return _scope_decode_offset; } -+ int obj_decode_offset() const { return _obj_decode_offset; } - - void set_pc_offset(int x) { _pc_offset = x; } - void set_scope_decode_offset(int x) { _scope_decode_offset = x; } -+ void set_obj_decode_offset(int x) { _obj_decode_offset = x; } - - // Constructor (only used for static in nmethod.cpp) - // Also used by ScopeDesc::sender()] -- PcDesc(int pc_offset, int scope_decode_offset); -+ PcDesc(int pc_offset, int scope_decode_offset, int obj_decode_offset); - - enum { - // upper and lower exclusive limits real offsets: -@@ -59,4 +59,3 @@ - void print(nmethod* code); - bool verify(nmethod* code); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/code/relocInfo.cpp openjdk/hotspot/src/share/vm/code/relocInfo.cpp ---- openjdk6/hotspot/src/share/vm/code/relocInfo.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/relocInfo.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)relocInfo.cpp 1.89 07/05/05 17:05:21 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/code/relocInfo.hpp openjdk/hotspot/src/share/vm/code/relocInfo.hpp ---- openjdk6/hotspot/src/share/vm/code/relocInfo.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/relocInfo.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)relocInfo.hpp 1.86 07/05/05 17:05:22 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -1201,10 +1198,12 @@ - - - class poll_Relocation : public Relocation { -+ bool is_data() { return true; } - relocInfo::relocType type() { return relocInfo::poll_type; } - }; - - class poll_return_Relocation : public Relocation { -+ bool is_data() { return true; } - relocInfo::relocType type() { return relocInfo::poll_return_type; } - }; - -@@ -1327,4 +1326,3 @@ - - ~PatchingRelocIterator() { postpass(); } - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/code/scopeDesc.cpp openjdk/hotspot/src/share/vm/code/scopeDesc.cpp ---- openjdk6/hotspot/src/share/vm/code/scopeDesc.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/scopeDesc.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)scopeDesc.cpp 1.57 07/05/05 17:05:22 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -29,24 +26,42 @@ - # include "incls/_scopeDesc.cpp.incl" - - -+ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset) { -+ _code = code; -+ _decode_offset = decode_offset; -+ _objects = decode_object_values(obj_decode_offset); -+ decode_body(); -+} -+ - ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset) { - _code = code; - _decode_offset = decode_offset; -+ _objects = decode_object_values(DebugInformationRecorder::serialized_null); -+ decode_body(); -+} -+ - -- if (decode_offset == DebugInformationRecorder::serialized_null) { -+ScopeDesc::ScopeDesc(const ScopeDesc* parent) { -+ _code = parent->_code; -+ _decode_offset = parent->_sender_decode_offset; -+ _objects = parent->_objects; -+ decode_body(); -+} -+ -+ -+void ScopeDesc::decode_body() { -+ if (decode_offset() == DebugInformationRecorder::serialized_null) { - // This is a sentinel record, which is only relevant to - // approximate queries. Decode a reasonable frame. - _sender_decode_offset = DebugInformationRecorder::serialized_null; -- _method = methodHandle(code->method()); -+ _method = methodHandle(_code->method()); - _bci = InvocationEntryBci; - _locals_decode_offset = DebugInformationRecorder::serialized_null; - _expressions_decode_offset = DebugInformationRecorder::serialized_null; - _monitors_decode_offset = DebugInformationRecorder::serialized_null; -- return; -- } -- -+ } else { - // decode header -- DebugInfoReadStream* stream = stream_at(_decode_offset); -+ DebugInfoReadStream* stream = stream_at(decode_offset()); - - _sender_decode_offset = stream->read_int(); - _method = methodHandle((methodOop) stream->read_oop()); -@@ -55,6 +70,7 @@ - _locals_decode_offset = stream->read_int(); - _expressions_decode_offset = stream->read_int(); - _monitors_decode_offset = stream->read_int(); -+ } - } - - -@@ -69,6 +85,18 @@ - return result; - } - -+GrowableArray* ScopeDesc::decode_object_values(int decode_offset) { -+ if (decode_offset == DebugInformationRecorder::serialized_null) return NULL; -+ GrowableArray* result = new GrowableArray(); -+ DebugInfoReadStream* stream = new DebugInfoReadStream(_code, decode_offset, result); -+ int length = stream->read_int(); -+ for (int index = 0; index < length; index++) { -+ result->push(ScopeValue::read_from(stream)); -+ } -+ assert(result->length() == length, "inconsistent debug information"); -+ return result; -+} -+ - - GrowableArray* ScopeDesc::decode_monitor_values(int decode_offset) { - if (decode_offset == DebugInformationRecorder::serialized_null) return NULL; -@@ -82,7 +110,7 @@ - } - - DebugInfoReadStream* ScopeDesc::stream_at(int decode_offset) const { -- return new DebugInfoReadStream(_code, decode_offset); -+ return new DebugInfoReadStream(_code, decode_offset, _objects); - } - - GrowableArray* ScopeDesc::locals() { -@@ -97,13 +125,17 @@ - return decode_monitor_values(_monitors_decode_offset); - } - -+GrowableArray* ScopeDesc::objects() { -+ return _objects; -+} -+ - bool ScopeDesc::is_top() const { - return _sender_decode_offset == DebugInformationRecorder::serialized_null; - } - - ScopeDesc* ScopeDesc::sender() const { - if (is_top()) return NULL; -- return new ScopeDesc(_code, _sender_decode_offset); -+ return new ScopeDesc(this); - } - - -@@ -174,6 +206,18 @@ - } - } - } -+ -+#ifdef COMPILER2 -+ if (DoEscapeAnalysis && is_top() && _objects != NULL) { -+ tty->print_cr("Objects"); -+ for (int i = 0; i < _objects->length(); i++) { -+ ObjectValue* sv = (ObjectValue*) _objects->at(i); -+ tty->print(" - %d: ", sv->id()); -+ sv->print_fields_on(tty); -+ tty->cr(); -+ } -+ } -+#endif // COMPILER2 - } - - #endif -diff -ruNb openjdk6/hotspot/src/share/vm/code/scopeDesc.hpp openjdk/hotspot/src/share/vm/code/scopeDesc.hpp ---- openjdk6/hotspot/src/share/vm/code/scopeDesc.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/scopeDesc.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)scopeDesc.hpp 1.36 07/05/05 17:05:22 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -55,6 +52,11 @@ - class ScopeDesc : public ResourceObj { - public: - // Constructor -+ ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset); -+ -+ // Calls above, giving default value of "serialized_null" to the -+ // "obj_decode_offset" argument. (We don't use a default argument to -+ // avoid a .hpp-.hpp dependency.) - ScopeDesc(const nmethod* code, int decode_offset); - - // JVM state -@@ -64,6 +66,7 @@ - GrowableArray* locals(); - GrowableArray* expressions(); - GrowableArray* monitors(); -+ GrowableArray* objects(); - - // Stack walking, returns NULL if this is the outer most scope. - ScopeDesc* sender() const; -@@ -77,6 +80,9 @@ - bool is_equal(ScopeDesc* sd) const; - - private: -+ // Alternative constructor -+ ScopeDesc(const ScopeDesc* parent); -+ - // JVM state - methodHandle _method; - int _bci; -@@ -88,6 +94,9 @@ - int _expressions_decode_offset; - int _monitors_decode_offset; - -+ // Object pool -+ GrowableArray* _objects; -+ - // Nmethod information - const nmethod* _code; - -@@ -95,6 +104,7 @@ - void decode_body(); - GrowableArray* decode_scope_values(int decode_offset); - GrowableArray* decode_monitor_values(int decode_offset); -+ GrowableArray* decode_object_values(int decode_offset); - - DebugInfoReadStream* stream_at(int decode_offset) const; - -@@ -111,6 +121,3 @@ - void print_value_on(outputStream* st) const; - #endif - }; -- -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/code/stubs.cpp openjdk/hotspot/src/share/vm/code/stubs.cpp ---- openjdk6/hotspot/src/share/vm/code/stubs.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/stubs.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)stubs.cpp 1.47 07/05/05 17:05:20 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/code/stubs.hpp openjdk/hotspot/src/share/vm/code/stubs.hpp ---- openjdk6/hotspot/src/share/vm/code/stubs.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/stubs.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)stubs.hpp 1.34 07/05/05 17:05:22 JVM" --#endif - /* - * Copyright 1997-2002 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -209,6 +206,3 @@ - void verify(); // verifies the stub queue - void print(); // prints information about the stub queue - }; -- -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/code/vmreg.cpp openjdk/hotspot/src/share/vm/code/vmreg.cpp ---- openjdk6/hotspot/src/share/vm/code/vmreg.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/vmreg.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)vmreg.cpp 1.35 07/05/05 17:05:22 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/code/vmreg.hpp openjdk/hotspot/src/share/vm/code/vmreg.hpp ---- openjdk6/hotspot/src/share/vm/code/vmreg.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/vmreg.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)vmreg.hpp 1.37 07/05/05 17:05:22 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/code/vtableStubs.cpp openjdk/hotspot/src/share/vm/code/vtableStubs.cpp ---- openjdk6/hotspot/src/share/vm/code/vtableStubs.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/vtableStubs.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)vtableStubs.cpp 1.55 07/05/05 17:05:22 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -198,8 +195,3 @@ - } - - #endif // Product -- -- -- -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/code/vtableStubs.hpp openjdk/hotspot/src/share/vm/code/vtableStubs.hpp ---- openjdk6/hotspot/src/share/vm/code/vtableStubs.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/code/vtableStubs.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)vtableStubs.hpp 1.27 07/05/05 17:05:22 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/compiler/abstractCompiler.cpp openjdk/hotspot/src/share/vm/compiler/abstractCompiler.cpp ---- openjdk6/hotspot/src/share/vm/compiler/abstractCompiler.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/compiler/abstractCompiler.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)abstractCompiler.cpp 1.4 07/05/05 17:05:23 JVM" --#endif - // - // Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. - // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/compiler/abstractCompiler.hpp openjdk/hotspot/src/share/vm/compiler/abstractCompiler.hpp ---- openjdk6/hotspot/src/share/vm/compiler/abstractCompiler.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/compiler/abstractCompiler.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)abstractCompiler.hpp 1.26 07/05/05 17:05:24 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/compiler/cha.cpp openjdk/hotspot/src/share/vm/compiler/cha.cpp ---- openjdk6/hotspot/src/share/vm/compiler/cha.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/compiler/cha.cpp 1970-01-01 01:00:00.000000000 +0100 -@@ -1,213 +0,0 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)cha.cpp 1.54 07/05/05 17:05:23 JVM" --#endif --/* -- * Copyright 1997-2005 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, -- * CA 95054 USA or visit www.sun.com if you need additional information or -- * have any questions. -- * -- */ -- --#include "incls/_precompiled.incl" --#include "incls/_cha.cpp.incl" -- --bool CHA::_used = false; --int CHA::_max_result = 5; -- -- --CHAResult* CHA::analyze_call(KlassHandle calling_klass, KlassHandle static_receiver, KlassHandle actual_receiver, -- symbolHandle name, symbolHandle signature) { -- assert(static_receiver->oop_is_instance(), "must be instance klass"); -- -- methodHandle m; -- // Only do exact lookup if receiver klass has been linked. Otherwise, -- // the vtables has not been setup, and the LinkResolver will fail. -- if (instanceKlass::cast(static_receiver())->is_linked() && instanceKlass::cast(actual_receiver())->is_linked()) { -- if (static_receiver->is_interface()) { -- // no point trying to resolve unless actual receiver is a klass -- if (!actual_receiver->is_interface()) { -- m = LinkResolver::resolve_interface_call_or_null(actual_receiver, static_receiver, name, signature, calling_klass); -- } -- } else { -- m = LinkResolver::resolve_virtual_call_or_null(actual_receiver, static_receiver, name, signature, calling_klass); -- } -- -- if (m.is_null()) { -- // didn't find method (e.g., could be abstract method) -- return new CHAResult(actual_receiver, name, signature, NULL, NULL, m, false); -- } -- if( m()->can_be_statically_bound() || -- m()->is_private() || -- actual_receiver->subklass() == NULL ) { -- // always optimize final methods, private methods or methods with no -- // subclasses. -- return new CHAResult(actual_receiver, name, signature, NULL, NULL, m); -- } -- if (!UseCHA) { -- // don't optimize this call -- return new CHAResult(actual_receiver, name, signature, NULL, NULL, m, false); -- } -- } -- -- // If the method is abstract then each non-abstract subclass must implement -- // the method and inlining is not possible. If there is exactly 1 subclass -- // then there can be only 1 implementation and we are OK. -- // (This test weakens CHA slightly, for the sake of the old dependency mechanism.) -- if( !m.is_null() && m()->is_abstract() ) {// Method is abstract? -- Klass *sr = Klass::cast(static_receiver()); -- if( sr == sr->up_cast_abstract() ) -- return new CHAResult(actual_receiver, name, signature, NULL, NULL, m, false); -- // Fall into the next code; it will find the one implementation -- // and that implementation is correct. -- } -- -- _used = true; -- GrowableArray* methods = new GrowableArray(CHA::max_result()); -- GrowableArray* receivers = new GrowableArray(CHA::max_result()); -- -- // Since 'm' is visible from the actual receiver we can call it if the -- // runtime receiver class does not override 'm'. -- if( !m.is_null() && m()->method_holder() != actual_receiver() && -- !m->is_abstract() ) { -- receivers->push(actual_receiver); -- methods->push(m); -- } -- if (static_receiver->is_interface()) { -- instanceKlassHandle sr = static_receiver(); -- process_interface(sr, receivers, methods, name, signature); -- } else { -- process_class(static_receiver, receivers, methods, name, signature); -- } -- -- methodHandle dummy; -- CHAResult* res = new CHAResult(actual_receiver, name, signature, receivers, methods, dummy); -- -- //res->print(); -- return res; --} -- --void CHA::process_class(KlassHandle r, GrowableArray* receivers, GrowableArray* methods, symbolHandle name, symbolHandle signature) { -- // recursively add non-abstract subclasses of r to receivers list -- assert(!r->is_interface(), "should call process_interface instead"); -- for (Klass* s = r->subklass(); s != NULL && !methods->is_full(); s = s->next_sibling()) { -- // preorder traversal, so check subclasses first -- if (s->is_interface()) { -- // can only happen if r == Object -- assert(r->superklass() == NULL, "must be klass Object"); -- } else { -- process_class(s, receivers, methods, name, signature); -- } -- } -- // now check r itself (after subclasses because of preorder) -- if (!methods->is_full()) { -- // don't add abstract classes to receivers list -- // (but still consider their methods -- they may be non-abstract) -- if (!receivers->is_full() && !r->is_abstract()) { -- // don't duplicate the actual receiver -- if (!receivers->contains(r)) receivers->push(r); -- } -- methodOop m = NULL; -- if (r->oop_is_instance()) m = instanceKlass::cast(r())->find_method(name(), signature()); -- if (m != NULL && !m->is_abstract()) { -- if (!methods->contains(m)) methods->push(m); -- } -- } --} -- --void CHA::process_interface(instanceKlassHandle r, GrowableArray* receivers, GrowableArray* methods, -- symbolHandle name, symbolHandle signature) { -- // recursively add non-abstract implementors of interface r to receivers list -- assert(r->is_interface(), "should call process_class instead"); -- -- // We only store the implementors for an interface, if there is exactly one implementor -- klassOop k = NULL; -- if (r->nof_implementors() == 1) k = r->implementor(0); -- if (k == NULL) methods->clear(); // no news is bad news -- if (k != NULL && !methods->is_full()) { -- instanceKlass* kl = instanceKlass::cast(k); -- assert(kl->oop_is_instance(), "primitive klasses don't implement interfaces"); -- assert(!kl->is_interface(), "must be a real klass"); -- process_class(kl, receivers, methods, name, signature); -- } -- -- // there are no links to subinterfaces -- assert(r->subklass() == NULL, "interfaces have no subclasses"); --} -- -- --CHAResult::CHAResult(KlassHandle r, symbolHandle n, symbolHandle s, -- GrowableArray* rs, GrowableArray* ms, -- methodHandle target, bool v) : -- _receiver(r), _name(n), _signature(s), _receivers(rs), _target_methods(ms), _valid(v), _target(target) {} -- --bool CHAResult::is_monomorphic() const { -- // note: check number of target methods, not number of receivers -- // (send can be monomorphic even with many receiver classes, if all inherit same method) -- return _valid && (_target_methods == NULL || _target_methods->length() == 1); --} -- --methodHandle CHAResult::monomorphic_target() const { -- assert(is_monomorphic(), "not monomorphic"); -- if (_target_methods != NULL) { -- assert(_target_methods->length() == 1, "expected single target"); -- return _target_methods->first(); -- } else { -- // final method -- // assert(_target->is_final_method(), "expected final method"); -- return _target; -- } --} -- --KlassHandle CHAResult::monomorphic_receiver() const { -- assert(is_monomorphic(), "not monomorphic"); -- if (_receivers != NULL) { -- // since all lookups will find the same method, it doesn't matter that much -- // which klass we return; for beauty's sake, return the target's method holder -- // (note: don't return _receiver -- its method may be abstract) -- return _target_methods->first()->method_holder(); -- } else { -- // final method -- // assert(_target->is_final_method(), "expected final method"); -- return _receiver; -- } --} -- --void CHAResult::print() { -- tty->print("(CHAResult*)%#x : ", this); -- (instanceKlass::cast(_receiver()))->name()->print_value(); -- tty->print("::"); -- _name()->print_value(); -- tty->print_cr(" %s", _valid ? "(Found)" : "(Not found)"); -- if (_receivers != NULL) -- tty->print("%d receiver klasses ", _receivers->length()); -- if (_target_methods != NULL) -- tty->print("%d target methods %s", _target_methods->length(), -- _target_methods->is_full() ? "(FULL)" : ""); -- if (is_monomorphic()) { -- methodHandle target = monomorphic_target(); -- tty->print("monomorphic target method : "); -- target->print_short_name(tty); -- if (target->is_final()) -- tty->print(" (final)"); -- if (target->is_abstract()) -- tty->print(" (abstract)"); -- } -- tty->cr(); --} -diff -ruNb openjdk6/hotspot/src/share/vm/compiler/cha.hpp openjdk/hotspot/src/share/vm/compiler/cha.hpp ---- openjdk6/hotspot/src/share/vm/compiler/cha.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/compiler/cha.hpp 1970-01-01 01:00:00.000000000 +0100 -@@ -1,88 +0,0 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)cha.hpp 1.21 07/05/05 17:05:23 JVM" --#endif --/* -- * Copyright 1997-1998 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, -- * CA 95054 USA or visit www.sun.com if you need additional information or -- * have any questions. -- * -- */ -- --// Class Hierarchy Analysis --// Computes the set of overriding methods for a particular call, --// using the subclass links in instanceKlass. --// Right now the CHA just traverses these links for every query; --// if this should become too slow we can put in a cache. -- --// result of a CHA query --class CHAResult : public ResourceObj { -- friend class CHA; -- const KlassHandle _receiver; // copies of the lookup (for better debugging) -- const symbolHandle _name; -- const symbolHandle _signature; -- const methodHandle _target; // target method (if final) -- const bool _valid; -- const GrowableArray* const _target_methods; // list of possible targets (NULL for final methods or if !UseCHA) -- const GrowableArray* const _receivers; // list of possible receiver klasses (NULL for final methods or if !UseCHA) -- -- CHAResult(KlassHandle receiver, symbolHandle name, symbolHandle signature, -- GrowableArray* receivers, GrowableArray* methods, -- methodHandle target, bool valid = true); -- public: -- KlassHandle receiver() const { return _receiver; } -- symbolHandle name() const { return _name; } -- symbolHandle signature() const { return _signature; } -- bool is_accurate() const { return !_target_methods->is_full(); } -- bool is_monomorphic() const; -- methodHandle monomorphic_target() const; // returns the single target (if is_monomorphic) -- KlassHandle monomorphic_receiver() const; // receiver klass of monomorphic_target -- const GrowableArray* receivers() const { return _receivers; } -- // Returns the list of all subclasses that are possible receivers (empty array if none, capped at max_result). -- // The static receiver klass *is* included in the result (unless it is abstract). -- // The list is a class hierarchy preorder, i.e., subclasses precede their superclass. -- // All possible receiver classes are included, not just those that (re)define the method. -- // Abstract classes are suppressed. -- const GrowableArray* target_methods() const { return _target_methods; } -- // Returns the list of possible target methods, i.e., all methods potentially invoked -- // by this send (empty array if none, capped at max_result). -- // If the receiver klass (or one of its superclasses) defines the method, this definition -- // is included in the result. Abstract methods are suppressed. -- void print(); --}; -- -- --class CHA : AllStatic { -- static int _max_result; // maximum result size (for efficiency) -- static bool _used; // has CHA been used yet? (will go away when deoptimization implemented) -- -- static void process_class(KlassHandle r, GrowableArray* receivers, GrowableArray* methods, -- symbolHandle name, symbolHandle signature); -- static void process_interface(instanceKlassHandle r, GrowableArray* receivers, GrowableArray* methods, -- symbolHandle name, symbolHandle signature); -- public: -- static bool has_been_used() { return _used; } -- static int max_result() { return _max_result; } -- static void set_max_result(int n) { _max_result = n; } -- -- static CHAResult* analyze_call(KlassHandle calling_klass, KlassHandle static_receiver, -- KlassHandle actual_receiver, symbolHandle name, symbolHandle signature); --}; -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/compiler/compileBroker.cpp openjdk/hotspot/src/share/vm/compiler/compileBroker.cpp ---- openjdk6/hotspot/src/share/vm/compiler/compileBroker.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/compiler/compileBroker.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)compileBroker.cpp 1.147 07/05/17 15:50:51 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/compiler/compileBroker.hpp openjdk/hotspot/src/share/vm/compiler/compileBroker.hpp ---- openjdk6/hotspot/src/share/vm/compiler/compileBroker.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/compiler/compileBroker.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)compileBroker.hpp 1.55 07/05/05 17:05:24 JVM" --#endif - /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/compiler/compileLog.cpp openjdk/hotspot/src/share/vm/compiler/compileLog.cpp ---- openjdk6/hotspot/src/share/vm/compiler/compileLog.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/compiler/compileLog.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)compileLog.cpp 1.20 07/05/05 17:05:23 JVM" --#endif - /* - * Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -295,4 +292,3 @@ - char buf[4 * K]; - finish_log_on_error(file, buf, sizeof(buf)); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/compiler/compileLog.hpp openjdk/hotspot/src/share/vm/compiler/compileLog.hpp ---- openjdk6/hotspot/src/share/vm/compiler/compileLog.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/compiler/compileLog.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)compileLog.hpp 1.12 07/05/05 17:05:24 JVM" --#endif - /* - * Copyright 2002-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/compiler/compilerOracle.cpp openjdk/hotspot/src/share/vm/compiler/compilerOracle.cpp ---- openjdk6/hotspot/src/share/vm/compiler/compilerOracle.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/compiler/compilerOracle.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)compilerOracle.cpp 1.34 07/05/17 15:50:53 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -539,7 +536,7 @@ - } - - static const char* cc_file() { -- if (CompileCommandFile[0] == '\0') -+ if (CompileCommandFile == NULL) - return ".hotspot_compiler"; - return CompileCommandFile; - } -@@ -711,5 +708,3 @@ - line = *line == '\0' ? line : line + 1; - } - } -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/compiler/compilerOracle.hpp openjdk/hotspot/src/share/vm/compiler/compilerOracle.hpp ---- openjdk6/hotspot/src/share/vm/compiler/compilerOracle.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/compiler/compilerOracle.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)compilerOracle.hpp 1.21 07/05/05 17:05:23 JVM" --#endif - /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/compiler/disassemblerEnv.hpp openjdk/hotspot/src/share/vm/compiler/disassemblerEnv.hpp ---- openjdk6/hotspot/src/share/vm/compiler/disassemblerEnv.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/compiler/disassemblerEnv.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)disassemblerEnv.hpp 1.18 07/05/05 17:05:24 JVM" --#endif - /* - * Copyright 1997-2002 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -36,4 +33,3 @@ - virtual char* string_for_offset(intptr_t value) = 0; - virtual char* string_for_constant(unsigned char* pc, intptr_t value, int is_decimal) = 0; - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/compiler/methodLiveness.cpp openjdk/hotspot/src/share/vm/compiler/methodLiveness.cpp ---- openjdk6/hotspot/src/share/vm/compiler/methodLiveness.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/compiler/methodLiveness.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)methodLiveness.cpp 1.41 07/05/05 17:05:24 JVM" --#endif - /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -1064,4 +1061,3 @@ - } - - #endif // PRODUCT -- -diff -ruNb openjdk6/hotspot/src/share/vm/compiler/methodLiveness.hpp openjdk/hotspot/src/share/vm/compiler/methodLiveness.hpp ---- openjdk6/hotspot/src/share/vm/compiler/methodLiveness.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/compiler/methodLiveness.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)methodLiveness.hpp 1.25 07/05/05 17:05:24 JVM" --#endif - /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/compiler/oopMap.cpp openjdk/hotspot/src/share/vm/compiler/oopMap.cpp ---- openjdk6/hotspot/src/share/vm/compiler/oopMap.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/compiler/oopMap.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)oopMap.cpp 1.151 07/05/05 17:05:23 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -194,6 +191,10 @@ - } - } - -+void OopMap::set_stack_obj(VMReg reg) { -+ set_xxx(reg, OopMapValue::stack_obj, VMRegImpl::Bad()); -+} -+ - // OopMapSet - - OopMapSet::OopMapSet() { -@@ -401,7 +402,7 @@ - if ( loc != NULL ) { - if ( omv.type() == OopMapValue::oop_value ) { - #ifdef ASSERT -- if (!Universe::heap()->is_in_or_null(*loc)) { -+ if (COMPILER2_PRESENT(!DoEscapeAnalysis &&) !Universe::heap()->is_in_or_null(*loc)) { - tty->print_cr("# Found non oop pointer. Dumping state at failure"); - // try to dump out some helpful debugging information - trace_codeblob_maps(fr, reg_map); -@@ -420,6 +421,17 @@ - } - } - } -+ -+#ifdef COMPILER2 -+ if (DoEscapeAnalysis) { -+ for (OopMapStream oms(map, OopMapValue::stack_obj); !oms.is_done(); oms.next()) { -+ omv = oms.current(); -+ assert(omv.is_stack_loc(), "should refer to stack location"); -+ oop loc = (oop) fr->oopmapreg_to_location(omv.reg(),reg_map); -+ oop_fn->do_oop(&loc); -+ } -+ } -+#endif // COMPILER2 - } - - -@@ -513,6 +525,9 @@ - tty->print("Derived_oop_" ); - optional->print(); - break; -+ case OopMapValue::stack_obj: -+ tty->print("Stack"); -+ break; - default: - ShouldNotReachHere(); - } -@@ -527,25 +542,25 @@ - } - - --void OopMap::print() const { -+void OopMap::print_on(outputStream* st) const { - OopMapValue omv; - for(OopMapStream oms((OopMap*)this); !oms.is_done(); oms.next()) { - omv = oms.current(); -- omv.print(); -+ omv.print_on(st); - } - } - - --void OopMapSet::print() const { -+void OopMapSet::print_on(outputStream* st) const { - int i, len = om_count(); - -- tty->print_cr("OopMapSet contains %d OopMaps\n",len); -+ st->print_cr("OopMapSet contains %d OopMaps\n",len); - - for( i = 0; i < len; i++) { - OopMap* m = at(i); -- tty->print_cr("OopMap #%d offset:%p",i,m->offset()); -- m->print(); -- tty->print_cr("\n"); -+ st->print_cr("OopMap #%d offset:%p",i,m->offset()); -+ m->print_on(st); -+ st->print_cr("\n"); - } - } - #endif // !PRODUCT -diff -ruNb openjdk6/hotspot/src/share/vm/compiler/oopMap.hpp openjdk/hotspot/src/share/vm/compiler/oopMap.hpp ---- openjdk6/hotspot/src/share/vm/compiler/oopMap.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/compiler/oopMap.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)oopMap.hpp 1.79 07/05/05 17:05:24 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -49,7 +46,7 @@ - - public: - // Constants -- enum { type_bits = 5, -+ enum { type_bits = 6, - register_bits = BitsPerShort - type_bits }; - - enum { type_shift = 0, -@@ -66,7 +63,8 @@ - value_value = 2, - dead_value = 4, - callee_saved_value = 8, -- derived_oop_value= 16 }; -+ derived_oop_value= 16, -+ stack_obj = 32 }; - - // Constructors - OopMapValue () { set_value(0); set_content_reg(VMRegImpl::Bad()); } -@@ -95,12 +93,14 @@ - bool is_dead() { return mask_bits(value(), type_mask_in_place) == dead_value; } - bool is_callee_saved() { return mask_bits(value(), type_mask_in_place) == callee_saved_value; } - bool is_derived_oop() { return mask_bits(value(), type_mask_in_place) == derived_oop_value; } -+ bool is_stack_obj() { return mask_bits(value(), type_mask_in_place) == stack_obj; } - - void set_oop() { set_value((value() & register_mask_in_place) | oop_value); } - void set_value() { set_value((value() & register_mask_in_place) | value_value); } - void set_dead() { set_value((value() & register_mask_in_place) | dead_value); } - void set_callee_saved() { set_value((value() & register_mask_in_place) | callee_saved_value); } - void set_derived_oop() { set_value((value() & register_mask_in_place) | derived_oop_value); } -+ void set_stack_obj() { set_value((value() & register_mask_in_place) | stack_obj); } - - VMReg reg() const { return VMRegImpl::as_VMReg(mask_bits(value(), register_mask_in_place) >> register_shift); } - oop_types type() const { return (oop_types)mask_bits(value(), type_mask_in_place); } -@@ -178,6 +178,7 @@ - void set_dead ( VMReg local); - void set_callee_saved( VMReg local, VMReg caller_machine_register ); - void set_derived_oop ( VMReg local, VMReg derived_from_local_register ); -+ void set_stack_obj( VMReg local); - void set_xxx(VMReg reg, OopMapValue::oop_types x, VMReg optional); - - int heap_size() const; -@@ -191,7 +192,8 @@ - } - - // Printing -- void print() const PRODUCT_RETURN; -+ void print_on(outputStream* st) const PRODUCT_RETURN; -+ void print() const { print_on(tty); } - }; - - -@@ -245,7 +247,8 @@ - OopClosure* value_fn, OopClosure* dead_fn); - - // Printing -- void print() const PRODUCT_RETURN; -+ void print_on(outputStream* st) const PRODUCT_RETURN; -+ void print() const { print_on(tty); } - }; - - -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)binaryTreeDictionary.cpp 1.37 07/05/05 17:05:43 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)binaryTreeDictionary.hpp 1.26 07/05/05 17:05:41 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.cpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)cmsAdaptiveSizePolicy.cpp 1.19 07/05/05 17:05:24 JVM" --#endif - /* - * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)cmsAdaptiveSizePolicy.hpp 1.16 07/05/05 17:05:25 JVM" --#endif - /* - * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)cmsCollectorPolicy.cpp 1.1 07/05/16 10:53:57 JVM" --#endif - /* - * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsCollectorPolicy.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)cmsCollectorPolicy.hpp 1.1 07/05/16 10:53:57 JVM" --#endif - /* - * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsGCAdaptivePolicyCounters.cpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsGCAdaptivePolicyCounters.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsGCAdaptivePolicyCounters.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsGCAdaptivePolicyCounters.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)cmsGCAdaptivePolicyCounters.cpp 1.16 07/05/05 17:05:25 JVM" --#endif - /* - * Copyright 2004-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsGCAdaptivePolicyCounters.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsGCAdaptivePolicyCounters.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsGCAdaptivePolicyCounters.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsGCAdaptivePolicyCounters.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)cmsGCAdaptivePolicyCounters.hpp 1.16 07/05/05 17:05:25 JVM" --#endif - /* - * Copyright 2004-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsLockVerifier.cpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsLockVerifier.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsLockVerifier.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsLockVerifier.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)cmsLockVerifier.cpp 1.14 07/05/05 17:05:44 JVM" --#endif - /* - * Copyright 2002-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -96,4 +93,3 @@ - } - } - #endif -- -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsLockVerifier.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsLockVerifier.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsLockVerifier.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsLockVerifier.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)cmsLockVerifier.hpp 1.9 07/05/05 17:05:44 JVM" --#endif - /* - * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)cmsOopClosures.hpp 1.2 07/05/16 16:53:01 JVM" --#endif - /* - * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -32,8 +29,10 @@ - class CMSBitMap; - class CMSMarkStack; - class CMSCollector; --class OopTaskQueue; --class OopTaskQueueSet; -+template class GenericTaskQueue; -+typedef GenericTaskQueue OopTaskQueue; -+template class GenericTaskQueueSet; -+typedef GenericTaskQueueSet OopTaskQueueSet; - class MarkFromRootsClosure; - class Par_MarkFromRootsClosure; - -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.inline.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.inline.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.inline.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsOopClosures.inline.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)cmsOopClosures.inline.hpp 1.1 07/05/16 10:52:51 JVM" --#endif - /* - * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.cpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.cpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)cmsPermGen.cpp 1.2 07/05/16 16:53:01 JVM" --#endif - /* - * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)cmsPermGen.hpp 1.1 07/05/02 16:12:51 JVM" --#endif - /* - * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)compactibleFreeListSpace.cpp 1.143 07/07/17 11:43:33 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -2846,4 +2843,3 @@ - pst->set_par_threads(n_threads); - pst->set_n_tasks((int)n_tasks); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)compactibleFreeListSpace.hpp 1.91 07/05/05 17:05:45 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentGCThread.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentGCThread.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentGCThread.hpp 2008-07-10 22:04:30.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentGCThread.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -158,6 +158,8 @@ - - SurrogateLockerThread(); - -+ bool is_hidden_from_external_view() const { return true; } -+ - void loop(); // main method - - void manipulatePLL(SLT_msg_type msg); -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)concurrentMarkSweepGeneration.cpp 1.290 07/07/17 11:49:58 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -4081,7 +4078,7 @@ - while (_restart_addr != NULL) { - // XXX For now we do not make use of ABORTED state and have not - // yet implemented the right abort semantics (even in the original -- // single-threaded CMS case. That needs some more investigation -+ // single-threaded CMS case). That needs some more investigation - // and is deferred for now; see CR# TBF. 07252005YSR. XXX - assert(!CMSAbortSemantics || tsk.aborted(), "Inconsistency"); - // If _restart_addr is non-NULL, a marking stack overflow -@@ -4238,7 +4235,9 @@ - // take a short break. - if (workdone < CMSAbortablePrecleanMinWorkPerIteration) { - // Sleep for some time, waiting for work to accumulate -+ stopTimer(); - cmsThread()->wait_on_cms_lock(CMSAbortablePrecleanWaitMillis); -+ startTimer(); - waited++; - } - } -@@ -4323,8 +4322,10 @@ - // the computed reachability of the referents, the - // only properties manipulated by the precleaning - // of these reference lists. -+ stopTimer(); - CMSTokenSyncWithLocks x(true /* is cms thread */, - bitMapLock()); -+ startTimer(); - sample_eden(); - // The following will yield to allow foreground - // collection to proceed promptly. XXX YSR: -@@ -4346,8 +4347,10 @@ - &_markBitMap, &_modUnionTable, - &_markStack, &_revisitStack, - true /* precleaning phase */); -+ stopTimer(); - CMSTokenSyncWithLocks ts(true /* is cms thread */, - bitMapLock()); -+ startTimer(); - unsigned int before_count = - GenCollectedHeap::heap()->total_collections(); - SurvivorSpacePrecleanClosure -@@ -4481,13 +4484,10 @@ - - MemRegion dirtyRegion; - { -+ stopTimer(); - CMSTokenSync ts(true); -- sample_eden(); -- -- if (PrintGCDetails) { - startTimer(); -- } -- -+ sample_eden(); - // Get dirty region starting at nextOffset (inclusive), - // simultaneously clearing it. - dirtyRegion = -@@ -4507,20 +4507,16 @@ - // We'll scan the cards in the dirty region (with periodic - // yields for foreground GC as needed). - if (!dirtyRegion.is_empty()) { -- if (PrintGCDetails) { -- stopTimer(); -- } - assert(numDirtyCards > 0, "consistency check"); - HeapWord* stop_point = NULL; - { -+ stopTimer(); - CMSTokenSyncWithLocks ts(true, gen->freelistLock(), - bitMapLock()); -+ startTimer(); - verify_work_stacks_empty(); - verify_overflow_empty(); - sample_eden(); -- if (PrintGCDetails) { -- startTimer(); -- } - stop_point = - gen->cmsSpace()->object_iterate_careful_m(dirtyRegion, cl); - } -@@ -4535,7 +4531,9 @@ - (_collectorState == AbortablePreclean && should_abort_preclean()), - "Unparsable objects should only be in perm gen."); - -+ stopTimer(); - CMSTokenSyncWithLocks ts(true, bitMapLock()); -+ startTimer(); - _modUnionTable.mark_range(MemRegion(stop_point, dirtyRegion.end())); - if (should_abort_preclean()) { - break; // out of preclean loop -@@ -4545,18 +4543,12 @@ - lastAddr = next_card_start_after_block(stop_point); - } - } -- if (PrintGCDetails) { -- stopTimer(); -- } - } else { - assert(lastAddr == endAddr, "consistency check"); - assert(numDirtyCards == 0, "consistency check"); - break; - } - } -- if (PrintGCDetails) { -- stopTimer(); -- } - verify_work_stacks_empty(); - verify_overflow_empty(); - return cumNumDirtyCards; -@@ -4592,13 +4584,10 @@ - // See comments in "Precleaning notes" above on why we - // do this locking. XXX Could the locking overheads be - // too high when dirty cards are sparse? [I don't think so.] -+ stopTimer(); - CMSTokenSync x(true); // is cms thread -- sample_eden(); -- -- if (PrintGCDetails) { - startTimer(); -- } -- -+ sample_eden(); - // Get and clear dirty region from card table - dirtyRegion = _ct->ct_bs()->dirty_card_range_after_preclean( - MemRegion(nextAddr, endAddr)); -@@ -4610,16 +4599,12 @@ - dirtyRegion.word_size()/CardTableModRefBS::card_size_in_words; - - if (!dirtyRegion.is_empty()) { -- if (PrintGCDetails) { - stopTimer(); -- } - CMSTokenSyncWithLocks ts(true, gen->freelistLock(), bitMapLock()); -+ startTimer(); - sample_eden(); - verify_work_stacks_empty(); - verify_overflow_empty(); -- if (PrintGCDetails) { -- startTimer(); -- } - HeapWord* stop_point = - gen->cmsSpace()->object_iterate_careful_m(dirtyRegion, cl); - if (stop_point != NULL) { -@@ -4638,16 +4623,10 @@ - lastAddr = next_card_start_after_block(stop_point); - } - } -- if (PrintGCDetails) { -- stopTimer(); -- } - } else { - break; - } - } -- if (PrintGCDetails) { -- stopTimer(); -- } - verify_work_stacks_empty(); - verify_overflow_empty(); - return cumNumDirtyCards; -@@ -8362,6 +8341,7 @@ - for (oop next; i > 0 && cur != NULL; cur = next, i--) { - next = oop(cur->mark()); - cur->set_mark(proto); // until proven otherwise -+ assert(cur->is_oop(), "Should be an oop"); - bool res = stack->push(cur); - assert(res, "Bit off more than can chew?"); - NOT_PRODUCT(n++;) -@@ -8416,6 +8396,7 @@ - for (cur = prefix; cur != NULL; cur = next) { - next = oop(cur->mark()); - cur->set_mark(proto); // until proven otherwise -+ assert(cur->is_oop(), "Should be an oop"); - bool res = work_q->push(cur); - assert(res, "Bit off more than we can chew?"); - NOT_PRODUCT(n++;) -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)concurrentMarkSweepGeneration.hpp 1.161 07/07/17 11:44:43 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -918,10 +915,10 @@ - CollectorCounters* counters() { return _gc_counters; } - - // timer stuff -- void startTimer() { _timer.start(); } -- void stopTimer() { _timer.stop(); } -- void resetTimer() { _timer.reset(); } -- double timerValue() { return _timer.seconds(); } -+ void startTimer() { assert(!_timer.is_active(), "Error"); _timer.start(); } -+ void stopTimer() { assert( _timer.is_active(), "Error"); _timer.stop(); } -+ void resetTimer() { assert(!_timer.is_active(), "Error"); _timer.reset(); } -+ double timerValue() { assert(!_timer.is_active(), "Error"); return _timer.seconds(); } - - int yields() { return _numYields; } - void resetYields() { _numYields = 0; } -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.inline.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)concurrentMarkSweepGeneration.inline.hpp 1.47 07/05/17 15:52:12 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)concurrentMarkSweepThread.cpp 1.48 07/05/05 17:06:45 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepThread.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)concurrentMarkSweepThread.hpp 1.38 07/05/05 17:06:46 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.cpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)freeBlockDictionary.cpp 1.12 07/05/05 17:05:47 JVM" --#endif - /* - * Copyright 2002-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)freeBlockDictionary.hpp 1.32 07/05/05 17:05:47 JVM" --#endif - /* - * Copyright 2001-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.cpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)freeChunk.cpp 1.16 07/05/05 17:05:47 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.cpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)freeList.cpp 1.31 07/05/05 17:05:48 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)freeList.hpp 1.31 07/05/05 17:05:48 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)vmCMSOperations.cpp 1.16 07/05/29 09:44:13 JVM" --#endif - /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -251,4 +248,3 @@ - // Enable iCMS back. - CMSCollector::enable_icms(); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)vmCMSOperations.hpp 1.13 07/05/29 09:44:13 JVM" --#endif - /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)vmStructs_cms.hpp 1.2 07/05/01 19:01:30 JVM" --#endif - /* - * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp openjdk/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)asParNewGeneration.cpp 1.11 07/05/05 17:05:25 JVM" --#endif - /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.hpp openjdk/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)asParNewGeneration.hpp 1.8 07/05/05 17:05:25 JVM" --#endif - /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp openjdk/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)parCardTableModRefBS.cpp 1.1 07/05/16 19:06:21 JVM" --#endif - /* - * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.cpp openjdk/hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)parGCAllocBuffer.cpp 1.28 07/05/29 09:44:12 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.hpp openjdk/hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)parGCAllocBuffer.hpp 1.30 07/05/29 09:44:13 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp openjdk/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)parNewGeneration.cpp 1.101 07/05/22 17:23:45 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -1193,7 +1190,7 @@ - _reserved, // span - refs_discovery_is_atomic(), // atomic_discovery - refs_discovery_is_mt(), // mt_discovery -- &_is_alive_closure, -+ NULL, // is_alive_non_header - ParallelGCThreads, - ParallelRefProcEnabled); - } -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp openjdk/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)parNewGeneration.hpp 1.48 07/05/17 15:52:44 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.hpp openjdk/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)parOopClosures.hpp 1.1 07/05/16 10:51:44 JVM" --#endif - /* - * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -29,7 +26,8 @@ - - class ParScanThreadState; - class ParNewGeneration; --typedef class OopTaskQueueSet ObjToScanQueueSet; -+template class GenericTaskQueueSet; -+typedef GenericTaskQueueSet ObjToScanQueueSet; - class ParallelTaskTerminator; - - class ParScanClosure: public OopsInGenClosure { -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp openjdk/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.inline.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)parOopClosures.inline.hpp 1.1 07/05/16 10:51:44 JVM" --#endif - /* - * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -100,4 +97,3 @@ - } - } - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningGenerations.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningGenerations.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningGenerations.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningGenerations.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)adjoiningGenerations.cpp 1.16 07/05/05 17:05:26 JVM" --#endif - /* - * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -279,4 +276,3 @@ - } - } - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningGenerations.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningGenerations.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningGenerations.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningGenerations.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)adjoiningGenerations.hpp 1.14 07/05/05 17:05:25 JVM" --#endif - /* - * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningVirtualSpaces.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningVirtualSpaces.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningVirtualSpaces.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningVirtualSpaces.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)adjoiningVirtualSpaces.cpp 1.14 07/05/05 17:05:26 JVM" --#endif - /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningVirtualSpaces.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningVirtualSpaces.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningVirtualSpaces.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningVirtualSpaces.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)adjoiningVirtualSpaces.hpp 1.11 07/05/05 17:05:25 JVM" --#endif - /* - * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -109,4 +106,3 @@ - size_t init_low_byte_size, - size_t init_high_byte_size); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSOldGen.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSOldGen.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSOldGen.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSOldGen.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)asPSOldGen.cpp 1.18 07/05/05 17:05:26 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -78,7 +75,10 @@ - assert(virtual_space()->is_aligned(gen_size_limit()), "not aligned"); - assert(gen_size_limit() >= virtual_space()->committed_size(), "bad gen size"); - -- return gen_size_limit() - virtual_space()->committed_size(); -+ ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); -+ size_t result = gen_size_limit() - virtual_space()->committed_size(); -+ size_t result_aligned = align_size_down(result, heap->old_gen_alignment()); -+ return result_aligned; - } - - size_t ASPSOldGen::available_for_contraction() { -@@ -87,12 +87,12 @@ - return uncommitted_bytes; - } - -- const size_t alignment = virtual_space()->alignment(); - ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); -+ const size_t gen_alignment = heap->old_gen_alignment(); - PSAdaptiveSizePolicy* policy = heap->size_policy(); - const size_t working_size = - used_in_bytes() + (size_t) policy->avg_promoted()->padded_average(); -- const size_t working_aligned = align_size_up(working_size, alignment); -+ const size_t working_aligned = align_size_up(working_size, gen_alignment); - const size_t working_or_min = MAX2(working_aligned, min_gen_size()); - if (working_or_min > reserved().byte_size()) { - // If the used or minimum gen size (aligned up) is greater -@@ -109,9 +109,11 @@ - // only reduce the footprint. - - size_t result = policy->promo_increment_aligned_down(max_contraction); -+ // Also adjust for inter-generational alignment -+ size_t result_aligned = align_size_down(result, gen_alignment); - if (PrintAdaptiveSizePolicy && Verbose) { - gclog_or_tty->print_cr("\nASPSOldGen::available_for_contraction:" -- " %d K / 0x%x", result/K, result); -+ " %d K / 0x%x", result_aligned/K, result_aligned); - gclog_or_tty->print_cr(" reserved().byte_size() %d K / 0x%x ", - reserved().byte_size()/K, reserved().byte_size()); - size_t working_promoted = (size_t) policy->avg_promoted()->padded_average(); -@@ -126,8 +128,8 @@ - gclog_or_tty->print_cr(" without alignment %d K / 0x%x", - policy->promo_increment(max_contraction)/K, - policy->promo_increment(max_contraction)); -- gclog_or_tty->print_cr(" alignment 0x%x", alignment); -+ gclog_or_tty->print_cr(" alignment 0x%x", gen_alignment); - } -- assert(result <= max_contraction, "arithmetic is wrong"); -- return result; -+ assert(result_aligned <= max_contraction, "arithmetic is wrong"); -+ return result_aligned; - } -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSOldGen.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSOldGen.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSOldGen.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSOldGen.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)asPSOldGen.hpp 1.14 07/05/05 17:05:26 JVM" --#endif - /* - * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)asPSYoungGen.cpp 1.22 07/05/05 17:05:27 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -69,7 +66,10 @@ - size_t current_committed_size = virtual_space()->committed_size(); - assert((gen_size_limit() >= current_committed_size), - "generation size limit is wrong"); -- return gen_size_limit() - current_committed_size; -+ ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); -+ size_t result = gen_size_limit() - current_committed_size; -+ size_t result_aligned = align_size_down(result, heap->young_gen_alignment()); -+ return result_aligned; - } - - // Return the number of bytes the young gen is willing give up. -@@ -87,7 +87,7 @@ - // Respect the minimum size for eden and for the young gen as a whole. - ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); - const size_t eden_alignment = heap->intra_generation_alignment(); -- const size_t gen_alignment = heap->generation_alignment(); -+ const size_t gen_alignment = heap->young_gen_alignment(); - - assert(eden_space()->capacity_in_bytes() >= eden_alignment, - "Alignment is wrong"); -@@ -104,14 +104,15 @@ - // for reasons the "increment" fraction is used. - PSAdaptiveSizePolicy* policy = heap->size_policy(); - size_t result = policy->eden_increment_aligned_down(max_contraction); -+ size_t result_aligned = align_size_down(result, gen_alignment); - if (PrintAdaptiveSizePolicy && Verbose) { - gclog_or_tty->print_cr("ASPSYoungGen::available_for_contraction: %d K", -- result/K); -+ result_aligned/K); - gclog_or_tty->print_cr(" max_contraction %d K", max_contraction/K); - gclog_or_tty->print_cr(" eden_avail %d K", eden_avail/K); - gclog_or_tty->print_cr(" gen_avail %d K", gen_avail/K); - } -- return result; -+ return result_aligned; - - } - -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)asPSYoungGen.hpp 1.16 07/05/05 17:05:26 JVM" --#endif - /* - * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)cardTableExtension.cpp 1.34 07/05/17 15:52:46 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -191,15 +188,21 @@ - *first_nonclean_card++ = clean_card; - } - // scan oops in objects -+ // hoisted the if (depth_first) check out of the loop -+ if (depth_first){ - do { -- if (depth_first) { - oop(bottom_obj)->push_contents(pm); -+ bottom_obj += oop(bottom_obj)->size(); -+ assert(bottom_obj <= sp_top, "just checking"); -+ } while (bottom_obj < top); -+ pm->drain_stacks_cond_depth(); - } else { -+ do { - oop(bottom_obj)->copy_contents(pm); -- } - bottom_obj += oop(bottom_obj)->size(); - assert(bottom_obj <= sp_top, "just checking"); - } while (bottom_obj < top); -+ } - // remember top oop* scanned - prev_top = top; - } -@@ -347,29 +350,44 @@ - const int interval = PrefetchScanIntervalInBytes; - // scan all objects in the range - if (interval != 0) { -+ // hoisted the if (depth_first) check out of the loop -+ if (depth_first) { - while (p < to) { - Prefetch::write(p, interval); - oop m = oop(p); - assert(m->is_oop_or_null(), "check for header"); -- if (depth_first) { - m->push_contents(pm); -+ p += m->size(); -+ } -+ pm->drain_stacks_cond_depth(); - } else { -+ while (p < to) { -+ Prefetch::write(p, interval); -+ oop m = oop(p); -+ assert(m->is_oop_or_null(), "check for header"); - m->copy_contents(pm); -- } - p += m->size(); - } -+ } - } else { -+ // hoisted the if (depth_first) check out of the loop -+ if (depth_first) { - while (p < to) { - oop m = oop(p); - assert(m->is_oop_or_null(), "check for header"); -- if (depth_first) { - m->push_contents(pm); -+ p += m->size(); -+ } -+ pm->drain_stacks_cond_depth(); - } else { -+ while (p < to) { -+ oop m = oop(p); -+ assert(m->is_oop_or_null(), "check for header"); - m->copy_contents(pm); -- } - p += m->size(); - } - } -+ } - last_scanned = p; - } - // "current_card" is still the "following_clean_card" or -@@ -759,4 +777,3 @@ - } - return min_start; - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)cardTableExtension.hpp 1.20 07/05/05 17:05:26 JVM" --#endif - /* - * Copyright 2001-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -109,4 +106,3 @@ - - #endif // ASSERT - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)gcTaskManager.cpp 1.34 07/05/05 17:05:27 JVM" --#endif - /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -333,7 +330,7 @@ - // - - SynchronizedGCTaskQueue::SynchronizedGCTaskQueue(GCTaskQueue* queue_arg, -- Mutex* lock_arg) : -+ Monitor * lock_arg) : - _unsynchronized_queue(queue_arg), - _lock(lock_arg) { - assert(unsynchronized_queue() != NULL, "null queue"); -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)gcTaskManager.hpp 1.28 07/05/05 17:05:26 JVM" --#endif - /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -209,10 +206,10 @@ - private: - // Instance state. - GCTaskQueue* _unsynchronized_queue; // Has-a unsynchronized queue. -- Mutex* _lock; // Lock to control access. -+ Monitor * _lock; // Lock to control access. - public: - // Factory create and destroy methods. -- static SynchronizedGCTaskQueue* create(GCTaskQueue* queue, Mutex* lock) { -+ static SynchronizedGCTaskQueue* create(GCTaskQueue* queue, Monitor * lock) { - return new SynchronizedGCTaskQueue(queue, lock); - } - static void destroy(SynchronizedGCTaskQueue* that) { -@@ -224,7 +221,7 @@ - GCTaskQueue* unsynchronized_queue() const { - return _unsynchronized_queue; - } -- Mutex* lock() const { -+ Monitor * lock() const { - return _lock; - } - // GCTaskQueue wrapper methods. -@@ -260,7 +257,7 @@ - } - protected: - // Constructor. Clients use factory, but there might be subclasses. -- SynchronizedGCTaskQueue(GCTaskQueue* queue, Mutex* lock); -+ SynchronizedGCTaskQueue(GCTaskQueue* queue, Monitor * lock); - // Destructor. Not virtual because no virtuals. - ~SynchronizedGCTaskQueue(); - }; -@@ -325,7 +322,7 @@ - Monitor* monitor() const { - return _monitor; - } -- Mutex* lock() const { -+ Monitor * lock() const { - return _monitor; - } - // Methods. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,7 +1,4 @@ - --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)gcTaskThread.cpp 1.25 07/05/05 17:05:26 JVM" --#endif - /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -151,4 +148,3 @@ - } - } - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)gcTaskThread.hpp 1.18 07/05/05 17:05:27 JVM" --#endif - /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)generationSizer.hpp 1.17 07/05/05 17:05:27 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -70,5 +67,3 @@ - size_t perm_gen_size() { return PermSize; } - size_t max_perm_gen_size() { return MaxPermSize; } - }; -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/objectStartArray.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/objectStartArray.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/objectStartArray.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/objectStartArray.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)objectStartArray.cpp 1.20 07/05/05 17:05:28 JVM" --#endif - /* - * Copyright 2001-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/objectStartArray.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/objectStartArray.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/objectStartArray.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/objectStartArray.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)objectStartArray.hpp 1.21 07/05/05 17:05:28 JVM" --#endif - /* - * Copyright 2001-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -163,4 +160,3 @@ - // "start", the method will return true. - bool object_starts_in_range(HeapWord* start_addr, HeapWord* end_addr) const; - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)parMarkBitMap.cpp 1.30 07/05/05 17:05:27 JVM" --#endif - /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -31,17 +28,23 @@ - bool - ParMarkBitMap::initialize(MemRegion covered_region) - { -- const size_t alloc_granularity = os::vm_allocation_granularity(); - const idx_t bits = bits_required(covered_region); -- const idx_t words = bits / BitsPerWord; -- const idx_t bytes = align_size_up(words * sizeof(idx_t), alloc_granularity); -- - // The bits will be divided evenly between two bitmaps; each of them should be - // an integral number of words. - assert(bits % (BitsPerWord * 2) == 0, "region size unaligned"); - -- ReservedSpace rs(bytes); -- _virtual_space = new PSVirtualSpace(rs, os::vm_page_size()); -+ const size_t words = bits / BitsPerWord; -+ const size_t raw_bytes = words * sizeof(idx_t); -+ const size_t page_sz = os::page_size_for_region(raw_bytes, raw_bytes, 10); -+ const size_t granularity = os::vm_allocation_granularity(); -+ const size_t bytes = align_size_up(raw_bytes, MAX2(page_sz, granularity)); -+ -+ const size_t rs_align = page_sz == (size_t) os::vm_page_size() ? 0 : -+ MAX2(page_sz, granularity); -+ ReservedSpace rs(bytes, rs_align, false); -+ os::trace_page_sizes("par bitmap", raw_bytes, raw_bytes, page_sz, -+ rs.base(), rs.size()); -+ _virtual_space = new PSVirtualSpace(rs, page_sz); - if (_virtual_space != NULL && _virtual_space->expand_by(bytes)) { - _region_start = covered_region.start(); - _region_size = covered_region.word_size(); -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)parMarkBitMap.hpp 1.16 07/05/05 17:05:27 JVM" --#endif - /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.inline.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.inline.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.inline.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.inline.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)parMarkBitMap.inline.hpp 1.6 07/05/05 17:05:27 JVM" --#endif - /* - * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)parallelScavengeHeap.cpp 1.94 07/05/17 15:52:49 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -36,59 +33,100 @@ - ParallelScavengeHeap* ParallelScavengeHeap::_psh = NULL; - GCTaskManager* ParallelScavengeHeap::_gc_task_manager = NULL; - -+static void trace_gen_sizes(const char* const str, -+ size_t pg_min, size_t pg_max, -+ size_t og_min, size_t og_max, -+ size_t yg_min, size_t yg_max) -+{ -+ if (TracePageSizes) { -+ tty->print_cr("%s: " SIZE_FORMAT "," SIZE_FORMAT " " -+ SIZE_FORMAT "," SIZE_FORMAT " " -+ SIZE_FORMAT "," SIZE_FORMAT " " -+ SIZE_FORMAT, -+ str, pg_min / K, pg_max / K, -+ og_min / K, og_max / K, -+ yg_min / K, yg_max / K, -+ (pg_max + og_max + yg_max) / K); -+ } -+} -+ - jint ParallelScavengeHeap::initialize() { - // Cannot be initialized until after the flags are parsed - GenerationSizer flag_parser; - -- size_t max_young_size = flag_parser.max_young_gen_size(); -- size_t max_old_size = flag_parser.max_old_gen_size(); -- if (UseLargePages && -- (max_young_size + max_old_size) >= LargePageHeapSizeThreshold) { -- adjust_generation_alignment_for_page_size(os::large_page_size()); -- } -- const size_t alignment = generation_alignment(); -- -- // Check alignments --// NEEDS_CLEANUP The default TwoGenerationCollectorPolicy uses --// NewRatio; it should check UseAdaptiveSizePolicy. Changes from --// generationSizer could move to the common code. -- size_t min_young_size = -- align_size_up(flag_parser.min_young_gen_size(), alignment); -- size_t young_size = align_size_up(flag_parser.young_gen_size(), alignment); -- max_young_size = align_size_up(max_young_size, alignment); -- -- size_t min_old_size = -- align_size_up(flag_parser.min_old_gen_size(), alignment); -- size_t old_size = align_size_up(flag_parser.old_gen_size(), alignment); -- old_size = MAX2(old_size, min_old_size); -- max_old_size = align_size_up(max_old_size, alignment); -- -- size_t perm_size = align_size_up(flag_parser.perm_gen_size(), alignment); -- size_t max_perm_size = align_size_up(flag_parser.max_perm_gen_size(), -- alignment); -- -- // Calculate the total size. -- size_t total_reserved = max_young_size + max_old_size + max_perm_size; -- -- if (UseLargePages) { -- total_reserved = round_to(total_reserved, os::large_page_size()); -- } -+ size_t yg_min_size = flag_parser.min_young_gen_size(); -+ size_t yg_max_size = flag_parser.max_young_gen_size(); -+ size_t og_min_size = flag_parser.min_old_gen_size(); -+ size_t og_max_size = flag_parser.max_old_gen_size(); -+ // Why isn't there a min_perm_gen_size()? -+ size_t pg_min_size = flag_parser.perm_gen_size(); -+ size_t pg_max_size = flag_parser.max_perm_gen_size(); -+ -+ trace_gen_sizes("ps heap raw", -+ pg_min_size, pg_max_size, -+ og_min_size, og_max_size, -+ yg_min_size, yg_max_size); -+ -+ // The ReservedSpace ctor used below requires that the page size for the perm -+ // gen is <= the page size for the rest of the heap (young + old gens). -+ const size_t og_page_sz = os::page_size_for_region(yg_min_size + og_min_size, -+ yg_max_size + og_max_size, -+ 8); -+ const size_t pg_page_sz = MIN2(os::page_size_for_region(pg_min_size, -+ pg_max_size, 16), -+ og_page_sz); -+ -+ const size_t pg_align = set_alignment(_perm_gen_alignment, pg_page_sz); -+ const size_t og_align = set_alignment(_old_gen_alignment, og_page_sz); -+ const size_t yg_align = set_alignment(_young_gen_alignment, og_page_sz); - -- ReservedSpace heap_rs(total_reserved, alignment, UseLargePages); -+ // Update sizes to reflect the selected page size(s). -+ // -+ // NEEDS_CLEANUP. The default TwoGenerationCollectorPolicy uses NewRatio; it -+ // should check UseAdaptiveSizePolicy. Changes from generationSizer could -+ // move to the common code. -+ yg_min_size = align_size_up(yg_min_size, yg_align); -+ yg_max_size = align_size_up(yg_max_size, yg_align); -+ size_t yg_cur_size = align_size_up(flag_parser.young_gen_size(), yg_align); -+ yg_cur_size = MAX2(yg_cur_size, yg_min_size); -+ -+ og_min_size = align_size_up(og_min_size, og_align); -+ og_max_size = align_size_up(og_max_size, og_align); -+ size_t og_cur_size = align_size_up(flag_parser.old_gen_size(), og_align); -+ og_cur_size = MAX2(og_cur_size, og_min_size); -+ -+ pg_min_size = align_size_up(pg_min_size, pg_align); -+ pg_max_size = align_size_up(pg_max_size, pg_align); -+ size_t pg_cur_size = pg_min_size; -+ -+ trace_gen_sizes("ps heap rnd", -+ pg_min_size, pg_max_size, -+ og_min_size, og_max_size, -+ yg_min_size, yg_max_size); -+ -+ // The main part of the heap (old gen + young gen) can often use a larger page -+ // size than is needed or wanted for the perm gen. Use the "compound -+ // alignment" ReservedSpace ctor to avoid having to use the same page size for -+ // all gens. -+ ReservedSpace heap_rs(pg_max_size, pg_align, og_max_size + yg_max_size, -+ og_align); -+ os::trace_page_sizes("ps perm", pg_min_size, pg_max_size, pg_page_sz, -+ heap_rs.base(), pg_max_size); -+ os::trace_page_sizes("ps main", og_min_size + yg_min_size, -+ og_max_size + yg_max_size, og_page_sz, -+ heap_rs.base() + pg_max_size, -+ heap_rs.size() - pg_max_size); - if (!heap_rs.is_reserved()) { - vm_shutdown_during_initialization( - "Could not reserve enough space for object heap"); - return JNI_ENOMEM; - } - -- _reserved_byte_size = heap_rs.size(); - _reserved = MemRegion((HeapWord*)heap_rs.base(), - (HeapWord*)(heap_rs.base() + heap_rs.size())); - -- HeapWord* boundary = (HeapWord*)(heap_rs.base() + max_young_size); -- CardTableExtension* card_table_barrier_set = new CardTableExtension(_reserved, 3); -- _barrier_set = card_table_barrier_set; -- -+ CardTableExtension* const barrier_set = new CardTableExtension(_reserved, 3); -+ _barrier_set = barrier_set; - oopDesc::set_bs(_barrier_set); - if (_barrier_set == NULL) { - vm_shutdown_during_initialization( -@@ -97,17 +135,15 @@ - } - - // Initial young gen size is 4 Mb -- size_t init_young_size = align_size_up(4 * M, alignment); -- init_young_size = MAX2(MIN2(init_young_size, max_young_size), young_size); -- -- // Divide up the reserved space: perm, old, young -- ReservedSpace perm_rs = heap_rs.first_part(max_perm_size); -- ReservedSpace old_young_rs -- = heap_rs.last_part(max_perm_size); -- ReservedSpace old_rs = old_young_rs.first_part(max_old_size); -- heap_rs = old_young_rs.last_part(max_old_size); -- ReservedSpace young_rs = heap_rs.first_part(max_young_size); -- assert(young_rs.size() == heap_rs.size(), "Didn't reserve all of the heap"); -+ // -+ // XXX - what about flag_parser.young_gen_size()? -+ const size_t init_young_size = align_size_up(4 * M, yg_align); -+ yg_cur_size = MAX2(MIN2(init_young_size, yg_max_size), yg_cur_size); -+ -+ // Split the reserved space into perm gen and the main heap (everything else). -+ // The main heap uses a different alignment. -+ ReservedSpace perm_rs = heap_rs.first_part(pg_max_size); -+ ReservedSpace main_rs = heap_rs.last_part(pg_max_size, og_align); - - // Make up the generations - // Calculate the maximum size that a generation can grow. This -@@ -118,14 +154,14 @@ - double max_gc_pause_sec = ((double) MaxGCPauseMillis)/1000.0; - double max_gc_minor_pause_sec = ((double) MaxGCMinorPauseMillis)/1000.0; - -- _gens = new AdjoiningGenerations(old_young_rs, -- old_size, -- min_old_size, -- max_old_size, -- init_young_size, -- min_young_size, -- max_young_size, -- alignment); -+ _gens = new AdjoiningGenerations(main_rs, -+ og_cur_size, -+ og_min_size, -+ og_max_size, -+ yg_cur_size, -+ yg_min_size, -+ yg_max_size, -+ yg_align); - - _old_gen = _gens->old_gen(); - _young_gen = _gens->young_gen(); -@@ -137,7 +173,6 @@ - new PSAdaptiveSizePolicy(eden_capacity, - initial_promo_size, - young_gen()->to_space()->capacity_in_bytes(), -- generation_alignment(), - intra_generation_alignment(), - max_gc_pause_sec, - max_gc_minor_pause_sec, -@@ -145,10 +180,10 @@ - ); - - _perm_gen = new PSPermGen(perm_rs, -- alignment, -- perm_size, -- perm_size, -- max_perm_size, -+ pg_align, -+ pg_cur_size, -+ pg_cur_size, -+ pg_max_size, - "perm", 2); - - assert(!UseAdaptiveGCBoundary || -@@ -170,22 +205,6 @@ - return JNI_OK; - } - --// Set the alignment of the generation so it would be aligned --// to both page_size and to intra_generation_alignment. --// This would require that we align to --// LCM(page_size, intra_generation_alignment), where LCM is --// "least common multiple". However, when page_size and --// intra_generation_alignment are both powers of 2, then --// round_to() below computes the same result; hence the --// assert below. --void ParallelScavengeHeap::adjust_generation_alignment_for_page_size( -- size_t page_size) { -- assert(is_power_of_2(page_size), -- "Should not use round_to() if page size is not a power of 2"); -- // round_to() checks that its second parameter is a power of 2 -- set_generation_alignment(round_to(page_size, intra_generation_alignment())); --} -- - void ParallelScavengeHeap::post_initialize() { - // Need to init the tenuring threshold - PSScavenge::initialize(); -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)parallelScavengeHeap.hpp 1.61 07/05/17 15:52:51 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -42,14 +39,11 @@ - - static ParallelScavengeHeap* _psh; - -- // Byte size of the reserved space for the heap -- size_t _reserved_byte_size; -+ size_t _perm_gen_alignment; -+ size_t _young_gen_alignment; -+ size_t _old_gen_alignment; - -- size_t _generation_alignment; -- inline void set_generation_alignment(size_t val); -- -- // Adjust alignment for page size (may be large page size) -- void adjust_generation_alignment_for_page_size(size_t page_size); -+ inline size_t set_alignment(size_t& var, size_t val); - - // Collection of generations that are adjacent in the - // space reserved for the heap. -@@ -57,9 +51,6 @@ - - static GCTaskManager* _gc_task_manager; // The task manager. - -- // Private accessors -- size_t reserved_byte_size() const { return _reserved_byte_size; } -- - protected: - static inline size_t total_invocations(); - HeapWord* allocate_new_tlab(size_t size); -@@ -67,7 +58,9 @@ - - public: - ParallelScavengeHeap() : CollectedHeap() { -- set_generation_alignment(intra_generation_alignment()); -+ set_alignment(_perm_gen_alignment, intra_generation_alignment()); -+ set_alignment(_young_gen_alignment, intra_generation_alignment()); -+ set_alignment(_old_gen_alignment, intra_generation_alignment()); - } - - // For use by VM operations -@@ -100,8 +93,10 @@ - void post_initialize(); - void update_counters(); - -- // The alignment used for generations. -- size_t generation_alignment() const { return _generation_alignment; } -+ // The alignment used for the various generations. -+ size_t perm_gen_alignment() const { return _perm_gen_alignment; } -+ size_t young_gen_alignment() const { return _young_gen_alignment; } -+ size_t old_gen_alignment() const { return _old_gen_alignment; } - - // The alignment used for eden and survivors within the young gen. - size_t intra_generation_alignment() const { return 64 * K; } -@@ -219,8 +214,9 @@ - void resize_old_gen(size_t desired_free_space); - }; - --inline void ParallelScavengeHeap::set_generation_alignment(size_t val) { -- assert(align_size_up_(val, os::vm_page_size()) == val, "not aligned"); -- assert(val >= intra_generation_alignment(), "alignment size is too small"); -- _generation_alignment = val; -+inline size_t ParallelScavengeHeap::set_alignment(size_t& var, size_t val) -+{ -+ assert(is_power_of_2((intptr_t)val), "must be a power of 2"); -+ var = round_to(val, intra_generation_alignment()); -+ return var; - } -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)parallelScavengeHeap.inline.hpp 1.5 07/05/05 17:05:28 JVM" --#endif - /* - * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)pcTasks.cpp 1.21 07/05/05 17:05:27 JVM" --#endif - /* - * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -149,7 +146,7 @@ - { - ParallelScavengeHeap* heap = PSParallelCompact::gc_heap(); - uint parallel_gc_threads = heap->gc_task_manager()->workers(); -- GenTaskQueueSet* qset = ParCompactionManager::chunk_array()->task_queue_set(); -+ TaskQueueSetSuper* qset = ParCompactionManager::chunk_array(); - ParallelTaskTerminator terminator(parallel_gc_threads, qset); - GCTaskQueue* q = GCTaskQueue::create(); - for(uint i=0; idrain_chunk_stacks(); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)pcTasks.hpp 1.19 07/05/05 17:05:26 JVM" --#endif - /* - * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/prefetchQueue.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/prefetchQueue.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/prefetchQueue.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/prefetchQueue.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)prefetchQueue.hpp 1.13 07/05/05 17:05:28 JVM" --#endif - /* - * Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -68,6 +65,3 @@ - return _prefetch_queue[_prefetch_index]; - } - }; -- -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)psAdaptiveSizePolicy.cpp 1.81 07/05/05 17:05:29 JVM" --#endif - /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -33,7 +30,6 @@ - PSAdaptiveSizePolicy::PSAdaptiveSizePolicy(size_t init_eden_size, - size_t init_promo_size, - size_t init_survivor_size, -- size_t generation_alignment, - size_t intra_generation_alignment, - double gc_pause_goal_sec, - double gc_minor_pause_goal_sec, -@@ -45,18 +41,13 @@ - gc_cost_ratio), - _collection_cost_margin_fraction(AdaptiveSizePolicyCollectionCostMargin/ - 100.0), -- _generation_alignment(generation_alignment), - _intra_generation_alignment(intra_generation_alignment), - _live_at_last_full_gc(init_promo_size), - _gc_minor_pause_goal_sec(gc_minor_pause_goal_sec), - _latest_major_mutator_interval_seconds(0), - _young_gen_change_for_major_pause_count(0) - { -- assert(generation_alignment >= intra_generation_alignment, -- "generation alignment is too small") -- - // Sizing policy statistics -- - _avg_major_pause = - new AdaptivePaddedAverage(AdaptiveTimeWeight, PausePadding); - _avg_minor_interval = new AdaptiveWeightedAverage(AdaptiveTimeWeight); -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)psAdaptiveSizePolicy.hpp 1.63 07/05/05 17:05:27 JVM" --#endif - /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -86,7 +83,6 @@ - // for making ergonomic decisions. - double _latest_major_mutator_interval_seconds; - -- const size_t _generation_alignment; // alignment for generations - const size_t _intra_generation_alignment; // alignment for eden, survivors - - const double _gc_minor_pause_goal_sec; // goal for maximum minor gc pause -@@ -222,7 +218,6 @@ - PSAdaptiveSizePolicy(size_t init_eden_size, - size_t init_promo_size, - size_t init_survivor_size, -- size_t generation_alignment, - size_t intra_generation_alignment, - double gc_pause_goal_sec, - double gc_minor_pause_goal_sec, -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)psCompactionManager.cpp 1.21 07/05/05 17:05:28 JVM" --#endif - /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -97,7 +94,11 @@ - _manager_array[i] = new ParCompactionManager(); - guarantee(_manager_array[i] != NULL, "Could not create ParCompactionManager"); - stack_array()->register_queue(i, _manager_array[i]->marking_stack()); -+#ifdef USE_ChunkTaskQueueWithOverflow -+ chunk_array()->register_queue(i, _manager_array[i]->chunk_stack()->task_queue()); -+#else - chunk_array()->register_queue(i, _manager_array[i]->chunk_stack()); -+#endif - } - - // The VMThread gets its own ParCompactionManager, which is not available -@@ -175,13 +176,12 @@ - } - - bool ParCompactionManager::retrieve_for_processing(size_t& chunk_index) { -- - #ifdef USE_ChunkTaskQueueWithOverflow - return chunk_stack()->retrieve(chunk_index); - #else - // Should not be used in the parallel case - ShouldNotReachHere(); -- return NULL; -+ return false; - #endif - } - -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)psCompactionManager.hpp 1.17 07/05/05 17:05:29 JVM" --#endif - /* - * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)psGCAdaptivePolicyCounters.cpp 1.23 07/05/05 17:05:31 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -200,4 +197,3 @@ - update_counters_from_policy(); - } - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)psGCAdaptivePolicyCounters.hpp 1.21 07/05/05 17:05:29 JVM" --#endif - /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGenerationCounters.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGenerationCounters.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGenerationCounters.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGenerationCounters.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)psGenerationCounters.cpp 1.7 07/05/05 17:05:29 JVM" --#endif - - /* - * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGenerationCounters.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGenerationCounters.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGenerationCounters.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGenerationCounters.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)psGenerationCounters.hpp 1.8 07/05/05 17:05:29 JVM" --#endif - - /* - * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)psMarkSweep.cpp 1.92 07/06/08 23:11:01 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)psMarkSweep.hpp 1.26 07/05/05 17:05:28 JVM" --#endif - /* - * Copyright 2001-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -86,4 +83,3 @@ - // Time since last full gc (in milliseconds) - static jlong millis_since_last_gc(); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)psMarkSweepDecorator.cpp 1.26 07/05/17 15:52:53 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)psMarkSweepDecorator.hpp 1.14 07/05/05 17:05:29 JVM" --#endif - /* - * Copyright 2001-2002 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -74,7 +71,3 @@ - void precompact(); - void compact(bool mangle_free_space); - }; -- -- -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)psOldGen.cpp 1.54 07/05/05 17:05:28 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)psOldGen.hpp 1.37 07/05/05 17:05:30 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)psParallelCompact.cpp 1.61 07/06/08 23:12:00 JVM" --#endif - /* - * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -47,11 +44,23 @@ - - const size_t ParallelCompactData::BlocksPerChunk = ChunkSize / BlockSize; - --// The values for Claimed and Completed were chosen simply to make decrementing --// them to another valid value 'unlikely.' --const size_t ParallelCompactData::ChunkData::Available = 0; --const size_t ParallelCompactData::ChunkData::Claimed = 0x0ffff; --const size_t ParallelCompactData::ChunkData::Completed = 0xfffff; -+const ParallelCompactData::ChunkData::chunk_sz_t -+ParallelCompactData::ChunkData::dc_shift = 27; -+ -+const ParallelCompactData::ChunkData::chunk_sz_t -+ParallelCompactData::ChunkData::dc_mask = ~0U << dc_shift; -+ -+const ParallelCompactData::ChunkData::chunk_sz_t -+ParallelCompactData::ChunkData::dc_one = 0x1U << dc_shift; -+ -+const ParallelCompactData::ChunkData::chunk_sz_t -+ParallelCompactData::ChunkData::los_mask = ~dc_mask; -+ -+const ParallelCompactData::ChunkData::chunk_sz_t -+ParallelCompactData::ChunkData::dc_claimed = 0x8U << dc_shift; -+ -+const ParallelCompactData::ChunkData::chunk_sz_t -+ParallelCompactData::ChunkData::dc_completed = 0xcU << dc_shift; - - #ifdef ASSERT - short ParallelCompactData::BlockData::_cur_phase = 0; -@@ -397,11 +406,17 @@ - PSVirtualSpace* - ParallelCompactData::create_vspace(size_t count, size_t element_size) - { -+ const size_t raw_bytes = count * element_size; -+ const size_t page_sz = os::page_size_for_region(raw_bytes, raw_bytes, 10); - const size_t granularity = os::vm_allocation_granularity(); -- const size_t bytes = align_size_up(count * element_size, granularity); -+ const size_t bytes = align_size_up(raw_bytes, MAX2(page_sz, granularity)); - -- ReservedSpace rs(bytes); -- PSVirtualSpace* vspace = new PSVirtualSpace(rs, os::vm_page_size()); -+ const size_t rs_align = page_sz == (size_t) os::vm_page_size() ? 0 : -+ MAX2(page_sz, granularity); -+ ReservedSpace rs(bytes, rs_align, false); -+ os::trace_page_sizes("par compact", raw_bytes, raw_bytes, page_sz, rs.base(), -+ rs.size()); -+ PSVirtualSpace* vspace = new PSVirtualSpace(rs, page_sz); - if (vspace != 0) { - if (vspace->expand_by(bytes)) { - return vspace; -@@ -517,14 +532,13 @@ - HeapWord* addr = beg; - while (cur_chunk < end_chunk) { - _chunk_data[cur_chunk].set_destination(addr); -- _chunk_data[cur_chunk].set_destination_count(ChunkData::Available); -+ _chunk_data[cur_chunk].set_destination_count(0); - _chunk_data[cur_chunk].set_source_chunk(cur_chunk); - _chunk_data[cur_chunk].set_data_location(addr); - - // Update live_obj_size so the chunk appears completely full. - size_t live_size = ChunkSize - _chunk_data[cur_chunk].partial_obj_size(); - _chunk_data[cur_chunk].set_live_obj_size(live_size); -- _chunk_data[cur_chunk].set_obj_not_updated(NULL); - - ++cur_chunk; - addr += ChunkSize; -@@ -590,7 +604,7 @@ - // adjust the value below if necessary. Under this assumption, if - // cur_chunk == dest_chunk_2, then cur_chunk will be compacted completely - // into itself. -- size_t destination_count = cur_chunk == dest_chunk_2 ? 0 : 1; -+ uint destination_count = cur_chunk == dest_chunk_2 ? 0 : 1; - if (dest_chunk_1 != dest_chunk_2) { - // Destination chunks differ; adjust destination_count. - destination_count += 1; -@@ -606,7 +620,7 @@ - // adjust the value below if necessary. Under this assumption, if - // cur_chunk == dest_chunk2, then cur_chunk will be compacted partially - // into dest_chunk_1 and partially into itself. -- size_t destination_count = cur_chunk == dest_chunk_2 ? 1 : 2; -+ uint destination_count = cur_chunk == dest_chunk_2 ? 1 : 2; - if (dest_chunk_1 != dest_chunk_2) { - // Data from cur_chunk will be copied to the start of dest_chunk_2. - _chunk_data[dest_chunk_2].set_source_chunk(cur_chunk); -@@ -633,11 +647,6 @@ - return true; - } - --void ParallelCompactData::set_obj_not_updated(HeapWord* moved_obj) { -- size_t chunk_index = addr_to_chunk_idx(moved_obj); -- chunk(chunk_index)->set_obj_not_updated(moved_obj); --} -- - bool ParallelCompactData::partial_obj_ends_in_block(size_t block_index) { - HeapWord* block_addr = block_to_addr(block_index); - HeapWord* block_end_addr = block_addr + BlockSize; -@@ -655,39 +664,6 @@ - return false; - } - --HeapWord* --ParallelCompactData::first_live_or_end_in_chunk_range(size_t chunk_index_start, -- size_t chunk_index_end) { -- HeapWord* const end_addr = chunk_to_addr(chunk_index_end); -- -- // A live object may entend into the chunk; skip over it. -- HeapWord* poe_addr = partial_obj_end(chunk_index_start); -- if (poe_addr >= end_addr) { -- return end_addr; -- } -- -- // Search the bitmap for the next object. -- typedef ParMarkBitMap::idx_t idx_t; -- ParMarkBitMap* bitmap = PSParallelCompact::mark_bitmap(); -- const idx_t beg_bit = bitmap->addr_to_bit(poe_addr); -- const idx_t end_bit = bitmap->addr_to_bit(end_addr); -- const idx_t res_bit = bitmap->find_obj_beg(beg_bit, end_bit); -- return res_bit < end_bit ? bitmap->bit_to_addr(res_bit) : end_addr; --} -- --HeapWord* ParallelCompactData::first_live_or_end_in_chunk(size_t chunk_index) { -- // Has the first live for the chunk already been found once? -- HeapWord* result = NULL; -- HeapWord* first_addr = chunk_to_addr(chunk_index); -- if (chunk(chunk_index)->first_live_obj() >= first_addr) { -- result = chunk(chunk_index)->first_live_obj(); -- } else { -- result = first_live_or_end_in_chunk_range(chunk_index, chunk_index + 1); -- chunk(chunk_index)->set_first_live_obj(result); -- } -- return result; --} -- - HeapWord* ParallelCompactData::calc_new_pointer(HeapWord* addr) { - HeapWord* result = NULL; - if (UseParallelOldGCChunkPointerCalc) { -@@ -2372,7 +2348,7 @@ - - ParallelScavengeHeap* heap = gc_heap(); - uint parallel_gc_threads = heap->gc_task_manager()->workers(); -- GenTaskQueueSet* qset = ParCompactionManager::chunk_array()->task_queue_set(); -+ TaskQueueSetSuper* qset = ParCompactionManager::chunk_array(); - ParallelTaskTerminator terminator(parallel_gc_threads, qset); - - PSParallelCompact::MarkAndPushClosure mark_and_push_closure(cm); -@@ -2677,7 +2653,7 @@ - PSOldGen* old_gen = heap->old_gen(); - old_gen->start_array()->reset(); - uint parallel_gc_threads = heap->gc_task_manager()->workers(); -- GenTaskQueueSet* qset = ParCompactionManager::chunk_array()->task_queue_set(); -+ TaskQueueSetSuper* qset = ParCompactionManager::chunk_array(); - ParallelTaskTerminator terminator(parallel_gc_threads, qset); - - GCTaskQueue* q = GCTaskQueue::create(); -@@ -3045,8 +3021,10 @@ - } - - // Mark the chunks as filled. -- for (size_t done_chunk = beg_chunk; done_chunk < end_chunk; ++done_chunk) { -- sd.chunk(done_chunk)->set_completed(); -+ ChunkData* const beg_cp = sd.chunk(beg_chunk); -+ ChunkData* const end_cp = sd.chunk(end_chunk); -+ for (ChunkData* cp = beg_cp; cp < end_cp; ++cp) { -+ cp->set_completed(); - } - } - -@@ -3083,7 +3061,7 @@ - const ChunkData* const end_chunk = sd.addr_to_chunk_ptr(end_addr); - const ChunkData* cur_chunk; - for (cur_chunk = beg_chunk; cur_chunk < end_chunk; ++cur_chunk) { -- HeapWord* const addr = cur_chunk->obj_not_updated(); -+ HeapWord* const addr = cur_chunk->deferred_obj_addr(); - if (addr != NULL) { - if (start_array != NULL) { - start_array->allocate_block(addr); -@@ -3312,6 +3290,7 @@ - closure.copy_partial_obj(); - if (closure.is_full()) { - decrement_destination_counts(cm, src_chunk_idx, closure.source()); -+ chunk_ptr->set_deferred_obj_addr(NULL); - chunk_ptr->set_completed(); - return; - } -@@ -3355,12 +3334,17 @@ - if (status == ParMarkBitMap::would_overflow) { - // The last object did not fit. Note that interior oop updates were - // deferred, then copy enough of the object to fill the chunk. -- chunk_ptr->set_obj_not_updated(closure.destination()); -+ chunk_ptr->set_deferred_obj_addr(closure.destination()); - status = closure.copy_until_full(); // copies from closure.source() -+ -+ decrement_destination_counts(cm, src_chunk_idx, closure.source()); -+ chunk_ptr->set_completed(); -+ return; - } - - if (status == ParMarkBitMap::full) { - decrement_destination_counts(cm, src_chunk_idx, closure.source()); -+ chunk_ptr->set_deferred_obj_addr(NULL); - chunk_ptr->set_completed(); - return; - } -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)psParallelCompact.hpp 1.47 07/05/05 17:05:30 JVM" --#endif - /* - * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -100,28 +97,33 @@ - class ChunkData - { - public: -- static const size_t Available; -- static const size_t Claimed; -- static const size_t Completed; -+ // Destination address of the chunk. -+ HeapWord* destination() const { return _destination; } - -- public: -- // Size of the partial object extending onto the chunk (words). -- size_t partial_obj_size() const { return _partial_obj_size; } -+ // The first chunk containing data destined for this chunk. -+ size_t source_chunk() const { return _source_chunk; } -+ -+ // The object (if any) starting in this chunk and ending in a different -+ // chunk that could not be updated during the main (parallel) compaction -+ // phase. This is different from _partial_obj_addr, which is an object that -+ // extends onto a source chunk. However, the two uses do not overlap in -+ // time, so the same field is used to save space. -+ HeapWord* deferred_obj_addr() const { return _partial_obj_addr; } - -- // The starting address of the partial object. -+ // The starting address of the partial object extending onto the chunk. - HeapWord* partial_obj_addr() const { return _partial_obj_addr; } - -+ // Size of the partial object extending onto the chunk (words). -+ size_t partial_obj_size() const { return _partial_obj_size; } -+ - // Size of live data that lies within this chunk due to objects that start - // in this chunk (words). This does not include the partial object - // extending onto the chunk (if any), or the part of an object that extends - // onto the next chunk (if any). -- size_t live_obj_size() const { return _live_obj_size; } -+ size_t live_obj_size() const { return _dc_and_los & los_mask; } - - // Total live data that lies within the chunk (words). -- size_t data_size() const { return _partial_obj_size + _live_obj_size; } -- -- // Destination address of the chunk. -- HeapWord* destination() const { return _destination; } -+ size_t data_size() const { return partial_obj_size() + live_obj_size(); } - - // The destination_count is the number of other chunks to which data from - // this chunk will be copied. At the end of the summary phase, the valid -@@ -138,90 +140,74 @@ - // then filled. - // - // A chunk is claimed for processing by atomically changing the -- // destination_count from Available to Claimed. After a chunk has been -- // filled, the destination_count should be set to ChunkData::Completed. -- size_t destination_count() const { return _destination_count; } -- -- // Cached address of the first live object starting in the chunk. If the -- // value has not been cached yet, returns NULL. If there is no live object -- // starting in the chunk, returns the address one past the end of the chunk. -- HeapWord* first_live_obj() { return _first_live_obj; } -- -- // Object that crosses this chunk's right (upper) boundary and whose -- // starting address is in this chunk. This is set during -- // compaction when an object extends over the right (upper) boundary of -- // a destination chunk. This is different than _partial_obj_addr -- // which extends over the left (lower) boundary of a source chunk. -- // This object is unique to a chunk. -- HeapWord* obj_not_updated() const { return _obj_not_updated; } -- -- // The first chunk containing data destined for this chunk. -- size_t source_chunk() const { return _source_chunk; } -+ // destination_count to the claimed value (dc_claimed). After a chunk has -+ // been filled, the destination_count should be set to the completed value -+ // (dc_completed). -+ inline uint destination_count() const; -+ inline uint destination_count_raw() const; - - // The location of the java heap data that corresponds to this chunk. -- HeapWord* data_location() const { return _data_location; } -+ inline HeapWord* data_location() const; - - // The highest address referenced by objects in this chunk. -- HeapWord* highest_ref() const { return _highest_ref; } -+ inline HeapWord* highest_ref() const; - - // Whether this chunk is available to be claimed, has been claimed, or has - // been completed. -- bool available() const { return _destination_count == Available; } -- bool claimed() const { return _destination_count == Claimed; } -- bool completed() const { return _destination_count == Completed; } -+ // -+ // Minor subtlety: claimed() returns true if the chunk is marked -+ // completed(), which is desirable since a chunk must be claimed before it -+ // can be completed. -+ bool available() const { return _dc_and_los < dc_one; } -+ bool claimed() const { return _dc_and_los >= dc_claimed; } -+ bool completed() const { return _dc_and_los >= dc_completed; } - - // These are not atomic. -- void set_partial_obj_size(size_t words) { _partial_obj_size = words; } -- void set_partial_obj_addr(HeapWord* k) { _partial_obj_addr = k; } -- void set_live_obj_size(size_t words) { _live_obj_size = words; } - void set_destination(HeapWord* addr) { _destination = addr; } -- void set_destination_count(size_t count) { _destination_count = count; } -- void set_first_live_obj(HeapWord* v) { _first_live_obj = v; } -- void set_obj_not_updated(HeapWord* addr) { _obj_not_updated = addr; } - void set_source_chunk(size_t chunk) { _source_chunk = chunk; } -- void set_data_location(HeapWord* addr) { _data_location = addr; } -+ void set_deferred_obj_addr(HeapWord* addr) { _partial_obj_addr = addr; } -+ void set_partial_obj_addr(HeapWord* addr) { _partial_obj_addr = addr; } -+ void set_partial_obj_size(size_t words) { -+ _partial_obj_size = (chunk_sz_t) words; -+ } -+ -+ inline void set_destination_count(uint count); -+ inline void set_live_obj_size(size_t words); -+ inline void set_data_location(HeapWord* addr); - inline void set_completed(); - inline bool claim_unsafe(); - - // These are atomic. -- void add_live_obj(size_t words) { add_live_obj((intptr_t)words); } -- -- void set_highest_ref(HeapWord* addr) { -- HeapWord* tmp = _highest_ref; -- while (addr > tmp) { -- tmp = (HeapWord*)Atomic::cmpxchg_ptr(addr, &_highest_ref, tmp); -- } -- } -- -- void decrement_destination_count() { -- assert(_destination_count < Claimed, "Chunk already claimed"); -- assert(_destination_count > 0, "count must not go negative"); -- Atomic::add_ptr(-1, &_destination_count); -- } -- -- bool claim() { -- size_t old_val = cmpxchg_size_t(Claimed, &_destination_count, Available); -- return old_val == Available; -- } -+ inline void add_live_obj(size_t words); -+ inline void set_highest_ref(HeapWord* addr); -+ inline void decrement_destination_count(); -+ inline bool claim(); - - private: -- static size_t cmpxchg_size_t(size_t new_val, volatile size_t* addr, -- size_t old_val) { -- return size_t(Atomic::cmpxchg_ptr((void*)new_val, addr, (void*)old_val)); -- } -- void add_live_obj(intptr_t sz) { Atomic::add_ptr(sz, &_live_obj_size); } -+ // The type used to represent object sizes within a chunk. -+ typedef uint chunk_sz_t; -+ -+ // Constants for manipulating the _dc_and_los field, which holds both the -+ // destination count and live obj size. The live obj size lives at the -+ // least significant end so no masking is necessary when adding. -+ static const chunk_sz_t dc_shift; // Shift amount. -+ static const chunk_sz_t dc_mask; // Mask for destination count. -+ static const chunk_sz_t dc_one; // 1, shifted appropriately. -+ static const chunk_sz_t dc_claimed; // Chunk has been claimed. -+ static const chunk_sz_t dc_completed; // Chunk has been completed. -+ static const chunk_sz_t los_mask; // Mask for live obj size. - -- private: -- size_t _partial_obj_size; -- HeapWord* _partial_obj_addr; -- volatile size_t _live_obj_size; - HeapWord* _destination; -- HeapWord* _first_live_obj; -- HeapWord* _obj_not_updated; - size_t _source_chunk; -+ HeapWord* _partial_obj_addr; -+ chunk_sz_t _partial_obj_size; -+ chunk_sz_t volatile _dc_and_los; -+#ifdef ASSERT -+ // These enable optimizations that are only partially implemented. Use -+ // debug builds to prevent the code fragments from breaking. - HeapWord* _data_location; - HeapWord* _highest_ref; -- volatile size_t _destination_count; -+#endif // #ifdef ASSERT - - #ifdef ASSERT - public: -@@ -357,10 +343,6 @@ - inline BlockData* addr_to_block_ptr(const HeapWord* addr) const; - inline HeapWord* block_to_addr(size_t block) const; - -- // The given object (new location) was not updated. -- // Set the _obj_not_updated field in the appropriate chunk. -- void set_obj_not_updated(HeapWord* moved_obj); -- - // Return the address one past the end of the partial object. - HeapWord* partial_obj_end(size_t chunk_idx) const; - -@@ -386,16 +368,6 @@ - // If there is no partial object, returns false. - bool partial_obj_ends_in_block(size_t block_index); - -- // Returns the address of the first live object starting in the chunk. -- HeapWord* first_live_or_end_in_chunk(size_t chunk_index); -- -- // Returns the address of the first live object starting in the chunk. -- HeapWord* first_live_or_end_in_chunk_range(size_t chunk_index_start, -- size_t chunk_index_end); -- -- // Returns the address of the first live object starting in the block. -- HeapWord* first_live_object_in_block(size_t block_index); -- - // Returns the block index for the block - static size_t block_idx(BlockData* block); - -@@ -424,23 +396,97 @@ - size_t _block_count; - }; - -+inline uint -+ParallelCompactData::ChunkData::destination_count_raw() const -+{ -+ return _dc_and_los & dc_mask; -+} -+ -+inline uint -+ParallelCompactData::ChunkData::destination_count() const -+{ -+ return destination_count_raw() >> dc_shift; -+} -+ -+inline void -+ParallelCompactData::ChunkData::set_destination_count(uint count) -+{ -+ assert(count <= (dc_completed >> dc_shift), "count too large"); -+ const chunk_sz_t live_sz = (chunk_sz_t) live_obj_size(); -+ _dc_and_los = (count << dc_shift) | live_sz; -+} -+ -+inline void ParallelCompactData::ChunkData::set_live_obj_size(size_t words) -+{ -+ assert(words <= los_mask, "would overflow"); -+ _dc_and_los = destination_count_raw() | (chunk_sz_t)words; -+} -+ -+inline void ParallelCompactData::ChunkData::decrement_destination_count() -+{ -+ assert(_dc_and_los < dc_claimed, "already claimed"); -+ assert(_dc_and_los >= dc_one, "count would go negative"); -+ Atomic::add((int)dc_mask, (volatile int*)&_dc_and_los); -+} -+ -+inline HeapWord* ParallelCompactData::ChunkData::data_location() const -+{ -+ DEBUG_ONLY(return _data_location;) -+ NOT_DEBUG(return NULL;) -+} -+ -+inline HeapWord* ParallelCompactData::ChunkData::highest_ref() const -+{ -+ DEBUG_ONLY(return _highest_ref;) -+ NOT_DEBUG(return NULL;) -+} -+ -+inline void ParallelCompactData::ChunkData::set_data_location(HeapWord* addr) -+{ -+ DEBUG_ONLY(_data_location = addr;) -+} -+ - inline void ParallelCompactData::ChunkData::set_completed() - { - assert(claimed(), "must be claimed first"); -- set_destination_count(Completed); -+ _dc_and_los = dc_completed | (chunk_sz_t) live_obj_size(); - } - - // MT-unsafe claiming of a chunk. Should only be used during single threaded - // execution. - inline bool ParallelCompactData::ChunkData::claim_unsafe() - { -- if (destination_count() == Available) { -- set_destination_count(Claimed); -+ if (available()) { -+ _dc_and_los |= dc_claimed; - return true; - } - return false; - } - -+inline void ParallelCompactData::ChunkData::add_live_obj(size_t words) -+{ -+ assert(words <= (size_t)los_mask - live_obj_size(), "overflow"); -+ Atomic::add((int) words, (volatile int*) &_dc_and_los); -+} -+ -+inline void ParallelCompactData::ChunkData::set_highest_ref(HeapWord* addr) -+{ -+#ifdef ASSERT -+ HeapWord* tmp = _highest_ref; -+ while (addr > tmp) { -+ tmp = (HeapWord*)Atomic::cmpxchg_ptr(addr, &_highest_ref, tmp); -+ } -+#endif // #ifdef ASSERT -+} -+ -+inline bool ParallelCompactData::ChunkData::claim() -+{ -+ const int los = (int) live_obj_size(); -+ const int old = Atomic::cmpxchg(dc_claimed | los, -+ (volatile int*) &_dc_and_los, los); -+ return old == los; -+} -+ - inline ParallelCompactData::ChunkData* - ParallelCompactData::chunk(size_t chunk_idx) const - { -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPermGen.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPermGen.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPermGen.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPermGen.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)psPermGen.cpp 1.28 07/05/05 17:05:30 JVM" --#endif - /* - * Copyright 2001-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPermGen.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPermGen.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPermGen.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPermGen.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)psPermGen.hpp 1.18 07/05/05 17:05:30 JVM" --#endif - /* - * Copyright 2001-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -54,4 +51,3 @@ - - virtual const char* name() const { return "PSPermGen"; } - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)psPromotionLAB.cpp 1.17 07/05/05 17:05:30 JVM" --#endif - /* - * Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)psPromotionLAB.hpp 1.13 07/05/05 17:05:30 JVM" --#endif - /* - * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -143,5 +140,3 @@ - - debug_only(virtual bool lab_is_valid(MemRegion lab)); - }; -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)psPromotionManager.cpp 1.29 07/05/05 17:05:30 JVM" --#endif - /* - * Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -68,7 +65,6 @@ - // for work stealing. - _manager_array[ParallelGCThreads] = new PSPromotionManager(); - guarantee(_manager_array[ParallelGCThreads] != NULL, "Could not create PSPromotionManager"); -- - } - - PSPromotionManager* PSPromotionManager::gc_thread_promotion_manager(int index) { -@@ -94,6 +90,10 @@ - } - - void PSPromotionManager::post_scavenge() { -+#if PS_PM_STATS -+ print_stats(); -+#endif // PS_PM_STATS -+ - for(uint i=0; iprint_cr("---- GC Worker %2d Stats", i); -+ tty->print_cr(" total pushes %8d", _total_pushes); -+ tty->print_cr(" masked pushes %8d", _masked_pushes); -+ tty->print_cr(" overflow pushes %8d", _overflow_pushes); -+ tty->print_cr(" max overflow length %8d", _max_overflow_length); -+ tty->print_cr(""); -+ tty->print_cr(" arrays chunked %8d", _arrays_chunked); -+ tty->print_cr(" array chunks processed %8d", _array_chunks_processed); -+ tty->print_cr(""); -+ tty->print_cr(" total steals %8d", _total_steals); -+ tty->print_cr(" masked steals %8d", _masked_steals); -+ tty->print_cr(""); -+} -+ -+void -+PSPromotionManager::print_stats() { -+ tty->print_cr("== GC Tasks Stats (%s), GC %3d", -+ (UseDepthFirstScavengeOrder) ? "Depth-First" : "Breadth-First", -+ Universe::heap()->total_collections()); -+ -+ for (uint i = 0; i < ParallelGCThreads+1; ++i) { -+ PSPromotionManager* manager = manager_array(i); -+ manager->print_stats(i); -+ } -+} -+ -+#endif // PS_PM_STATS -+ - PSPromotionManager::PSPromotionManager() { - ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); - assert(heap->kind() == CollectedHeap::ParallelScavengeHeap, "Sanity"); -@@ -169,6 +201,10 @@ - (uint) (queue_size / 4)); - } - -+ _array_chunk_size = ParGCArrayScanChunk; -+ // let's choose 1.5x the chunk size -+ _min_array_size_for_chunking = 3 * _array_chunk_size / 2; -+ - reset(); - } - -@@ -191,9 +227,21 @@ - _old_gen_is_full = false; - - _prefetch_queue.clear(); -+ -+#if PS_PM_STATS -+ _total_pushes = 0; -+ _masked_pushes = 0; -+ _overflow_pushes = 0; -+ _max_overflow_length = 0; -+ _arrays_chunked = 0; -+ _array_chunks_processed = 0; -+ _total_steals = 0; -+ _masked_steals = 0; -+#endif // PS_PM_STATS - } - - void PSPromotionManager::drain_stacks_depth(bool totally_drain) { -+ assert(depth_first(), "invariant"); - assert(overflow_stack_depth() != NULL, "invariant"); - totally_drain = totally_drain || _totally_drain; - -@@ -212,17 +260,17 @@ - // claimed stack while we work. - while(!overflow_stack_depth()->is_empty()) { - p = overflow_stack_depth()->pop(); -- PSScavenge::copy_and_push_safe_barrier(this, p); -+ process_popped_location_depth(p); - } - - if (totally_drain) { - while (claimed_stack_depth()->pop_local(p)) { -- PSScavenge::copy_and_push_safe_barrier(this, p); -+ process_popped_location_depth(p); - } - } else { - while (claimed_stack_depth()->size() > _target_stack_size && - claimed_stack_depth()->pop_local(p)) { -- PSScavenge::copy_and_push_safe_barrier(this, p); -+ process_popped_location_depth(p); - } - } - } while( (totally_drain && claimed_stack_depth()->size() > 0) || -@@ -236,6 +284,7 @@ - } - - void PSPromotionManager::drain_stacks_breadth(bool totally_drain) { -+ assert(!depth_first(), "invariant"); - assert(overflow_stack_breadth() != NULL, "invariant"); - totally_drain = totally_drain || _totally_drain; - -@@ -420,13 +469,28 @@ - } - - if (depth_first) { -- new_obj->push_contents(this); -+ // Do the size comparison first with new_obj_size, which we -+ // already have. Hopefully, only a few objects are larger than -+ // _min_array_size_for_chunking, and most of them will be arrays. -+ // So, the is->objArray() test would be very infrequent. -+ if (new_obj_size > _min_array_size_for_chunking && -+ new_obj->is_objArray() && -+ PSChunkLargeArrays) { -+ // we'll chunk it -+#if PS_PM_STATS -+ ++_arrays_chunked; -+#endif // PS_PM_STATS -+ oop* const masked_o = mask_chunked_array_oop(o); -+ push_depth(masked_o); -+#if PS_PM_STATS -+ ++_masked_pushes; -+#endif // PS_PM_STATS - } else { -- // If we loop too many times, handle_stack_overflow will assert. -- // It may be worth adding loop count asserts anyway. -- if (!claimed_stack_breadth()->push(new_obj)) { -- overflow_stack_breadth()->push(new_obj); -+ // we'll just push its contents -+ new_obj->push_contents(this); - } -+ } else { -+ push_breadth(new_obj); - } - } else { - // We lost, someone else "owns" this object -@@ -476,6 +540,47 @@ - return new_obj; - } - -+void PSPromotionManager::process_array_chunk(oop old) { -+ assert(PSChunkLargeArrays, "invariant"); -+ assert(old->is_objArray(), "invariant"); -+ assert(old->is_forwarded(), "invariant"); -+ -+#if PS_PM_STATS -+ ++_array_chunks_processed; -+#endif // PS_PM_STATS -+ -+ oop const obj = old->forwardee(); -+ -+ int start; -+ int const end = arrayOop(old)->length(); -+ if (end > (int) _min_array_size_for_chunking) { -+ // we'll chunk more -+ start = end - _array_chunk_size; -+ assert(start > 0, "invariant"); -+ arrayOop(old)->set_length(start); -+ push_depth(mask_chunked_array_oop(old)); -+#if PS_PM_STATS -+ ++_masked_pushes; -+#endif // PS_PM_STATS -+ } else { -+ // this is the final chunk for this array -+ start = 0; -+ int const actual_length = arrayOop(obj)->length(); -+ arrayOop(old)->set_length(actual_length); -+ } -+ -+ assert(start < end, "invariant"); -+ oop* const base = objArrayOop(obj)->base(); -+ oop* p = base + start; -+ oop* const chunk_end = base + end; -+ while (p < chunk_end) { -+ if (PSScavenge::should_scavenge(*p)) { -+ claim_or_forward_depth(p); -+ } -+ ++p; -+ } -+} -+ - oop PSPromotionManager::oop_promotion_failed(oop obj, markOop obj_mark) { - assert(_old_gen_is_full || PromotionFailureALot, "Sanity"); - -@@ -493,9 +598,7 @@ - } else { - // Don't bother incrementing the age, just push - // onto the claimed_stack.. -- if(!claimed_stack_breadth()->push(obj)) { -- overflow_stack_breadth()->push(obj); -- } -+ push_breadth(obj); - } - - // Save the mark if needed -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)psPromotionManager.hpp 1.19 07/05/05 17:05:30 JVM" --#endif - /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -41,11 +38,14 @@ - #define HAS_BEEN_MOVED 0x1501d01d - // End move to some global location - -- - class MutableSpace; - class PSOldGen; - class ParCompactionManager; - -+#define PS_CHUNKED_ARRAY_OOP_MASK 1 -+ -+#define PS_PM_STATS 0 -+ - class PSPromotionManager : public CHeapObj { - friend class PSScavenge; - friend class PSRefProcTaskExecutor; -@@ -56,6 +56,23 @@ - static PSOldGen* _old_gen; - static MutableSpace* _young_space; - -+#if PS_PM_STATS -+ uint _total_pushes; -+ uint _masked_pushes; -+ -+ uint _overflow_pushes; -+ uint _max_overflow_length; -+ -+ uint _arrays_chunked; -+ uint _array_chunks_processed; -+ -+ uint _total_steals; -+ uint _masked_steals; -+ -+ void print_stats(uint i); -+ static void print_stats(); -+#endif // PS_PM_STATS -+ - PSYoungPromotionLAB _young_lab; - PSOldPromotionLAB _old_lab; - bool _young_gen_is_full; -@@ -71,17 +88,92 @@ - bool _totally_drain; - uint _target_stack_size; - -+ uint _array_chunk_size; -+ uint _min_array_size_for_chunking; -+ - // Accessors - static PSOldGen* old_gen() { return _old_gen; } - static MutableSpace* young_space() { return _young_space; } - - inline static PSPromotionManager* manager_array(int index); -- inline void claim_or_forward_internal_depth(oop* p); -- inline void claim_or_forward_internal_breadth(oop* p); - - GrowableArray* overflow_stack_depth() { return _overflow_stack_depth; } - GrowableArray* overflow_stack_breadth() { return _overflow_stack_breadth; } - -+ // On the task queues we push reference locations as well as -+ // partially-scanned arrays (in the latter case, we push an oop to -+ // the from-space image of the array and the length on the -+ // from-space image indicates how many entries on the array we still -+ // need to scan; this is basically how ParNew does partial array -+ // scanning too). To be able to distinguish between reference -+ // locations and partially-scanned array oops we simply mask the -+ // latter oops with 0x01. The next three methods do the masking, -+ // unmasking, and checking whether the oop is masked or not. Notice -+ // that the signature of the mask and unmask methods looks a bit -+ // strange, as they accept and return different types (oop and -+ // oop*). This is because of the difference in types between what -+ // the task queue holds (oop*) and oops to partially-scanned arrays -+ // (oop). We do all the necessary casting in the mask / unmask -+ // methods to avoid sprinkling the rest of the code with more casts. -+ -+ bool is_oop_masked(oop* p) { -+ return ((intptr_t) p & PS_CHUNKED_ARRAY_OOP_MASK) == PS_CHUNKED_ARRAY_OOP_MASK; -+ } -+ -+ oop* mask_chunked_array_oop(oop obj) { -+ assert(!is_oop_masked((oop*) obj), "invariant"); -+ oop* ret = (oop*) ((intptr_t) obj | PS_CHUNKED_ARRAY_OOP_MASK); -+ assert(is_oop_masked(ret), "invariant"); -+ return ret; -+ } -+ -+ oop unmask_chunked_array_oop(oop* p) { -+ assert(is_oop_masked(p), "invariant"); -+ oop ret = oop((intptr_t) p & ~PS_CHUNKED_ARRAY_OOP_MASK); -+ assert(!is_oop_masked((oop*) ret), "invariant"); -+ return ret; -+ } -+ -+ void process_array_chunk(oop old); -+ -+ void push_depth(oop* p) { -+ assert(depth_first(), "pre-condition"); -+ -+#if PS_PM_STATS -+ ++_total_pushes; -+#endif // PS_PM_STATS -+ -+ if (!claimed_stack_depth()->push(p)) { -+ overflow_stack_depth()->push(p); -+#if PS_PM_STATS -+ ++_overflow_pushes; -+ uint stack_length = (uint) overflow_stack_depth()->length(); -+ if (stack_length > _max_overflow_length) { -+ _max_overflow_length = stack_length; -+ } -+#endif // PS_PM_STATS -+ } -+ } -+ -+ void push_breadth(oop o) { -+ assert(!depth_first(), "pre-condition"); -+ -+#if PS_PM_STATS -+ ++_total_pushes; -+#endif // PS_PM_STATS -+ -+ if(!claimed_stack_breadth()->push(o)) { -+ overflow_stack_breadth()->push(o); -+#if PS_PM_STATS -+ ++_overflow_pushes; -+ uint stack_length = (uint) overflow_stack_breadth()->length(); -+ if (stack_length > _max_overflow_length) { -+ _max_overflow_length = stack_length; -+ } -+#endif // PS_PM_STATS -+ } -+ } -+ - protected: - static OopStarTaskQueueSet* stack_array_depth() { return _stack_array_depth; } - static OopTaskQueueSet* stack_array_breadth() { return _stack_array_breadth; } -@@ -124,7 +216,6 @@ - // Promotion methods - oop copy_to_survivor_space(oop o, bool depth_first); - oop oop_promotion_failed(oop obj, markOop obj_mark); -- void handle_stack_overflow(); - - void reset(); - -@@ -136,6 +227,11 @@ - drain_stacks_breadth(totally_drain); - } - } -+ void drain_stacks_cond_depth() { -+ if (claimed_stack_depth()->size() > _target_stack_size) { -+ drain_stacks_depth(false); -+ } -+ } - void drain_stacks_depth(bool totally_drain); - void drain_stacks_breadth(bool totally_drain); - -@@ -160,7 +256,22 @@ - return _depth_first; - } - -+ inline void process_popped_location_depth(oop* p); -+ - inline void flush_prefetch_queue(); -+ - inline void claim_or_forward_depth(oop* p); -+ inline void claim_or_forward_internal_depth(oop* p); -+ - inline void claim_or_forward_breadth(oop* p); -+ inline void claim_or_forward_internal_breadth(oop* p); -+ -+#if PS_PM_STATS -+ void increment_steals(oop* p = NULL) { -+ _total_steals += 1; -+ if (p != NULL && is_oop_masked(p)) { -+ _masked_steals += 1; -+ } -+ } -+#endif // PS_PM_STATS - }; -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)psPromotionManager.inline.hpp 1.18 07/05/05 17:05:30 JVM" --#endif - /* - * Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -43,9 +40,7 @@ - } - *p = o; - } else { -- if (!claimed_stack_depth()->push(p)) { -- overflow_stack_depth()->push(p); -- } -+ push_depth(p); - } - } - } -@@ -110,3 +105,13 @@ - claim_or_forward_internal_breadth(p); - } - } -+ -+inline void PSPromotionManager::process_popped_location_depth(oop* p) { -+ if (is_oop_masked(p)) { -+ assert(PSChunkLargeArrays, "invariant"); -+ oop const old = unmask_chunked_array_oop(p); -+ process_array_chunk(old); -+ } else { -+ PSScavenge::copy_and_push_safe_barrier(this, p); -+ } -+} -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)psScavenge.cpp 1.98 07/06/08 23:12:37 JVM" --#endif - /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -778,7 +775,7 @@ - mr, // span - true, // atomic_discovery - true, // mt_discovery -- &_is_alive_closure, -+ NULL, // is_alive_non_header - ParallelGCThreads, - ParallelRefProcEnabled); - -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)psScavenge.hpp 1.46 07/05/05 17:05:30 JVM" --#endif - /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)psScavenge.inline.hpp 1.18 07/05/05 17:05:29 JVM" --#endif - /* - * Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)psTasks.cpp 1.28 07/05/05 17:05:27 JVM" --#endif - /* - * Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -140,7 +137,10 @@ - while(true) { - oop* p; - if (PSPromotionManager::steal_depth(which, &random_seed, p)) { -- PSScavenge::copy_and_push_safe_barrier(pm, p); -+#if PS_PM_STATS -+ pm->increment_steals(p); -+#endif // PS_PM_STATS -+ pm->process_popped_location_depth(p); - pm->drain_stacks_depth(true); - } else { - if (terminator()->offer_termination()) { -@@ -152,6 +152,9 @@ - while(true) { - oop obj; - if (PSPromotionManager::steal_breadth(which, &random_seed, obj)) { -+#if PS_PM_STATS -+ pm->increment_steals(); -+#endif // PS_PM_STATS - obj->copy_contents(pm); - pm->drain_stacks_breadth(true); - } else { -@@ -216,5 +219,3 @@ - pm->drain_stacks(false); - } - } -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)psTasks.hpp 1.21 07/05/05 17:05:29 JVM" --#endif - /* - * Copyright 2002-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -146,4 +143,3 @@ - - virtual void do_it(GCTaskManager* manager, uint which); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)psVirtualspace.cpp 1.16 07/05/05 17:05:31 JVM" --#endif - /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)psVirtualspace.hpp 1.15 07/05/05 17:05:31 JVM" --#endif - /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)psYoungGen.cpp 1.67 07/05/05 17:05:31 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -712,7 +709,7 @@ - size_t delta_in_survivor = 0; - ParallelScavengeHeap* heap = (ParallelScavengeHeap*)Universe::heap(); - const size_t space_alignment = heap->intra_generation_alignment(); -- const size_t gen_alignment = heap->generation_alignment(); -+ const size_t gen_alignment = heap->young_gen_alignment(); - - MutableSpace* space_shrinking = NULL; - if (from_space()->end() > to_space()->end()) { -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)psYoungGen.hpp 1.48 07/05/05 17:05:31 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)vmPSOperations.cpp 1.1 07/05/14 11:57:11 JVM" --#endif - /* - * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -102,4 +99,3 @@ - } - notify_gc_end(); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmPSOperations.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)vmPSOperations.hpp 1.2 07/05/16 16:53:01 JVM" --#endif - /* - * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmStructs_parallelgc.hpp openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmStructs_parallelgc.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmStructs_parallelgc.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/parallelScavenge/vmStructs_parallelgc.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)vmStructs_parallelgc.hpp 1.2 07/05/01 19:01:30 JVM" --#endif - /* - * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)adaptiveSizePolicy.cpp 1.13 07/05/05 17:05:33 JVM" --#endif - /* - * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)adaptiveSizePolicy.hpp 1.15 07/05/05 17:05:32 JVM" --#endif - /* - * Copyright 2004-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/ageTable.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/ageTable.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/ageTable.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/ageTable.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ageTable.cpp 1.36 07/05/05 17:05:33 JVM" --#endif - /* - * Copyright 1997-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/ageTable.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/ageTable.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/ageTable.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/ageTable.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ageTable.hpp 1.29 07/05/05 17:05:32 JVM" --#endif - /* - * Copyright 1997-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)cSpaceCounters.cpp 1.10 07/05/05 17:05:32 JVM" --#endif - /* - * Copyright 2002-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)cSpaceCounters.hpp 1.12 07/05/05 17:05:33 JVM" --#endif - /* - * Copyright 2002-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -78,4 +75,3 @@ - return _space->used(); - } - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/collectorCounters.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/collectorCounters.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/collectorCounters.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/collectorCounters.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)collectorCounters.cpp 1.10 07/05/05 17:05:32 JVM" --#endif - /* - * Copyright 2002-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/collectorCounters.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/collectorCounters.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/collectorCounters.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/collectorCounters.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)collectorCounters.hpp 1.10 07/05/05 17:05:33 JVM" --#endif - /* - * Copyright 2002-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -81,4 +78,3 @@ - if (UsePerfData) _c->last_exit_counter()->set_value(os::elapsed_counter()); - } - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/gSpaceCounters.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/gSpaceCounters.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/gSpaceCounters.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/gSpaceCounters.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)gSpaceCounters.cpp 1.11 07/05/05 17:05:33 JVM" --#endif - /* - * Copyright 2002-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)gSpaceCounters.hpp 1.14 07/05/05 17:05:33 JVM" --#endif - /* - * Copyright 2002-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -103,4 +100,3 @@ - return _gen->used(); - } - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcAdaptivePolicyCounters.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/gcAdaptivePolicyCounters.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcAdaptivePolicyCounters.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/gcAdaptivePolicyCounters.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)gcAdaptivePolicyCounters.cpp 1.10 07/05/05 17:05:34 JVM" --#endif - /* - * Copyright 2004-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcAdaptivePolicyCounters.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/gcAdaptivePolicyCounters.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcAdaptivePolicyCounters.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/gcAdaptivePolicyCounters.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)gcAdaptivePolicyCounters.hpp 1.11 07/05/05 17:05:34 JVM" --#endif - /* - * Copyright 2004-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcPolicyCounters.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/gcPolicyCounters.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcPolicyCounters.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/gcPolicyCounters.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)gcPolicyCounters.cpp 1.13 07/05/05 17:05:34 JVM" --#endif - /* - * Copyright 2002-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcPolicyCounters.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/gcPolicyCounters.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcPolicyCounters.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/gcPolicyCounters.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)gcPolicyCounters.hpp 1.18 07/05/05 17:05:33 JVM" --#endif - /* - * Copyright 2002-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcStats.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/gcStats.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcStats.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/gcStats.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)gcStats.cpp 1.9 07/05/05 17:05:33 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcStats.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/gcStats.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcStats.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/gcStats.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)gcStats.hpp 1.10 07/05/05 17:05:34 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcUtil.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/gcUtil.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcUtil.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/gcUtil.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)gcUtil.cpp 1.21 07/05/05 17:05:32 JVM" --#endif - /* - * Copyright 2002-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcUtil.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/gcUtil.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/gcUtil.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/gcUtil.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)gcUtil.hpp 1.19 07/05/05 17:05:32 JVM" --#endif - /* - * Copyright 2002-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -177,4 +174,3 @@ - _timer->start(); - } - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/generationCounters.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/generationCounters.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/generationCounters.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/generationCounters.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)generationCounters.cpp 1.10 07/05/05 17:05:34 JVM" --#endif - /* - * Copyright 2002-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/generationCounters.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/generationCounters.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/generationCounters.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/generationCounters.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)generationCounters.hpp 1.14 07/05/05 17:05:34 JVM" --#endif - /* - * Copyright 2002-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)immutableSpace.cpp 1.13 07/05/05 17:05:34 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -80,4 +77,3 @@ - } - guarantee(p == end(), "end of last object must match end of space"); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)immutableSpace.hpp 1.14 07/05/05 17:05:33 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/isGCActiveMark.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/isGCActiveMark.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/isGCActiveMark.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/isGCActiveMark.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)isGCActiveMark.hpp 1.9 07/05/05 17:05:34 JVM" --#endif - /* - * Copyright 2002 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/liveRange.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/liveRange.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/liveRange.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/liveRange.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)liveRange.hpp 1.11 07/05/05 17:05:34 JVM" --#endif - /* - * Copyright 2001-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)markSweep.cpp 1.196 07/05/05 17:05:35 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -358,4 +355,3 @@ - } - - #endif -- -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)markSweep.hpp 1.67 07/05/17 15:52:55 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/markSweep.inline.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/markSweep.inline.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/markSweep.inline.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/markSweep.inline.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)markSweep.inline.hpp 1.17 07/05/29 09:44:12 JVM" --#endif - /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)mutableNUMASpace.cpp 1.8 07/05/05 17:05:35 JVM" --#endif - - /* - * Copyright 2006-2007 Sun Microsystems, Inc. All Rights Reserved. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)mutableNUMASpace.hpp 1.8 07/05/05 17:05:34 JVM" --#endif - /* - * Copyright 2006-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)mutableSpace.cpp 1.22 07/05/05 17:05:35 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)mutableSpace.hpp 1.22 07/05/05 17:05:35 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/spaceCounters.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/spaceCounters.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/spaceCounters.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/spaceCounters.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)spaceCounters.cpp 1.10 07/05/05 17:05:35 JVM" --#endif - /* - * Copyright 2002-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/spaceCounters.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/spaceCounters.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/spaceCounters.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/spaceCounters.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)spaceCounters.hpp 1.11 07/05/05 17:05:35 JVM" --#endif - /* - * Copyright 2002-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp openjdk/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)vmGCOperations.cpp 1.21 07/05/29 09:44:12 JVM" --#endif - /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.hpp openjdk/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.hpp ---- openjdk6/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_implementation/shared/vmGCOperations.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)vmGCOperations.hpp 1.14 07/05/29 09:44:12 JVM" --#endif - /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_interface/collectedHeap.cpp openjdk/hotspot/src/share/vm/gc_interface/collectedHeap.cpp ---- openjdk6/hotspot/src/share/vm/gc_interface/collectedHeap.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_interface/collectedHeap.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)collectedHeap.cpp 1.23 07/05/05 17:05:40 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -132,6 +129,23 @@ - return obj; - } - -+oop CollectedHeap::new_store_barrier(oop new_obj) { -+ // %%% This needs refactoring. (It was imported from the server compiler.) -+ guarantee(can_elide_tlab_store_barriers(), "store barrier elision not supported"); -+ BarrierSet* bs = this->barrier_set(); -+ assert(bs->has_write_region_opt(), "Barrier set does not have write_region"); -+ int new_size = new_obj->size(); -+ bs->write_region(MemRegion((HeapWord*)new_obj, new_size)); -+ return new_obj; -+} -+ -+bool CollectedHeap::can_elide_permanent_oop_store_barriers() const { -+ // %%% This needs refactoring. (It was gating logic from the server compiler.) -+ guarantee(kind() < CollectedHeap::G1CollectedHeap, ""); -+ return !UseConcMarkSweepGC; -+} -+ -+ - HeapWord* CollectedHeap::allocate_new_tlab(size_t size) { - guarantee(false, "thread-local allocation buffers not supported"); - return NULL; -diff -ruNb openjdk6/hotspot/src/share/vm/gc_interface/collectedHeap.hpp openjdk/hotspot/src/share/vm/gc_interface/collectedHeap.hpp ---- openjdk6/hotspot/src/share/vm/gc_interface/collectedHeap.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_interface/collectedHeap.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)collectedHeap.hpp 1.55 07/05/17 15:52:57 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -245,6 +242,11 @@ - return p == NULL || is_in_permanent(p); - } - -+ // Returns "TRUE" if "p" is a method oop in the -+ // current heap, with high probability. This predicate -+ // is not stable, in general. -+ bool is_valid_method(oop p) const; -+ - void set_gc_cause(GCCause::Cause v) { - if (UsePerfData) { - _gc_lastcause = _gc_cause; -@@ -363,6 +365,25 @@ - guarantee(false, "thread-local allocation buffers not supported"); - return 0; - } -+ // Can a compiler initialize a new object without store barriers? -+ // This permission only extends from the creation of a new object -+ // via a TLAB up to the first subsequent safepoint. -+ virtual bool can_elide_tlab_store_barriers() const { -+ guarantee(kind() < CollectedHeap::G1CollectedHeap, "else change or refactor this"); -+ return true; -+ } -+ // If a compiler is eliding store barriers for TLAB-allocated objects, -+ // there is probably a corresponding slow path which can produce -+ // an object allocated anywhere. The compiler's runtime support -+ // promises to call this function on such a slow-path-allocated -+ // object before performing initializations that have elided -+ // store barriers. Returns new_obj, or maybe a safer copy thereof. -+ virtual oop new_store_barrier(oop new_obj); -+ -+ // Can a compiler elide a store barrier when it writes -+ // a permanent oop into the heap? Applies when the compiler -+ // is storing x to the heap, where x->is_perm() is true. -+ virtual bool can_elide_permanent_oop_store_barriers() const; - - // Does this heap support heap inspection (+PrintClassHistogram?) - virtual bool supports_heap_inspection() const { -@@ -386,7 +407,7 @@ - // Returns "true" iff there is a stop-world GC in progress. (I assume - // that it should answer "false" for the concurrent part of a concurrent - // collector -- dld). -- bool is_gc_active() { return _is_gc_active; } -+ bool is_gc_active() const { return _is_gc_active; } - - // Total number of GC collections (started) - unsigned int total_collections() const { return _total_collections; } -diff -ruNb openjdk6/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp openjdk/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp ---- openjdk6/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)collectedHeap.inline.hpp 1.46 07/05/17 15:52:59 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -292,7 +289,45 @@ - return (oop)obj; - } - -+// Returns "TRUE" if "p" is a method oop in the -+// current heap with high probability. NOTE: The main -+// current consumers of this interface are Forte:: -+// and ThreadProfiler::. In these cases, the -+// interpreter frame from which "p" came, may be -+// under construction when sampled asynchronously, so -+// the clients want to check that it represents a -+// valid method before using it. Nonetheless since -+// the clients do not typically lock out GC, the -+// predicate is_valid_method() is not stable, so -+// it is possible that by the time "p" is used, it -+// is no longer valid. -+inline bool CollectedHeap::is_valid_method(oop p) const { -+ return -+ p != NULL && -+ -+ // Check whether it is aligned at a HeapWord boundary. -+ Space::is_aligned(p) && -+ -+ // Check whether "method" is in the allocated part of the -+ // permanent generation -- this needs to be checked before -+ // p->klass() below to avoid a SEGV (but see below -+ // for a potential window of vulnerability). -+ is_permanent((void*)p) && -+ -+ // See if GC is active; however, there is still an -+ // apparently unavoidable window after this call -+ // and before the client of this interface uses "p". -+ // If the client chooses not to lock out GC, then -+ // it's a risk the client must accept. -+ !is_gc_active() && -+ -+ // Check that p is a methodOop. -+ p->klass() == Universe::methodKlassObj(); -+} -+ -+ - #ifndef PRODUCT -+ - inline bool - CollectedHeap::promotion_should_fail(volatile size_t* count) { - // Access to count is not atomic; the value does not have to be exact. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_interface/gcCause.cpp openjdk/hotspot/src/share/vm/gc_interface/gcCause.cpp ---- openjdk6/hotspot/src/share/vm/gc_interface/gcCause.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_interface/gcCause.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)gcCause.cpp 1.20 07/05/05 17:05:40 JVM" --#endif - /* - * Copyright 2002-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/gc_interface/gcCause.hpp openjdk/hotspot/src/share/vm/gc_interface/gcCause.hpp ---- openjdk6/hotspot/src/share/vm/gc_interface/gcCause.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/gc_interface/gcCause.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)gcCause.hpp 1.24 07/05/05 17:05:40 JVM" --#endif - /* - * Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/includeDB_compiler1 openjdk/hotspot/src/share/vm/includeDB_compiler1 ---- openjdk6/hotspot/src/share/vm/includeDB_compiler1 2008-07-10 22:04:28.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/includeDB_compiler1 2007-12-14 08:57:02.000000000 +0100 -@@ -281,7 +281,7 @@ - c1_LinearScan_.hpp generate_platform_dependent_include - - c1_MacroAssembler.hpp assembler.hpp --c1_MacroAssembler.hpp assembler_.inline.hpp -+c1_MacroAssembler.hpp assembler_.inline.hpp - - c1_MacroAssembler_.cpp arrayOop.hpp - c1_MacroAssembler_.cpp biasedLocking.hpp -@@ -326,7 +326,7 @@ - c1_Runtime1.cpp disassembler_.hpp - c1_Runtime1.cpp events.hpp - c1_Runtime1.cpp interfaceSupport.hpp --c1_Runtime1.cpp interpreter_.hpp -+c1_Runtime1.cpp interpreter.hpp - c1_Runtime1.cpp javaCalls.hpp - c1_Runtime1.cpp objArrayKlass.hpp - c1_Runtime1.cpp oop.inline.hpp -@@ -352,7 +352,7 @@ - c1_Runtime1_.cpp c1_MacroAssembler.hpp - c1_Runtime1_.cpp c1_Runtime1.hpp - c1_Runtime1_.cpp compiledICHolderOop.hpp --c1_Runtime1_.cpp interpreter_.hpp -+c1_Runtime1_.cpp interpreter.hpp - c1_Runtime1_.cpp jvmtiExport.hpp - c1_Runtime1_.cpp nativeInst_.hpp - c1_Runtime1_.cpp oop.inline.hpp -@@ -395,8 +395,6 @@ - - compileBroker.cpp c1_Compiler.hpp - --fprofiler.cpp c1_Compiler.hpp -- - frame.hpp c1_Defs.hpp - - frame_.cpp c1_Runtime1.hpp -@@ -408,7 +406,7 @@ - - instanceKlass.cpp c1_Compiler.hpp - --interpreter_.cpp c1_Runtime1.hpp -+interpreter_.cpp c1_Runtime1.hpp - - java.cpp c1_Compiler.hpp - java.cpp c1_Runtime1.hpp -@@ -419,7 +417,7 @@ - - os_.cpp c1_Runtime1.hpp - --os__.cpp c1_Runtime1.hpp -+os_.cpp c1_Runtime1.hpp - - registerMap.hpp c1_Defs.hpp - -@@ -427,12 +425,11 @@ - - sharedRuntime.cpp c1_Runtime1.hpp - --sharedRuntime_.cpp c1_Runtime1.hpp -+sharedRuntime_.cpp c1_Runtime1.hpp - - thread.cpp c1_Compiler.hpp - - top.hpp c1_globals.hpp - --vmStructs.cpp c1_Defs.hpp --vmStructs.cpp c1_Runtime1.hpp -+vmStructs.hpp c1_Runtime1.hpp - -diff -ruNb openjdk6/hotspot/src/share/vm/includeDB_compiler2 openjdk/hotspot/src/share/vm/includeDB_compiler2 ---- openjdk6/hotspot/src/share/vm/includeDB_compiler2 2008-07-10 22:04:28.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/includeDB_compiler2 2007-12-14 08:57:02.000000000 +0100 -@@ -22,55 +22,55 @@ - // - // - --ad_.cpp adGlobals_.hpp --ad_.cpp ad_.hpp --ad_.cpp allocation.inline.hpp --ad_.cpp assembler.hpp --ad_.cpp assembler_.inline.hpp --ad_.cpp biasedLocking.hpp --ad_.cpp cfgnode.hpp --ad_.cpp collectedHeap.inline.hpp --ad_.cpp compiledICHolderOop.hpp --ad_.cpp growableArray.hpp --ad_.cpp locknode.hpp --ad_.cpp markOop.hpp --ad_.cpp methodOop.hpp --ad_.cpp nativeInst_.hpp --ad_.cpp oop.inline.hpp --ad_.cpp oop.inline2.hpp --ad_.cpp opcodes.hpp --ad_.cpp regalloc.hpp --ad_.cpp regmask.hpp --ad_.cpp runtime.hpp --ad_.cpp sharedRuntime.hpp --ad_.cpp stubRoutines.hpp --ad_.cpp vmreg.hpp --ad_.cpp vmreg_.inline.hpp -- --ad_.hpp addnode.hpp --ad_.hpp machnode.hpp --ad_.hpp matcher.hpp --ad_.hpp opcodes.hpp --ad_.hpp regalloc.hpp --ad_.hpp resourceArea.hpp --ad_.hpp subnode.hpp --ad_.hpp vectornode.hpp -- --ad__clone.cpp ad_.hpp -- --ad__expand.cpp ad_.hpp -- --ad__format.cpp ad_.hpp -- --ad__gen.cpp ad_.hpp --ad__gen.cpp cfgnode.hpp --ad__gen.cpp locknode.hpp -+ad_.cpp adGlobals_.hpp -+ad_.cpp ad_.hpp -+ad_.cpp allocation.inline.hpp -+ad_.cpp assembler.hpp -+ad_.cpp assembler_.inline.hpp -+ad_.cpp biasedLocking.hpp -+ad_.cpp cfgnode.hpp -+ad_.cpp collectedHeap.inline.hpp -+ad_.cpp compiledICHolderOop.hpp -+ad_.cpp growableArray.hpp -+ad_.cpp locknode.hpp -+ad_.cpp markOop.hpp -+ad_.cpp methodOop.hpp -+ad_.cpp nativeInst_.hpp -+ad_.cpp oop.inline.hpp -+ad_.cpp oop.inline2.hpp -+ad_.cpp opcodes.hpp -+ad_.cpp regalloc.hpp -+ad_.cpp regmask.hpp -+ad_.cpp runtime.hpp -+ad_.cpp sharedRuntime.hpp -+ad_.cpp stubRoutines.hpp -+ad_.cpp vmreg.hpp -+ad_.cpp vmreg_.inline.hpp -+ -+ad_.hpp addnode.hpp -+ad_.hpp machnode.hpp -+ad_.hpp matcher.hpp -+ad_.hpp opcodes.hpp -+ad_.hpp regalloc.hpp -+ad_.hpp resourceArea.hpp -+ad_.hpp subnode.hpp -+ad_.hpp vectornode.hpp -+ -+ad__clone.cpp ad_.hpp -+ -+ad__expand.cpp ad_.hpp -+ -+ad__format.cpp ad_.hpp -+ -+ad__gen.cpp ad_.hpp -+ad__gen.cpp cfgnode.hpp -+ad__gen.cpp locknode.hpp - --ad__misc.cpp ad_.hpp -+ad__misc.cpp ad_.hpp - --ad__peephole.cpp ad_.hpp -+ad__peephole.cpp ad_.hpp - --ad__pipeline.cpp ad_.hpp -+ad__pipeline.cpp ad_.hpp - - addnode.cpp addnode.hpp - addnode.cpp allocation.inline.hpp -@@ -125,6 +125,8 @@ - bytecodeInfo.cpp systemDictionary.hpp - bytecodeInfo.cpp vmSymbols.hpp - -+bytecodeInterpreter.hpp methodDataOop.hpp -+ - c2_globals.cpp c2_globals.hpp - - c2_globals.hpp c2_globals_.hpp -@@ -139,14 +141,12 @@ - - c2_init_.cpp compile.hpp - --c2compiler.cpp ad_.hpp -+c2compiler.cpp ad_.hpp - c2compiler.cpp c2compiler.hpp - c2compiler.cpp runtime.hpp - - c2compiler.hpp abstractCompiler.hpp - --cInterpreter.hpp methodDataOop.hpp -- - callGenerator.cpp addnode.hpp - callGenerator.cpp callGenerator.hpp - callGenerator.cpp callnode.hpp -@@ -287,7 +287,7 @@ - - coalesce.hpp phase.hpp - --compile.cpp ad_.hpp -+compile.cpp ad_.hpp - compile.cpp addnode.hpp - compile.cpp arguments.hpp - compile.cpp assembler.hpp -@@ -333,6 +333,7 @@ - compile.hpp deoptimization.hpp - compile.hpp dict.hpp - compile.hpp exceptionHandlerTable.hpp -+compile.hpp idealGraphPrinter.hpp - compile.hpp phase.hpp - compile.hpp port.hpp - compile.hpp regmask.hpp -@@ -358,11 +359,11 @@ - connode.hpp opcodes.hpp - connode.hpp type.hpp - --deoptimization.cpp ad_.hpp -+deoptimization.cpp ad_.hpp - --dfa_.cpp ad_.hpp --dfa_.cpp matcher.hpp --dfa_.cpp opcodes.hpp -+dfa_.cpp ad_.hpp -+dfa_.cpp matcher.hpp -+dfa_.cpp opcodes.hpp - - dict.cpp allocation.inline.hpp - dict.cpp dict.hpp -@@ -389,7 +390,6 @@ - doCall.cpp addnode.hpp - doCall.cpp callGenerator.hpp - doCall.cpp cfgnode.hpp --doCall.cpp cha.hpp - doCall.cpp compileLog.hpp - doCall.cpp linkResolver.hpp - doCall.cpp mulnode.hpp -@@ -422,9 +422,9 @@ - escape.hpp growableArray.hpp - escape.hpp node.hpp - --frame.hpp adGlobals_.hpp -+frame.hpp adGlobals_.hpp - --gcm.cpp ad_.hpp -+gcm.cpp ad_.hpp - gcm.cpp allocation.inline.hpp - gcm.cpp block.hpp - gcm.cpp c2compiler.hpp -@@ -481,9 +481,11 @@ - graphKit.hpp type.hpp - - idealKit.cpp addnode.hpp -+idealKit.cpp callnode.hpp - idealKit.cpp cfgnode.hpp - idealKit.cpp idealKit.hpp - -+idealKit.hpp connode.hpp - idealKit.hpp mulnode.hpp - idealKit.hpp phaseX.hpp - idealKit.hpp subnode.hpp -@@ -530,7 +532,7 @@ - java.cpp methodLiveness.hpp - java.cpp runtime.hpp - --lcm.cpp ad_.hpp -+lcm.cpp ad_.hpp - lcm.cpp allocation.inline.hpp - lcm.cpp block.hpp - lcm.cpp c2compiler.hpp -@@ -572,7 +574,7 @@ - locknode.cpp rootnode.hpp - locknode.cpp runtime.hpp - --locknode.hpp ad_.hpp -+locknode.hpp ad_.hpp - locknode.hpp node.hpp - locknode.hpp opcodes.hpp - locknode.hpp subnode.hpp -@@ -647,7 +649,7 @@ - macro.cpp vectset.hpp - macro.hpp phase.hpp - --matcher.cpp ad_.hpp -+matcher.cpp ad_.hpp - matcher.cpp addnode.hpp - matcher.cpp allocation.inline.hpp - matcher.cpp atomic.hpp -@@ -762,7 +764,7 @@ - output.cpp type.hpp - output.cpp xmlstream.hpp - --output.hpp ad_.hpp -+output.hpp ad_.hpp - output.hpp block.hpp - output.hpp node.hpp - -@@ -881,11 +883,11 @@ - regalloc.hpp phase.hpp - regalloc.hpp vmreg.hpp - --regmask.cpp ad_.hpp -+regmask.cpp ad_.hpp - regmask.cpp compile.hpp - regmask.cpp regmask.hpp - --regmask.hpp adGlobals_.hpp -+regmask.hpp adGlobals_.hpp - regmask.hpp optoreg.hpp - regmask.hpp port.hpp - regmask.hpp vmreg.hpp -@@ -901,7 +903,7 @@ - - rootnode.hpp loopnode.hpp - --runtime.cpp ad_.hpp -+runtime.cpp ad_.hpp - runtime.cpp addnode.hpp - runtime.cpp barrierSet.hpp - runtime.cpp bytecode.hpp -@@ -953,21 +955,21 @@ - runtime.hpp type.hpp - runtime.hpp vframe.hpp - --runtime_.cpp adGlobals_.hpp --runtime_.cpp ad_.hpp --runtime_.cpp assembler.hpp --runtime_.cpp assembler_.inline.hpp --runtime_.cpp globalDefinitions.hpp --runtime_.cpp interfaceSupport.hpp --runtime_.cpp interpreter_.hpp --runtime_.cpp nativeInst_.hpp --runtime_.cpp runtime.hpp --runtime_.cpp sharedRuntime.hpp --runtime_.cpp stubRoutines.hpp --runtime_.cpp systemDictionary.hpp --runtime_.cpp vframeArray.hpp --runtime_.cpp vmreg.hpp --runtime_.cpp vmreg_.inline.hpp -+runtime_.cpp adGlobals_.hpp -+runtime_.cpp ad_.hpp -+runtime_.cpp assembler.hpp -+runtime_.cpp assembler_.inline.hpp -+runtime_.cpp globalDefinitions.hpp -+runtime_.cpp interfaceSupport.hpp -+runtime_.cpp interpreter.hpp -+runtime_.cpp nativeInst_.hpp -+runtime_.cpp runtime.hpp -+runtime_.cpp sharedRuntime.hpp -+runtime_.cpp stubRoutines.hpp -+runtime_.cpp systemDictionary.hpp -+runtime_.cpp vframeArray.hpp -+runtime_.cpp vmreg.hpp -+runtime_.cpp vmreg_.inline.hpp - - set.cpp allocation.inline.hpp - set.cpp set.hpp -@@ -975,16 +977,14 @@ - set.hpp allocation.hpp - set.hpp port.hpp - --sharedRuntime_.cpp runtime.hpp -+sharedRuntime_.cpp runtime.hpp - - split_if.cpp allocation.inline.hpp - split_if.cpp callnode.hpp - split_if.cpp connode.hpp - split_if.cpp loopnode.hpp - --stackValue.cpp debugInfo.hpp -- --stubGenerator_.cpp runtime.hpp -+stubGenerator_.cpp runtime.hpp - - stubRoutines.cpp runtime.hpp - -@@ -1025,8 +1025,6 @@ - superword.hpp phaseX.hpp - superword.hpp vectornode.hpp - --systemDictionary.cpp cha.hpp -- - thread.cpp c2compiler.hpp - - top.hpp c2_globals.hpp -@@ -1070,15 +1068,34 @@ - - vframe_hp.cpp matcher.hpp - --vmStructs.cpp adGlobals_.hpp -+vmStructs.cpp adGlobals_.hpp - vmStructs.cpp matcher.hpp - --vmreg.hpp adGlobals_.hpp -+vmreg.hpp adGlobals_.hpp - vmreg.hpp adlcVMDeps.hpp - vmreg.hpp ostream.hpp - - vtableStubs.cpp matcher.hpp - --vtableStubs_.cpp ad_.hpp --vtableStubs_.cpp runtime.hpp -+vtableStubs_.cpp ad_.hpp -+vtableStubs_.cpp runtime.hpp - -+idealGraphPrinter.hpp dict.hpp -+idealGraphPrinter.hpp vectset.hpp -+idealGraphPrinter.hpp growableArray.hpp -+idealGraphPrinter.hpp ostream.hpp -+ -+idealGraphPrinter.cpp idealGraphPrinter.hpp -+idealGraphPrinter.cpp chaitin.hpp -+idealGraphPrinter.cpp machnode.hpp -+idealGraphPrinter.cpp parse.hpp -+idealGraphPrinter.cpp threadCritical.hpp -+ -+compile.cpp idealGraphPrinter.hpp -+thread.cpp idealGraphPrinter.hpp -+phaseX.cpp idealGraphPrinter.hpp -+parse2.cpp idealGraphPrinter.hpp -+parse1.cpp idealGraphPrinter.hpp -+matcher.cpp idealGraphPrinter.hpp -+loopnode.cpp idealGraphPrinter.hpp -+chaitin.cpp idealGraphPrinter.hpp -diff -ruNb openjdk6/hotspot/src/share/vm/includeDB_core openjdk/hotspot/src/share/vm/includeDB_core ---- openjdk6/hotspot/src/share/vm/includeDB_core 2008-07-10 22:04:29.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/includeDB_core 2007-12-14 08:57:02.000000000 +0100 -@@ -47,7 +47,7 @@ - // bodies for inline functions declared in H.hpp. - // - // NOTE: Files that use the token "generate_platform_dependent_include" --// are expected to contain macro references like , , ... and -+// are expected to contain macro references like , , ... and - // makedeps has a dependency on these platform files looking like: - // foo_.trailing_string - // (where "trailing_string" can be any legal filename strings but typically -@@ -120,6 +120,13 @@ - - abstractCompiler.hpp compilerInterface.hpp - -+abstractInterpreter.hpp bytecodes.hpp -+abstractInterpreter.hpp interp_masm_.hpp -+abstractInterpreter.hpp stubs.hpp -+abstractInterpreter.hpp thread_.inline.hpp -+abstractInterpreter.hpp top.hpp -+abstractInterpreter.hpp vmThread.hpp -+ - accessFlags.cpp accessFlags.hpp - accessFlags.cpp oop.inline.hpp - accessFlags.cpp os_.inline.hpp -@@ -175,7 +182,7 @@ - arguments.cpp oop.inline.hpp - arguments.cpp os_.inline.hpp - arguments.cpp universe.inline.hpp --arguments.cpp vm_version_.hpp -+arguments.cpp vm_version_.hpp - - arguments.hpp perfData.hpp - arguments.hpp top.hpp -@@ -226,7 +233,7 @@ - - assembler.cpp assembler.hpp - assembler.cpp assembler.inline.hpp --assembler.cpp assembler_.inline.hpp -+assembler.cpp assembler_.inline.hpp - assembler.cpp codeBuffer.hpp - assembler.cpp icache.hpp - assembler.cpp os.hpp -@@ -239,36 +246,36 @@ - assembler.hpp register_.hpp - assembler.hpp relocInfo.hpp - assembler.hpp top.hpp --assembler.hpp vm_version_.hpp -+assembler.hpp vm_version_.hpp - - assembler.inline.hpp assembler.hpp - assembler.inline.hpp codeBuffer.hpp - assembler.inline.hpp disassembler_.hpp - assembler.inline.hpp threadLocalStorage.hpp - --assembler_.cpp assembler_.inline.hpp --assembler_.cpp biasedLocking.hpp --assembler_.cpp cardTableModRefBS.hpp --assembler_.cpp collectedHeap.hpp --assembler_.cpp interfaceSupport.hpp --assembler_.cpp interpreter_.hpp --assembler_.cpp objectMonitor.hpp --assembler_.cpp os.hpp --assembler_.cpp resourceArea.hpp --assembler_.cpp sharedRuntime.hpp --assembler_.cpp stubRoutines.hpp -- --assembler_.hpp generate_platform_dependent_include -- --assembler_.inline.hpp assembler.inline.hpp --assembler_.inline.hpp codeBuffer.hpp --assembler_.inline.hpp codeCache.hpp --assembler_.inline.hpp handles.inline.hpp -- --assembler_.cpp assembler.hpp --assembler_.cpp assembler_.inline.hpp --assembler_.cpp os.hpp --assembler_.cpp threadLocalStorage.hpp -+assembler_.cpp assembler_.inline.hpp -+assembler_.cpp biasedLocking.hpp -+assembler_.cpp cardTableModRefBS.hpp -+assembler_.cpp collectedHeap.hpp -+assembler_.cpp interfaceSupport.hpp -+assembler_.cpp interpreter.hpp -+assembler_.cpp objectMonitor.hpp -+assembler_.cpp os.hpp -+assembler_.cpp resourceArea.hpp -+assembler_.cpp sharedRuntime.hpp -+assembler_.cpp stubRoutines.hpp -+ -+assembler_.hpp generate_platform_dependent_include -+ -+assembler_.inline.hpp assembler.inline.hpp -+assembler_.inline.hpp codeBuffer.hpp -+assembler_.inline.hpp codeCache.hpp -+assembler_.inline.hpp handles.inline.hpp -+ -+assembler_.cpp assembler.hpp -+assembler_.cpp assembler_.inline.hpp -+assembler_.cpp os.hpp -+assembler_.cpp threadLocalStorage.hpp - - atomic.cpp atomic.hpp - atomic.cpp atomic_.inline.hpp -@@ -278,30 +285,14 @@ - - atomic_.inline.hpp atomic.hpp - atomic_.inline.hpp os.hpp --atomic_.inline.hpp vm_version_.hpp -+atomic_.inline.hpp vm_version_.hpp - --attachListener.cpp arguments.hpp --attachListener.cpp attachListener.hpp --attachListener.cpp globals.hpp --attachListener.cpp heapDumper.hpp --attachListener.cpp java.hpp --attachListener.cpp javaCalls.hpp --attachListener.cpp javaClasses.hpp --attachListener.cpp jvmtiExport.hpp --attachListener.cpp os.hpp --attachListener.cpp resourceArea.hpp --attachListener.cpp systemDictionary.hpp --attachListener.cpp vmGCOperations.hpp -+// attachListener is jck optional, put cpp deps in includeDB_features - - attachListener.hpp allocation.hpp - attachListener.hpp debug.hpp - attachListener.hpp ostream.hpp - --attachListener_.cpp attachListener.hpp --attachListener_.cpp dtraceAttacher.hpp --attachListener_.cpp interfaceSupport.hpp --attachListener_.cpp os.hpp -- - barrierSet.hpp memRegion.hpp - barrierSet.hpp oopsHierarchy.hpp - -@@ -384,6 +375,64 @@ - bytecodeHistogram.hpp allocation.hpp - bytecodeHistogram.hpp bytecodes.hpp - -+bytecodeInterpreter.cpp no_precompiled_headers -+bytecodeInterpreter.cpp bytecodeHistogram.hpp -+bytecodeInterpreter.cpp bytecodeInterpreter.hpp -+bytecodeInterpreter.cpp bytecodeInterpreter.inline.hpp -+bytecodeInterpreter.cpp cardTableModRefBS.hpp -+bytecodeInterpreter.cpp collectedHeap.hpp -+bytecodeInterpreter.cpp exceptions.hpp -+bytecodeInterpreter.cpp frame.inline.hpp -+bytecodeInterpreter.cpp handles.inline.hpp -+bytecodeInterpreter.cpp interfaceSupport.hpp -+bytecodeInterpreter.cpp interpreterRuntime.hpp -+bytecodeInterpreter.cpp interpreter.hpp -+bytecodeInterpreter.cpp jvmtiExport.hpp -+bytecodeInterpreter.cpp objArrayKlass.hpp -+bytecodeInterpreter.cpp oop.inline.hpp -+bytecodeInterpreter.cpp orderAccess_.inline.hpp -+bytecodeInterpreter.cpp resourceArea.hpp -+bytecodeInterpreter.cpp sharedRuntime.hpp -+bytecodeInterpreter.cpp threadCritical.hpp -+bytecodeInterpreter.cpp vmSymbols.hpp -+ -+bytecodeInterpreter_.cpp assembler.hpp -+bytecodeInterpreter_.cpp bytecodeInterpreter.hpp -+bytecodeInterpreter_.cpp bytecodeInterpreter.inline.hpp -+bytecodeInterpreter_.cpp debug.hpp -+bytecodeInterpreter_.cpp deoptimization.hpp -+bytecodeInterpreter_.cpp frame.inline.hpp -+bytecodeInterpreter_.cpp interp_masm_.hpp -+bytecodeInterpreter_.cpp interpreterRuntime.hpp -+bytecodeInterpreter_.cpp interpreter.hpp -+bytecodeInterpreter_.cpp jvmtiExport.hpp -+bytecodeInterpreter_.cpp jvmtiThreadState.hpp -+bytecodeInterpreter_.cpp methodDataOop.hpp -+bytecodeInterpreter_.cpp methodOop.hpp -+bytecodeInterpreter_.cpp oop.inline.hpp -+bytecodeInterpreter_.cpp sharedRuntime.hpp -+bytecodeInterpreter_.cpp stubRoutines.hpp -+bytecodeInterpreter_.cpp synchronizer.hpp -+bytecodeInterpreter_.cpp vframeArray.hpp -+ -+bytecodeInterpreterWithChecks.cpp bytecodeInterpreter.cpp -+ -+bytecodeInterpreter.hpp allocation.hpp -+bytecodeInterpreter.hpp bytes_.hpp -+bytecodeInterpreter.hpp frame.hpp -+bytecodeInterpreter.hpp globalDefinitions.hpp -+bytecodeInterpreter.hpp globals.hpp -+bytecodeInterpreter.hpp methodDataOop.hpp -+bytecodeInterpreter.hpp methodOop.hpp -+bytecodeInterpreter.hpp synchronizer.hpp -+ -+bytecodeInterpreter.inline.hpp bytecodeInterpreter.hpp -+bytecodeInterpreter.inline.hpp stubRoutines.hpp -+ -+bytecodeInterpreter_.hpp generate_platform_dependent_include -+ -+bytecodeInterpreter_.inline.hpp generate_platform_dependent_include -+ - bytecodeStream.cpp bytecodeStream.hpp - bytecodeStream.cpp bytecodes.hpp - -@@ -421,45 +470,6 @@ - - bytes_.inline.hpp generate_platform_dependent_include - --cInterpretMethod.hpp interpreter_.hpp --cInterpretMethod.hpp threadLocalAllocBuffer.inline.hpp -- --cInterpreter.cpp bytecodeHistogram.hpp --cInterpreter.cpp cInterpretMethod.hpp --cInterpreter.cpp cInterpreter.hpp --cInterpreter.cpp cInterpreter.inline.hpp --cInterpreter.cpp cardTableModRefBS.hpp --cInterpreter.cpp collectedHeap.hpp --cInterpreter.cpp exceptions.hpp --cInterpreter.cpp frame.inline.hpp --cInterpreter.cpp handles.inline.hpp --cInterpreter.cpp interfaceSupport.hpp --cInterpreter.cpp interpreterRuntime.hpp --cInterpreter.cpp interpreter_.hpp --cInterpreter.cpp jvmtiExport.hpp --cInterpreter.cpp objArrayKlass.hpp --cInterpreter.cpp oop.inline.hpp --cInterpreter.cpp orderAccess_.inline.hpp --cInterpreter.cpp resourceArea.hpp --cInterpreter.cpp sharedRuntime.hpp --cInterpreter.cpp threadCritical.hpp --cInterpreter.cpp vmSymbols.hpp -- --cInterpreter.hpp allocation.hpp --cInterpreter.hpp bytes_.hpp --cInterpreter.hpp frame.hpp --cInterpreter.hpp globalDefinitions.hpp --cInterpreter.hpp globals.hpp --cInterpreter.hpp methodOop.hpp --cInterpreter.hpp synchronizer.hpp -- --cInterpreter.inline.hpp cInterpreter.hpp --cInterpreter.inline.hpp stubRoutines.hpp -- --cInterpreter_.hpp generate_platform_dependent_include -- --cInterpreter_.inline.hpp generate_platform_dependent_include -- - cardTableModRefBS.cpp allocation.inline.hpp - cardTableModRefBS.cpp cardTableModRefBS.hpp - cardTableModRefBS.cpp cardTableRS.hpp -@@ -487,19 +497,6 @@ - cardTableRS.hpp genRemSet.hpp - cardTableRS.hpp memRegion.hpp - --cha.cpp cha.hpp --cha.cpp instanceKlass.hpp --cha.cpp linkResolver.hpp --cha.cpp methodOop.hpp --cha.cpp oop.inline.hpp --cha.cpp systemDictionary.hpp --cha.cpp universe.inline.hpp -- --cha.hpp growableArray.hpp --cha.hpp handles.hpp --cha.hpp handles.inline.hpp --cha.hpp klassOop.hpp -- - ciArray.cpp ciArray.hpp - ciArray.cpp ciKlass.hpp - ciArray.cpp ciUtilities.hpp -@@ -654,7 +651,6 @@ - ciMethod.cpp abstractCompiler.hpp - ciMethod.cpp allocation.inline.hpp - ciMethod.cpp bcEscapeAnalyzer.hpp --ciMethod.cpp cha.hpp - ciMethod.cpp ciCallProfile.hpp - ciMethod.cpp ciExceptionHandler.hpp - ciMethod.cpp ciInstanceKlass.hpp -@@ -984,6 +980,8 @@ - codeCache.cpp allocation.inline.hpp - codeCache.cpp codeBlob.hpp - codeCache.cpp codeCache.hpp -+codeCache.cpp dependencies.hpp -+codeCache.cpp gcLocker.hpp - codeCache.cpp icache.hpp - codeCache.cpp iterator.hpp - codeCache.cpp java.hpp -@@ -1046,7 +1044,7 @@ - compilationPolicy.cpp frame.hpp - compilationPolicy.cpp globalDefinitions.hpp - compilationPolicy.cpp handles.inline.hpp --compilationPolicy.cpp interpreter_.hpp -+compilationPolicy.cpp interpreter.hpp - compilationPolicy.cpp methodDataOop.hpp - compilationPolicy.cpp methodOop.hpp - compilationPolicy.cpp nativeLookup.hpp -@@ -1104,7 +1102,7 @@ - compiledIC.cpp events.hpp - compiledIC.cpp icBuffer.hpp - compiledIC.cpp icache.hpp --compiledIC.cpp interpreter_.hpp -+compiledIC.cpp interpreter.hpp - compiledIC.cpp linkResolver.hpp - compiledIC.cpp methodOop.hpp - compiledIC.cpp nmethod.hpp -@@ -1275,7 +1273,7 @@ - cpCacheOop.cpp cpCacheOop.hpp - cpCacheOop.cpp handles.inline.hpp - cpCacheOop.cpp interpreter.hpp --cpCacheOop.cpp jvmtiRedefineClasses.hpp -+cpCacheOop.cpp jvmtiRedefineClassesTrace.hpp - cpCacheOop.cpp markSweep.hpp - cpCacheOop.cpp markSweep.inline.hpp - cpCacheOop.cpp objArrayOop.hpp -@@ -1287,6 +1285,39 @@ - cpCacheOop.hpp arrayOop.hpp - cpCacheOop.hpp bytecodes.hpp - -+cppInterpreter.cpp bytecodeInterpreter.hpp -+cppInterpreter.cpp interpreter.hpp -+cppInterpreter.cpp interpreterGenerator.hpp -+cppInterpreter.cpp interpreterRuntime.hpp -+ -+cppInterpreter.hpp abstractInterpreter.hpp -+ -+cppInterpreter_.cpp arguments.hpp -+cppInterpreter_.cpp arrayOop.hpp -+cppInterpreter_.cpp assembler.hpp -+cppInterpreter_.cpp bytecodeHistogram.hpp -+cppInterpreter_.cpp debug.hpp -+cppInterpreter_.cpp deoptimization.hpp -+cppInterpreter_.cpp frame.inline.hpp -+cppInterpreter_.cpp interpreterRuntime.hpp -+cppInterpreter_.cpp interpreter.hpp -+cppInterpreter_.cpp interpreterGenerator.hpp -+cppInterpreter_.cpp jvmtiExport.hpp -+cppInterpreter_.cpp jvmtiThreadState.hpp -+cppInterpreter_.cpp methodDataOop.hpp -+cppInterpreter_.cpp methodOop.hpp -+cppInterpreter_.cpp oop.inline.hpp -+cppInterpreter_.cpp sharedRuntime.hpp -+cppInterpreter_.cpp stubRoutines.hpp -+cppInterpreter_.cpp synchronizer.hpp -+cppInterpreter_.cpp cppInterpreter.hpp -+cppInterpreter_.cpp timer.hpp -+cppInterpreter_.cpp vframeArray.hpp -+ -+cppInterpreter_.hpp generate_platform_dependent_include -+ -+cppInterpreterGenerator_.hpp generate_platform_dependent_include -+ - debug.cpp arguments.hpp - debug.cpp bytecodeHistogram.hpp - debug.cpp codeCache.hpp -@@ -1298,7 +1329,7 @@ - debug.cpp frame.hpp - debug.cpp heapDumper.hpp - debug.cpp icBuffer.hpp --debug.cpp interpreter_.hpp -+debug.cpp interpreter.hpp - debug.cpp java.hpp - debug.cpp markSweep.hpp - debug.cpp nmethod.hpp -@@ -1433,7 +1464,7 @@ - dictionary.cpp classLoadingService.hpp - dictionary.cpp dictionary.hpp - dictionary.cpp hashtable.inline.hpp --dictionary.cpp jvmtiRedefineClasses.hpp -+dictionary.cpp jvmtiRedefineClassesTrace.hpp - dictionary.cpp oop.inline.hpp - dictionary.cpp systemDictionary.hpp - -@@ -1465,24 +1496,7 @@ - dtraceAttacher.cpp vmThread.hpp - dtraceAttacher.cpp vm_operations.hpp - --dump.cpp classify.hpp --dump.cpp copy.hpp --dump.cpp filemap.hpp --dump.cpp javaCalls.hpp --dump.cpp javaClasses.hpp --dump.cpp loaderConstraints.hpp --dump.cpp methodDataOop.hpp --dump.cpp oop.hpp --dump.cpp oopFactory.hpp --dump.cpp resourceArea.hpp --dump.cpp signature.hpp --dump.cpp symbolTable.hpp --dump.cpp systemDictionary.hpp --dump.cpp vmThread.hpp --dump.cpp vm_operations.hpp -- --dump_.cpp assembler_.inline.hpp --dump_.cpp compactingPermGenGen.hpp -+// dump is jck optional, put cpp deps in includeDB_features - - events.cpp allocation.inline.hpp - events.cpp events.hpp -@@ -1559,34 +1573,8 @@ - filemap.hpp compactingPermGenGen.hpp - filemap.hpp space.hpp - --forte.cpp collectedHeap.inline.hpp --forte.cpp debugInfoRec.hpp --forte.cpp forte.hpp --forte.cpp oop.inline.hpp --forte.cpp oop.inline2.hpp --forte.cpp pcDesc.hpp --forte.cpp space.hpp --forte.cpp thread.hpp --forte.cpp universe.inline.hpp --forte.cpp vframe.hpp --forte.cpp vframeArray.hpp -- --fprofiler.cpp allocation.inline.hpp --fprofiler.cpp classLoader.hpp --fprofiler.cpp collectedHeap.inline.hpp --fprofiler.cpp deoptimization.hpp --fprofiler.cpp fprofiler.hpp --fprofiler.cpp interpreter_.hpp --fprofiler.cpp mutexLocker.hpp --fprofiler.cpp oop.inline.hpp --fprofiler.cpp oop.inline2.hpp --fprofiler.cpp stubCodeGenerator.hpp --fprofiler.cpp stubRoutines.hpp --fprofiler.cpp symbolOop.hpp --fprofiler.cpp task.hpp --fprofiler.cpp universe.inline.hpp --fprofiler.cpp vframe.hpp --fprofiler.cpp vtableStubs.hpp -+// forte is jck optional, put cpp deps in includeDB_features -+// fprofiler is jck optional, put cpp deps in includeDB_features - - fprofiler.hpp thread_.inline.hpp - fprofiler.hpp timer.hpp -@@ -1594,8 +1582,7 @@ - frame.cpp collectedHeap.inline.hpp - frame.cpp frame.inline.hpp - frame.cpp handles.inline.hpp --frame.cpp init.hpp --frame.cpp interpreter_.hpp -+frame.cpp interpreter.hpp - frame.cpp javaCalls.hpp - frame.cpp markOop.hpp - frame.cpp methodDataOop.hpp -@@ -1620,8 +1607,8 @@ - frame.hpp synchronizer.hpp - frame.hpp top.hpp - --frame.inline.hpp cInterpreter.hpp --frame.inline.hpp cInterpreter.inline.hpp -+frame.inline.hpp bytecodeInterpreter.hpp -+frame.inline.hpp bytecodeInterpreter.inline.hpp - frame.inline.hpp frame.hpp - frame.inline.hpp interpreter.hpp - frame.inline.hpp jniTypes_.hpp -@@ -1630,7 +1617,7 @@ - - frame_.cpp frame.inline.hpp - frame_.cpp handles.inline.hpp --frame_.cpp interpreter_.hpp -+frame_.cpp interpreter.hpp - frame_.cpp javaCalls.hpp - frame_.cpp markOop.hpp - frame_.cpp methodOop.hpp -@@ -1871,33 +1858,14 @@ - heap.hpp allocation.hpp - heap.hpp virtualspace.hpp - --heapDumper.cpp genCollectedHeap.hpp --heapDumper.cpp heapDumper.hpp --heapDumper.cpp javaCalls.hpp --heapDumper.cpp jniHandles.hpp --heapDumper.cpp objArrayKlass.hpp --heapDumper.cpp ostream.hpp --heapDumper.cpp reflectionUtils.hpp --heapDumper.cpp symbolTable.hpp --heapDumper.cpp systemDictionary.hpp --heapDumper.cpp universe.hpp --heapDumper.cpp vframe.hpp --heapDumper.cpp vmSymbols.hpp --heapDumper.cpp vmThread.hpp --heapDumper.cpp vm_operations.hpp -+// heapDumper is jck optional, put cpp deps in includeDB_features - - heapDumper.hpp allocation.hpp - heapDumper.hpp klassOop.hpp - heapDumper.hpp oop.hpp - heapDumper.hpp os.hpp - --heapInspection.cpp collectedHeap.hpp --heapInspection.cpp genCollectedHeap.hpp --heapInspection.cpp globalDefinitions.hpp --heapInspection.cpp heapInspection.hpp --heapInspection.cpp klassOop.hpp --heapInspection.cpp os.hpp --heapInspection.cpp resourceArea.hpp -+// heapInspection is jck optional, put cpp deps in includeDB_features - - heapInspection.hpp allocation.inline.hpp - heapInspection.hpp oop.inline.hpp -@@ -1924,11 +1892,11 @@ - - hpi_imported.h jni.h - --icBuffer.cpp assembler_.inline.hpp -+icBuffer.cpp assembler_.inline.hpp - icBuffer.cpp collectedHeap.inline.hpp - icBuffer.cpp compiledIC.hpp - icBuffer.cpp icBuffer.hpp --icBuffer.cpp interpreter_.hpp -+icBuffer.cpp interpreter.hpp - icBuffer.cpp linkResolver.hpp - icBuffer.cpp methodOop.hpp - icBuffer.cpp mutexLocker.hpp -@@ -1945,7 +1913,7 @@ - icBuffer.hpp stubs.hpp - - icBuffer_.cpp assembler.hpp --icBuffer_.cpp assembler_.inline.hpp -+icBuffer_.cpp assembler_.inline.hpp - icBuffer_.cpp bytecodes.hpp - icBuffer_.cpp collectedHeap.inline.hpp - icBuffer_.cpp icBuffer.hpp -@@ -1960,13 +1928,14 @@ - icache.hpp allocation.hpp - icache.hpp stubCodeGenerator.hpp - --icache_.cpp assembler_.inline.hpp -+icache_.cpp assembler_.inline.hpp - icache_.cpp icache.hpp - - icache_.hpp generate_platform_dependent_include - - init.cpp bytecodes.hpp - init.cpp collectedHeap.hpp -+init.cpp handles.inline.hpp - init.cpp icBuffer.hpp - init.cpp icache.hpp - init.cpp init.hpp -@@ -1987,7 +1956,7 @@ - instanceKlass.cpp javaClasses.hpp - instanceKlass.cpp jvmti.h - instanceKlass.cpp jvmtiExport.hpp --instanceKlass.cpp jvmtiRedefineClasses.hpp -+instanceKlass.cpp jvmtiRedefineClassesTrace.hpp - instanceKlass.cpp methodOop.hpp - instanceKlass.cpp mutexLocker.hpp - instanceKlass.cpp objArrayKlassKlass.hpp -@@ -2076,33 +2045,33 @@ - - interfaceSupport_.hpp generate_platform_dependent_include - --interp_masm_.cpp arrayOop.hpp --interp_masm_.cpp biasedLocking.hpp --interp_masm_.cpp interp_masm_.hpp --interp_masm_.cpp interpreterRuntime.hpp --interp_masm_.cpp interpreter_.hpp --interp_masm_.cpp jvmtiExport.hpp --interp_masm_.cpp jvmtiThreadState.hpp --interp_masm_.cpp markOop.hpp --interp_masm_.cpp methodDataOop.hpp --interp_masm_.cpp methodOop.hpp --interp_masm_.cpp sharedRuntime.hpp --interp_masm_.cpp synchronizer.hpp --interp_masm_.cpp thread_.inline.hpp -+interp_masm_.cpp arrayOop.hpp -+interp_masm_.cpp biasedLocking.hpp -+interp_masm_.cpp interp_masm_.hpp -+interp_masm_.cpp interpreterRuntime.hpp -+interp_masm_.cpp interpreter.hpp -+interp_masm_.cpp jvmtiExport.hpp -+interp_masm_.cpp jvmtiThreadState.hpp -+interp_masm_.cpp markOop.hpp -+interp_masm_.cpp methodDataOop.hpp -+interp_masm_.cpp methodOop.hpp -+interp_masm_.cpp sharedRuntime.hpp -+interp_masm_.cpp synchronizer.hpp -+interp_masm_.cpp thread_.inline.hpp - --interp_masm_.hpp assembler_.inline.hpp --interp_masm_.hpp invocationCounter.hpp -+interp_masm_.hpp assembler_.inline.hpp -+interp_masm_.hpp invocationCounter.hpp - - interpreter.cpp allocation.inline.hpp - interpreter.cpp arrayOop.hpp - interpreter.cpp assembler.hpp - interpreter.cpp bytecodeHistogram.hpp --interpreter.cpp cInterpreter.hpp -+interpreter.cpp bytecodeInterpreter.hpp - interpreter.cpp forte.hpp - interpreter.cpp handles.inline.hpp - interpreter.cpp interpreter.hpp - interpreter.cpp interpreterRuntime.hpp --interpreter.cpp interpreter_.hpp -+interpreter.cpp interpreter.hpp - interpreter.cpp jvmtiExport.hpp - interpreter.cpp methodDataOop.hpp - interpreter.cpp methodOop.hpp -@@ -2114,25 +2083,20 @@ - interpreter.cpp timer.hpp - interpreter.cpp vtune.hpp - --interpreter.hpp bytecodes.hpp --interpreter.hpp cInterpreter.hpp --interpreter.hpp interp_masm_.hpp -+interpreter.hpp cppInterpreter.hpp - interpreter.hpp stubs.hpp --interpreter.hpp templateTable.hpp --interpreter.hpp thread_.inline.hpp --interpreter.hpp top.hpp --interpreter.hpp vmThread.hpp -- --interpreterRT_.cpp allocation.inline.hpp --interpreterRT_.cpp handles.inline.hpp --interpreterRT_.cpp icache.hpp --interpreterRT_.cpp interfaceSupport.hpp --interpreterRT_.cpp interpreterRuntime.hpp --interpreterRT_.cpp interpreter_.hpp --interpreterRT_.cpp methodOop.hpp --interpreterRT_.cpp oop.inline.hpp --interpreterRT_.cpp signature.hpp --interpreterRT_.cpp universe.inline.hpp -+interpreter.hpp templateInterpreter.hpp -+ -+interpreterRT_.cpp allocation.inline.hpp -+interpreterRT_.cpp handles.inline.hpp -+interpreterRT_.cpp icache.hpp -+interpreterRT_.cpp interfaceSupport.hpp -+interpreterRT_.cpp interpreterRuntime.hpp -+interpreterRT_.cpp interpreter.hpp -+interpreterRT_.cpp methodOop.hpp -+interpreterRT_.cpp oop.inline.hpp -+interpreterRT_.cpp signature.hpp -+interpreterRT_.cpp universe.inline.hpp - - interpreterRT_.hpp allocation.hpp - interpreterRT_.hpp generate_platform_dependent_include -@@ -2149,7 +2113,7 @@ - interpreterRuntime.cpp instanceKlass.hpp - interpreterRuntime.cpp interfaceSupport.hpp - interpreterRuntime.cpp interpreterRuntime.hpp --interpreterRuntime.cpp interpreter_.hpp -+interpreterRuntime.cpp interpreter.hpp - interpreterRuntime.cpp java.hpp - interpreterRuntime.cpp jfieldIDWorkaround.hpp - interpreterRuntime.cpp jvmtiExport.hpp -@@ -2169,7 +2133,7 @@ - interpreterRuntime.cpp threadCritical.hpp - interpreterRuntime.cpp universe.inline.hpp - interpreterRuntime.cpp vmSymbols.hpp --interpreterRuntime.cpp vm_version_.hpp -+interpreterRuntime.cpp vm_version_.hpp - - interpreterRuntime.hpp bytecode.hpp - interpreterRuntime.hpp frame.inline.hpp -@@ -2180,29 +2144,36 @@ - interpreterRuntime.hpp top.hpp - interpreterRuntime.hpp universe.hpp - --interpreter_.cpp arguments.hpp --interpreter_.cpp arrayOop.hpp --interpreter_.cpp assembler.hpp --interpreter_.cpp bytecodeHistogram.hpp --interpreter_.cpp debug.hpp --interpreter_.cpp deoptimization.hpp --interpreter_.cpp frame.inline.hpp --interpreter_.cpp interpreterRuntime.hpp --interpreter_.cpp interpreter_.hpp --interpreter_.cpp jvmtiExport.hpp --interpreter_.cpp jvmtiThreadState.hpp --interpreter_.cpp methodDataOop.hpp --interpreter_.cpp methodOop.hpp --interpreter_.cpp oop.inline.hpp --interpreter_.cpp sharedRuntime.hpp --interpreter_.cpp stubRoutines.hpp --interpreter_.cpp synchronizer.hpp --interpreter_.cpp templateTable.hpp --interpreter_.cpp timer.hpp --interpreter_.cpp vframeArray.hpp -+interpreter_.cpp arguments.hpp -+interpreter_.cpp arrayOop.hpp -+interpreter_.cpp assembler.hpp -+interpreter_.cpp bytecodeHistogram.hpp -+interpreter_.cpp debug.hpp -+interpreter_.cpp deoptimization.hpp -+interpreter_.cpp frame.inline.hpp -+interpreter_.cpp interpreterRuntime.hpp -+interpreter_.cpp interpreter.hpp -+interpreter_.cpp interpreterGenerator.hpp -+interpreter_.cpp jvmtiExport.hpp -+interpreter_.cpp jvmtiThreadState.hpp -+interpreter_.cpp methodDataOop.hpp -+interpreter_.cpp methodOop.hpp -+interpreter_.cpp oop.inline.hpp -+interpreter_.cpp sharedRuntime.hpp -+interpreter_.cpp stubRoutines.hpp -+interpreter_.cpp synchronizer.hpp -+interpreter_.cpp templateTable.hpp -+interpreter_.cpp timer.hpp -+interpreter_.cpp vframeArray.hpp -+ -+interpreter_.hpp generate_platform_dependent_include -+ -+interpreterGenerator.hpp cppInterpreter.hpp -+interpreterGenerator.hpp cppInterpreterGenerator.hpp -+interpreterGenerator.hpp templateInterpreter.hpp -+interpreterGenerator.hpp templateInterpreterGenerator.hpp - --interpreter_.hpp frame.inline.hpp --interpreter_.hpp interpreter.hpp -+interpreterGenerator_.hpp generate_platform_dependent_include - - invocationCounter.cpp frame.hpp - invocationCounter.cpp handles.inline.hpp -@@ -2260,7 +2231,7 @@ - java.cpp universe.hpp - java.cpp vmError.hpp - java.cpp vm_operations.hpp --java.cpp vm_version_.hpp -+java.cpp vm_version_.hpp - java.cpp vtune.hpp - - java.hpp os.hpp -@@ -2283,7 +2254,7 @@ - javaCalls.cpp compileBroker.hpp - javaCalls.cpp handles.inline.hpp - javaCalls.cpp interfaceSupport.hpp --javaCalls.cpp interpreter_.hpp -+javaCalls.cpp interpreter.hpp - javaCalls.cpp javaCalls.hpp - javaCalls.cpp linkResolver.hpp - javaCalls.cpp mutexLocker.hpp -@@ -2388,31 +2359,18 @@ - jni.cpp vmSymbols.hpp - jni.cpp vm_operations.hpp - --jniCheck.cpp fieldDescriptor.hpp --jniCheck.cpp handles.hpp --jniCheck.cpp instanceKlass.hpp --jniCheck.cpp interfaceSupport.hpp --jniCheck.cpp jfieldIDWorkaround.hpp --jniCheck.cpp jni.h --jniCheck.cpp jniCheck.hpp --jniCheck.cpp jniTypes_.hpp --jniCheck.cpp jvm_misc.hpp --jniCheck.cpp oop.inline.hpp --jniCheck.cpp symbolOop.hpp --jniCheck.cpp systemDictionary.hpp --jniCheck.cpp thread.hpp --jniCheck.cpp vmSymbols.hpp -+// jniCheck is jck optional, put cpp deps in includeDB_features - - jniFastGetField.cpp jniFastGetField.hpp - - jniFastGetField.hpp allocation.hpp - jniFastGetField.hpp jvm_misc.hpp - --jniFastGetField_.cpp assembler_.inline.hpp --jniFastGetField_.cpp jniFastGetField.hpp --jniFastGetField_.cpp jvm_misc.hpp --jniFastGetField_.cpp resourceArea.hpp --jniFastGetField_.cpp safepoint.hpp -+jniFastGetField_.cpp assembler_.inline.hpp -+jniFastGetField_.cpp jniFastGetField.hpp -+jniFastGetField_.cpp jvm_misc.hpp -+jniFastGetField_.cpp resourceArea.hpp -+jniFastGetField_.cpp safepoint.hpp - - jniHandles.cpp jniHandles.hpp - jniHandles.cpp mutexLocker.hpp -@@ -2487,181 +2445,6 @@ - jvm_misc.hpp handles.hpp - jvm_misc.hpp jni.h - --jvmtiAgentThread.hpp jvmtiEnv.hpp -- --jvmtiClassFileReconstituter.cpp bytecodeStream.hpp --jvmtiClassFileReconstituter.cpp bytes_.hpp --jvmtiClassFileReconstituter.cpp jvmtiClassFileReconstituter.hpp --jvmtiClassFileReconstituter.cpp symbolTable.hpp -- --jvmtiClassFileReconstituter.hpp jvmtiEnv.hpp -- --jvmtiCodeBlobEvents.cpp codeBlob.hpp --jvmtiCodeBlobEvents.cpp codeCache.hpp --jvmtiCodeBlobEvents.cpp handles.hpp --jvmtiCodeBlobEvents.cpp handles.inline.hpp --jvmtiCodeBlobEvents.cpp jvmtiCodeBlobEvents.hpp --jvmtiCodeBlobEvents.cpp jvmtiExport.hpp --jvmtiCodeBlobEvents.cpp oop.inline.hpp --jvmtiCodeBlobEvents.cpp resourceArea.hpp --jvmtiCodeBlobEvents.cpp scopeDesc.hpp --jvmtiCodeBlobEvents.cpp vmThread.hpp -- --jvmtiCodeBlobEvents.hpp jvmti.h -- --jvmtiEnter.cpp jvmtiEnter.hpp -- --jvmtiEnter.hpp interfaceSupport.hpp --jvmtiEnter.hpp jvmtiEnv.hpp --jvmtiEnter.hpp jvmtiImpl.hpp --jvmtiEnter.hpp resourceArea.hpp --jvmtiEnter.hpp systemDictionary.hpp -- --jvmtiEnterTrace.cpp jvmtiEnter.hpp -- --jvmtiEnv.cpp arguments.hpp --jvmtiEnv.cpp bytecodeStream.hpp --jvmtiEnv.cpp cpCacheOop.hpp --jvmtiEnv.cpp deoptimization.hpp --jvmtiEnv.cpp exceptions.hpp --jvmtiEnv.cpp instanceKlass.hpp --jvmtiEnv.cpp interfaceSupport.hpp --jvmtiEnv.cpp interpreter.hpp --jvmtiEnv.cpp javaCalls.hpp --jvmtiEnv.cpp jfieldIDWorkaround.hpp --jvmtiEnv.cpp jniCheck.hpp --jvmtiEnv.cpp jvm_misc.hpp --jvmtiEnv.cpp jvmtiAgentThread.hpp --jvmtiEnv.cpp jvmtiClassFileReconstituter.hpp --jvmtiEnv.cpp jvmtiCodeBlobEvents.hpp --jvmtiEnv.cpp jvmtiEnv.hpp --jvmtiEnv.cpp jvmtiExtensions.hpp --jvmtiEnv.cpp jvmtiGetLoadedClasses.hpp --jvmtiEnv.cpp jvmtiImpl.hpp --jvmtiEnv.cpp jvmtiManageCapabilities.hpp --jvmtiEnv.cpp jvmtiRedefineClasses.hpp --jvmtiEnv.cpp jvmtiTagMap.hpp --jvmtiEnv.cpp jvmtiThreadState.inline.hpp --jvmtiEnv.cpp objectMonitor.inline.hpp --jvmtiEnv.cpp osThread.hpp --jvmtiEnv.cpp preserveException.hpp --jvmtiEnv.cpp reflectionUtils.hpp --jvmtiEnv.cpp resourceArea.hpp --jvmtiEnv.cpp signature.hpp --jvmtiEnv.cpp systemDictionary.hpp --jvmtiEnv.cpp threadService.hpp --jvmtiEnv.cpp thread_.inline.hpp --jvmtiEnv.cpp universe.inline.hpp --jvmtiEnv.cpp vframe.hpp --jvmtiEnv.cpp vmSymbols.hpp --jvmtiEnv.cpp vmThread.hpp -- --jvmtiEnv.hpp jvmtiEnvBase.hpp -- --jvmtiEnvBase.cpp biasedLocking.hpp --jvmtiEnvBase.cpp interfaceSupport.hpp --jvmtiEnvBase.cpp jfieldIDWorkaround.hpp --jvmtiEnvBase.cpp jvmtiEnv.hpp --jvmtiEnvBase.cpp jvmtiEnvBase.hpp --jvmtiEnvBase.cpp jvmtiEventController.inline.hpp --jvmtiEnvBase.cpp jvmtiExtensions.hpp --jvmtiEnvBase.cpp jvmtiImpl.hpp --jvmtiEnvBase.cpp jvmtiManageCapabilities.hpp --jvmtiEnvBase.cpp jvmtiTagMap.hpp --jvmtiEnvBase.cpp jvmtiThreadState.inline.hpp --jvmtiEnvBase.cpp objArrayKlass.hpp --jvmtiEnvBase.cpp objArrayOop.hpp --jvmtiEnvBase.cpp objectMonitor.hpp --jvmtiEnvBase.cpp objectMonitor.inline.hpp --jvmtiEnvBase.cpp signature.hpp --jvmtiEnvBase.cpp systemDictionary.hpp --jvmtiEnvBase.cpp vframe.hpp --jvmtiEnvBase.cpp vframe_hp.hpp --jvmtiEnvBase.cpp vmThread.hpp --jvmtiEnvBase.cpp vm_operations.hpp -- --jvmtiEnvBase.hpp classLoader.hpp --jvmtiEnvBase.hpp fieldDescriptor.hpp --jvmtiEnvBase.hpp frame.hpp --jvmtiEnvBase.hpp growableArray.hpp --jvmtiEnvBase.hpp handles.inline.hpp --jvmtiEnvBase.hpp jvmtiEnvThreadState.hpp --jvmtiEnvBase.hpp jvmtiEventController.hpp --jvmtiEnvBase.hpp jvmtiThreadState.hpp --jvmtiEnvBase.hpp thread.hpp --jvmtiEnvBase.hpp vm_operations.hpp -- --jvmtiEnvThreadState.cpp handles.hpp --jvmtiEnvThreadState.cpp handles.inline.hpp --jvmtiEnvThreadState.cpp interfaceSupport.hpp --jvmtiEnvThreadState.cpp interpreter.hpp --jvmtiEnvThreadState.cpp javaCalls.hpp --jvmtiEnvThreadState.cpp jvmtiEnv.hpp --jvmtiEnvThreadState.cpp jvmtiEnvThreadState.hpp --jvmtiEnvThreadState.cpp jvmtiEventController.inline.hpp --jvmtiEnvThreadState.cpp jvmtiImpl.hpp --jvmtiEnvThreadState.cpp resourceArea.hpp --jvmtiEnvThreadState.cpp signature.hpp --jvmtiEnvThreadState.cpp systemDictionary.hpp --jvmtiEnvThreadState.cpp vframe.hpp --jvmtiEnvThreadState.cpp vm_operations.hpp -- --jvmtiEnvThreadState.hpp allocation.hpp --jvmtiEnvThreadState.hpp allocation.inline.hpp --jvmtiEnvThreadState.hpp globalDefinitions.hpp --jvmtiEnvThreadState.hpp growableArray.hpp --jvmtiEnvThreadState.hpp instanceKlass.hpp --jvmtiEnvThreadState.hpp jvmti.h --jvmtiEnvThreadState.hpp jvmtiEventController.hpp -- --jvmtiEventController.cpp frame.hpp --jvmtiEventController.cpp interpreter.hpp --jvmtiEventController.cpp jvmtiEnv.hpp --jvmtiEventController.cpp jvmtiEventController.hpp --jvmtiEventController.cpp jvmtiEventController.inline.hpp --jvmtiEventController.cpp jvmtiExport.hpp --jvmtiEventController.cpp jvmtiImpl.hpp --jvmtiEventController.cpp jvmtiThreadState.inline.hpp --jvmtiEventController.cpp resourceArea.hpp --jvmtiEventController.cpp thread.hpp --jvmtiEventController.cpp vframe.hpp --jvmtiEventController.cpp vframe_hp.hpp --jvmtiEventController.cpp vmThread.hpp --jvmtiEventController.cpp vm_operations.hpp -- --jvmtiEventController.hpp allocation.hpp --jvmtiEventController.hpp allocation.inline.hpp --jvmtiEventController.hpp globalDefinitions.hpp --jvmtiEventController.hpp jvmti.h -- --jvmtiEventController.inline.hpp jvmtiEventController.hpp --jvmtiEventController.inline.hpp jvmtiImpl.hpp -- --jvmtiExport.cpp arguments.hpp --jvmtiExport.cpp attachListener.hpp --jvmtiExport.cpp handles.hpp --jvmtiExport.cpp interfaceSupport.hpp --jvmtiExport.cpp interpreter.hpp --jvmtiExport.cpp jvmtiCodeBlobEvents.hpp --jvmtiExport.cpp jvmtiEventController.hpp --jvmtiExport.cpp jvmtiEventController.inline.hpp --jvmtiExport.cpp jvmtiExport.hpp --jvmtiExport.cpp jvmtiImpl.hpp --jvmtiExport.cpp jvmtiManageCapabilities.hpp --jvmtiExport.cpp jvmtiTagMap.hpp --jvmtiExport.cpp jvmtiThreadState.inline.hpp --jvmtiExport.cpp nmethod.hpp --jvmtiExport.cpp objArrayKlass.hpp --jvmtiExport.cpp objArrayOop.hpp --jvmtiExport.cpp objectMonitor.inline.hpp --jvmtiExport.cpp pcDesc.hpp --jvmtiExport.cpp resourceArea.hpp --jvmtiExport.cpp scopeDesc.hpp --jvmtiExport.cpp serviceUtil.hpp --jvmtiExport.cpp systemDictionary.hpp --jvmtiExport.cpp thread.hpp --jvmtiExport.cpp vframe.hpp -- - jvmtiExport.hpp allocation.hpp - jvmtiExport.hpp globalDefinitions.hpp - jvmtiExport.hpp growableArray.hpp -@@ -2671,113 +2454,6 @@ - jvmtiExport.hpp oop.hpp - jvmtiExport.hpp oopsHierarchy.hpp - --jvmtiExtensions.cpp jvmtiExport.hpp --jvmtiExtensions.cpp jvmtiExtensions.hpp -- --jvmtiExtensions.hpp allocation.hpp --jvmtiExtensions.hpp jvmti.h --jvmtiExtensions.hpp jvmtiEnv.hpp -- --jvmtiGetLoadedClasses.cpp jvmtiGetLoadedClasses.hpp --jvmtiGetLoadedClasses.cpp systemDictionary.hpp --jvmtiGetLoadedClasses.cpp thread.hpp --jvmtiGetLoadedClasses.cpp universe.inline.hpp -- --jvmtiGetLoadedClasses.hpp jvmtiEnv.hpp -- --jvmtiImpl.cpp exceptions.hpp --jvmtiImpl.cpp handles.hpp --jvmtiImpl.cpp handles.inline.hpp --jvmtiImpl.cpp instanceKlass.hpp --jvmtiImpl.cpp interfaceSupport.hpp --jvmtiImpl.cpp interpreter.hpp --jvmtiImpl.cpp javaCalls.hpp --jvmtiImpl.cpp jvmtiAgentThread.hpp --jvmtiImpl.cpp jvmtiEnv.hpp --jvmtiImpl.cpp jvmtiEventController.inline.hpp --jvmtiImpl.cpp jvmtiImpl.hpp --jvmtiImpl.cpp jvmtiRedefineClasses.hpp --jvmtiImpl.cpp resourceArea.hpp --jvmtiImpl.cpp signature.hpp --jvmtiImpl.cpp systemDictionary.hpp --jvmtiImpl.cpp thread_.inline.hpp --jvmtiImpl.cpp vframe.hpp --jvmtiImpl.cpp vframe_hp.hpp --jvmtiImpl.cpp vm_operations.hpp -- --jvmtiImpl.hpp jvmti.h --jvmtiImpl.hpp jvmtiEnvThreadState.hpp --jvmtiImpl.hpp jvmtiEventController.hpp --jvmtiImpl.hpp objArrayOop.hpp --jvmtiImpl.hpp stackValueCollection.hpp --jvmtiImpl.hpp systemDictionary.hpp --jvmtiImpl.hpp vm_operations.hpp -- --jvmtiManageCapabilities.cpp jvmtiEnv.hpp --jvmtiManageCapabilities.cpp jvmtiExport.hpp --jvmtiManageCapabilities.cpp jvmtiManageCapabilities.hpp -- --jvmtiManageCapabilities.hpp allocation.hpp --jvmtiManageCapabilities.hpp jvmti.h -- --jvmtiRedefineClasses.cpp codeCache.hpp --jvmtiRedefineClasses.cpp deoptimization.hpp --jvmtiRedefineClasses.cpp gcLocker.hpp --jvmtiRedefineClasses.cpp jvmtiImpl.hpp --jvmtiRedefineClasses.cpp jvmtiRedefineClasses.hpp --jvmtiRedefineClasses.cpp klassVtable.hpp --jvmtiRedefineClasses.cpp methodComparator.hpp --jvmtiRedefineClasses.cpp oopMapCache.hpp --jvmtiRedefineClasses.cpp relocator.hpp --jvmtiRedefineClasses.cpp rewriter.hpp --jvmtiRedefineClasses.cpp systemDictionary.hpp --jvmtiRedefineClasses.cpp universe.inline.hpp --jvmtiRedefineClasses.cpp verifier.hpp -- --jvmtiRedefineClasses.hpp jvmtiEnv.hpp --jvmtiRedefineClasses.hpp objArrayKlass.hpp --jvmtiRedefineClasses.hpp objArrayOop.hpp --jvmtiRedefineClasses.hpp oopFactory.hpp --jvmtiRedefineClasses.hpp resourceArea.hpp --jvmtiRedefineClasses.hpp vm_operations.hpp -- --jvmtiTagMap.cpp biasedLocking.hpp --jvmtiTagMap.cpp javaCalls.hpp --jvmtiTagMap.cpp jniHandles.hpp --jvmtiTagMap.cpp jvmtiEnv.hpp --jvmtiTagMap.cpp jvmtiEventController.hpp --jvmtiTagMap.cpp jvmtiEventController.inline.hpp --jvmtiTagMap.cpp jvmtiExport.hpp --jvmtiTagMap.cpp jvmtiImpl.hpp --jvmtiTagMap.cpp jvmtiTagMap.hpp --jvmtiTagMap.cpp mutex.hpp --jvmtiTagMap.cpp mutexLocker.hpp --jvmtiTagMap.cpp objArrayKlass.hpp --jvmtiTagMap.cpp oop.inline2.hpp --jvmtiTagMap.cpp reflectionUtils.hpp --jvmtiTagMap.cpp serviceUtil.hpp --jvmtiTagMap.cpp symbolTable.hpp --jvmtiTagMap.cpp systemDictionary.hpp --jvmtiTagMap.cpp vframe.hpp --jvmtiTagMap.cpp vmSymbols.hpp --jvmtiTagMap.cpp vmThread.hpp --jvmtiTagMap.cpp vm_operations.hpp -- --jvmtiTagMap.hpp allocation.hpp --jvmtiTagMap.hpp collectedHeap.hpp --jvmtiTagMap.hpp genCollectedHeap.hpp --jvmtiTagMap.hpp jvmti.h --jvmtiTagMap.hpp jvmtiEnv.hpp --jvmtiTagMap.hpp universe.hpp -- --jvmtiThreadState.cpp gcLocker.hpp --jvmtiThreadState.cpp jvmtiEnv.hpp --jvmtiThreadState.cpp jvmtiEventController.inline.hpp --jvmtiThreadState.cpp jvmtiImpl.hpp --jvmtiThreadState.cpp jvmtiThreadState.inline.hpp --jvmtiThreadState.cpp resourceArea.hpp --jvmtiThreadState.cpp vframe.hpp -- - jvmtiThreadState.hpp allocation.hpp - jvmtiThreadState.hpp allocation.inline.hpp - jvmtiThreadState.hpp growableArray.hpp -@@ -2785,9 +2461,6 @@ - jvmtiThreadState.hpp jvmtiEventController.hpp - jvmtiThreadState.hpp thread.hpp - --jvmtiThreadState.inline.hpp jvmtiEnvThreadState.hpp --jvmtiThreadState.inline.hpp jvmtiThreadState.hpp -- - klass.cpp atomic.hpp - klass.cpp collectedHeap.inline.hpp - klass.cpp instanceKlass.hpp -@@ -2844,7 +2517,7 @@ - klassVtable.cpp gcLocker.hpp - klassVtable.cpp handles.inline.hpp - klassVtable.cpp instanceKlass.hpp --klassVtable.cpp jvmtiRedefineClasses.hpp -+klassVtable.cpp jvmtiRedefineClassesTrace.hpp - klassVtable.cpp klassOop.hpp - klassVtable.cpp klassVtable.hpp - klassVtable.cpp markSweep.hpp -@@ -3046,7 +2719,7 @@ - - methodComparator.cpp globalDefinitions.hpp - methodComparator.cpp handles.inline.hpp --methodComparator.cpp jvmtiRedefineClasses.hpp -+methodComparator.cpp jvmtiRedefineClassesTrace.hpp - methodComparator.cpp methodComparator.hpp - methodComparator.cpp oop.inline.hpp - methodComparator.cpp symbolOop.hpp -@@ -3193,7 +2866,7 @@ - mutex_.inline.hpp os_.inline.hpp - mutex_.inline.hpp thread_.inline.hpp - --nativeInst_.cpp assembler_.inline.hpp -+nativeInst_.cpp assembler_.inline.hpp - nativeInst_.cpp handles.hpp - nativeInst_.cpp nativeInst_.hpp - nativeInst_.cpp oop.hpp -@@ -3240,7 +2913,7 @@ - nmethod.cpp disassembler_.hpp - nmethod.cpp dtrace.hpp - nmethod.cpp events.hpp --nmethod.cpp jvmtiRedefineClasses.hpp -+nmethod.cpp jvmtiRedefineClassesTrace.hpp - nmethod.cpp methodDataOop.hpp - nmethod.cpp nmethod.hpp - nmethod.cpp scopeDesc.hpp -@@ -3395,7 +3068,6 @@ - - oopMapCache.cpp allocation.inline.hpp - oopMapCache.cpp handles.inline.hpp --oopMapCache.cpp jvmtiRedefineClasses.hpp - oopMapCache.cpp oop.inline.hpp - oopMapCache.cpp oopMapCache.hpp - oopMapCache.cpp resourceArea.hpp -@@ -3459,7 +3131,7 @@ - - os_.cpp allocation.inline.hpp - os_.cpp arguments.hpp --os_.cpp assembler_.inline.hpp -+os_.cpp assembler_.inline.hpp - os_.cpp classLoader.hpp - os_.cpp events.hpp - os_.cpp extendedPC.hpp -@@ -3467,7 +3139,7 @@ - os_.cpp hpi.hpp - os_.cpp icBuffer.hpp - os_.cpp interfaceSupport.hpp --os_.cpp interpreter_.hpp -+os_.cpp interpreter.hpp - os_.cpp java.hpp - os_.cpp javaCalls.hpp - os_.cpp jniFastGetField.hpp -@@ -3493,7 +3165,7 @@ - - os_.cpp allocation.inline.hpp - os_.cpp arguments.hpp --os_.cpp assembler_.inline.hpp -+os_.cpp assembler_.inline.hpp - os_.cpp attachListener.hpp - os_.cpp classLoader.hpp - os_.cpp compileBroker.hpp -@@ -3505,7 +3177,7 @@ - os_.cpp hpi.hpp - os_.cpp icBuffer.hpp - os_.cpp interfaceSupport.hpp --os_.cpp interpreter_.hpp -+os_.cpp interpreter.hpp - os_.cpp java.hpp - os_.cpp javaCalls.hpp - os_.cpp jniFastGetField.hpp -@@ -3551,7 +3223,7 @@ - osThread.hpp objectMonitor.hpp - osThread.hpp top.hpp - --osThread_.cpp assembler_.inline.hpp -+osThread_.cpp assembler_.inline.hpp - osThread_.cpp atomic.hpp - osThread_.cpp handles.inline.hpp - osThread_.cpp mutexLocker.hpp -@@ -3568,6 +3240,8 @@ - ostream.cpp defaultStream.hpp - ostream.cpp oop.inline.hpp - ostream.cpp os_.inline.hpp -+ostream.cpp hpi.hpp -+ostream.cpp hpi_.hpp - ostream.cpp ostream.hpp - ostream.cpp top.hpp - ostream.cpp xmlstream.hpp -@@ -3745,7 +3419,7 @@ - register_.cpp register_.hpp - - register_.hpp register.hpp --register_.hpp vm_version_.hpp -+register_.hpp vm_version_.hpp - - registerMap.hpp globalDefinitions.hpp - registerMap.hpp register_.hpp -@@ -3754,11 +3428,11 @@ - registerMap_.hpp generate_platform_dependent_include - - register_definitions_.cpp assembler.hpp --register_definitions_.cpp interp_masm_.hpp -+register_definitions_.cpp interp_masm_.hpp - register_definitions_.cpp register.hpp - register_definitions_.cpp register_.hpp - --relocInfo.cpp assembler_.inline.hpp -+relocInfo.cpp assembler_.inline.hpp - relocInfo.cpp compiledIC.hpp - relocInfo.cpp copy.hpp - relocInfo.cpp nativeInst_.hpp -@@ -3771,7 +3445,7 @@ - relocInfo.hpp top.hpp - - relocInfo_.cpp assembler.inline.hpp --relocInfo_.cpp assembler_.inline.hpp -+relocInfo_.cpp assembler_.inline.hpp - relocInfo_.cpp nativeInst_.hpp - relocInfo_.cpp relocInfo.hpp - relocInfo_.cpp safepoint.hpp -@@ -3806,11 +3480,7 @@ - resourceArea.hpp allocation.hpp - resourceArea.hpp thread_.inline.hpp - --restore.cpp filemap.hpp --restore.cpp hashtable.inline.hpp --restore.cpp oop.inline.hpp --restore.cpp symbolTable.hpp --restore.cpp systemDictionary.hpp -+// restore is jck optional, put cpp deps in includeDB_features - - rewriter.cpp bytecodes.hpp - rewriter.cpp gcLocker.hpp -@@ -3827,7 +3497,7 @@ - rewriter.hpp handles.inline.hpp - - rframe.cpp frame.inline.hpp --rframe.cpp interpreter_.hpp -+rframe.cpp interpreter.hpp - rframe.cpp oop.inline.hpp - rframe.cpp rframe.hpp - rframe.cpp symbolOop.hpp -@@ -3855,7 +3525,6 @@ - safepoint.cpp icBuffer.hpp - safepoint.cpp interfaceSupport.hpp - safepoint.cpp interpreter.hpp --safepoint.cpp interpreter_.hpp - safepoint.cpp mutexLocker.hpp - safepoint.cpp nativeInst_.hpp - safepoint.cpp nmethod.hpp -@@ -3896,15 +3565,7 @@ - scopeDesc.hpp methodOop.hpp - scopeDesc.hpp pcDesc.hpp - --serialize.cpp classify.hpp --serialize.cpp codeCache.hpp --serialize.cpp compactingPermGenGen.hpp --serialize.cpp compiledICHolderOop.hpp --serialize.cpp methodDataOop.hpp --serialize.cpp objArrayOop.hpp --serialize.cpp oop.hpp --serialize.cpp symbolTable.hpp --serialize.cpp systemDictionary.hpp -+// serialize is jck optional, put cpp deps in includeDB_features - - serviceUtil.hpp objArrayOop.hpp - serviceUtil.hpp systemDictionary.hpp -@@ -3939,7 +3600,7 @@ - sharedRuntime.cpp init.hpp - sharedRuntime.cpp interfaceSupport.hpp - sharedRuntime.cpp interpreterRuntime.hpp --sharedRuntime.cpp interpreter_.hpp -+sharedRuntime.cpp interpreter.hpp - sharedRuntime.cpp javaCalls.hpp - sharedRuntime.cpp jvmtiExport.hpp - sharedRuntime.cpp nativeInst_.hpp -@@ -3965,17 +3626,16 @@ - sharedRuntime.hpp resourceArea.hpp - sharedRuntime.hpp threadLocalStorage.hpp - --sharedRuntime_.cpp assembler.hpp --sharedRuntime_.cpp assembler_.inline.hpp --sharedRuntime_.cpp compiledICHolderOop.hpp --sharedRuntime_.cpp debugInfoRec.hpp --sharedRuntime_.cpp icBuffer.hpp --sharedRuntime_.cpp interpreter.hpp --sharedRuntime_.cpp interpreter_.hpp --sharedRuntime_.cpp sharedRuntime.hpp --sharedRuntime_.cpp vframeArray.hpp --sharedRuntime_.cpp vmreg_.inline.hpp --sharedRuntime_.cpp vtableStubs.hpp -+sharedRuntime_.cpp assembler.hpp -+sharedRuntime_.cpp assembler_.inline.hpp -+sharedRuntime_.cpp compiledICHolderOop.hpp -+sharedRuntime_.cpp debugInfoRec.hpp -+sharedRuntime_.cpp icBuffer.hpp -+sharedRuntime_.cpp interpreter.hpp -+sharedRuntime_.cpp sharedRuntime.hpp -+sharedRuntime_.cpp vframeArray.hpp -+sharedRuntime_.cpp vmreg_.inline.hpp -+sharedRuntime_.cpp vtableStubs.hpp - - sharedRuntimeTrans.cpp interfaceSupport.hpp - sharedRuntimeTrans.cpp jni.h -@@ -4070,11 +3730,14 @@ - stackMapTable.hpp methodOop.hpp - stackMapTable.hpp stackMapFrame.hpp - -+stackValue.cpp debugInfo.hpp -+stackValue.cpp frame.inline.hpp - stackValue.cpp handles.inline.hpp - stackValue.cpp oop.hpp - stackValue.cpp stackValue.hpp - - stackValue.hpp handles.hpp -+stackValue.hpp location.hpp - stackValue.hpp top.hpp - - stackValueCollection.cpp jniTypes_.hpp -@@ -4094,12 +3757,12 @@ - statSampler.cpp statSampler.hpp - statSampler.cpp systemDictionary.hpp - statSampler.cpp vmSymbols.hpp --statSampler.cpp vm_version_.hpp -+statSampler.cpp vm_version_.hpp - - statSampler.hpp perfData.hpp - statSampler.hpp task.hpp - --stubCodeGenerator.cpp assembler_.inline.hpp -+stubCodeGenerator.cpp assembler_.inline.hpp - stubCodeGenerator.cpp disassembler_.hpp - stubCodeGenerator.cpp forte.hpp - stubCodeGenerator.cpp oop.inline.hpp -@@ -4109,20 +3772,21 @@ - stubCodeGenerator.hpp allocation.hpp - stubCodeGenerator.hpp assembler.hpp - --stubGenerator_.cpp assembler.hpp --stubGenerator_.cpp assembler_.inline.hpp --stubGenerator_.cpp handles.inline.hpp --stubGenerator_.cpp instanceOop.hpp --stubGenerator_.cpp interpreter_.hpp --stubGenerator_.cpp methodOop.hpp --stubGenerator_.cpp nativeInst_.hpp --stubGenerator_.cpp objArrayKlass.hpp --stubGenerator_.cpp oop.inline.hpp --stubGenerator_.cpp sharedRuntime.hpp --stubGenerator_.cpp stubCodeGenerator.hpp --stubGenerator_.cpp stubRoutines.hpp --stubGenerator_.cpp thread_.inline.hpp --stubGenerator_.cpp top.hpp -+stubGenerator_.cpp assembler.hpp -+stubGenerator_.cpp assembler_.inline.hpp -+stubGenerator_.cpp frame.inline.hpp -+stubGenerator_.cpp handles.inline.hpp -+stubGenerator_.cpp instanceOop.hpp -+stubGenerator_.cpp interpreter.hpp -+stubGenerator_.cpp methodOop.hpp -+stubGenerator_.cpp nativeInst_.hpp -+stubGenerator_.cpp objArrayKlass.hpp -+stubGenerator_.cpp oop.inline.hpp -+stubGenerator_.cpp sharedRuntime.hpp -+stubGenerator_.cpp stubCodeGenerator.hpp -+stubGenerator_.cpp stubRoutines.hpp -+stubGenerator_.cpp thread_.inline.hpp -+stubGenerator_.cpp top.hpp - - stubRoutines.cpp codeBuffer.hpp - stubRoutines.cpp copy.hpp -@@ -4141,12 +3805,12 @@ - stubRoutines.hpp stubCodeGenerator.hpp - stubRoutines.hpp top.hpp - --stubRoutines_.cpp deoptimization.hpp --stubRoutines_.cpp frame.inline.hpp --stubRoutines_.cpp stubRoutines.hpp --stubRoutines_.cpp thread_.inline.hpp -+stubRoutines_.cpp deoptimization.hpp -+stubRoutines_.cpp frame.inline.hpp -+stubRoutines_.cpp stubRoutines.hpp -+stubRoutines_.cpp thread_.inline.hpp - --stubRoutines_.hpp generate_platform_dependent_include -+stubRoutines_.hpp generate_platform_dependent_include - - stubRoutines_.cpp os.hpp - stubRoutines_.cpp stubRoutines.hpp -@@ -4283,26 +3947,60 @@ - taskqueue.hpp mutex.hpp - taskqueue.hpp orderAccess_.inline.hpp - -+templateInterpreter.cpp interpreter.hpp -+templateInterpreter.cpp interpreterGenerator.hpp -+templateInterpreter.cpp interpreterRuntime.hpp -+templateInterpreter.cpp templateTable.hpp -+ -+templateInterpreter.hpp abstractInterpreter.hpp -+templateInterpreter.hpp templateTable.hpp -+ -+templateInterpreter_.cpp arguments.hpp -+templateInterpreter_.cpp arrayOop.hpp -+templateInterpreter_.cpp assembler.hpp -+templateInterpreter_.cpp bytecodeHistogram.hpp -+templateInterpreter_.cpp debug.hpp -+templateInterpreter_.cpp deoptimization.hpp -+templateInterpreter_.cpp frame.inline.hpp -+templateInterpreter_.cpp interpreterRuntime.hpp -+templateInterpreter_.cpp interpreter.hpp -+templateInterpreter_.cpp interpreterGenerator.hpp -+templateInterpreter_.cpp jvmtiExport.hpp -+templateInterpreter_.cpp jvmtiThreadState.hpp -+templateInterpreter_.cpp methodDataOop.hpp -+templateInterpreter_.cpp methodOop.hpp -+templateInterpreter_.cpp oop.inline.hpp -+templateInterpreter_.cpp sharedRuntime.hpp -+templateInterpreter_.cpp stubRoutines.hpp -+templateInterpreter_.cpp synchronizer.hpp -+templateInterpreter_.cpp templateTable.hpp -+templateInterpreter_.cpp timer.hpp -+templateInterpreter_.cpp vframeArray.hpp -+ -+templateInterpreter_.hpp generate_platform_dependent_include -+ -+templateInterpreterGenerator_.hpp generate_platform_dependent_include -+ - templateTable.cpp templateTable.hpp - templateTable.cpp timer.hpp - - templateTable.hpp allocation.hpp - templateTable.hpp bytecodes.hpp - templateTable.hpp frame.hpp --templateTable.hpp interp_masm_.hpp -+templateTable.hpp interp_masm_.hpp - --templateTable_.cpp interpreterRuntime.hpp --templateTable_.cpp interpreter_.hpp --templateTable_.cpp methodDataOop.hpp --templateTable_.cpp objArrayKlass.hpp --templateTable_.cpp oop.inline.hpp --templateTable_.cpp sharedRuntime.hpp --templateTable_.cpp stubRoutines.hpp --templateTable_.cpp synchronizer.hpp --templateTable_.cpp templateTable.hpp --templateTable_.cpp universe.inline.hpp -+templateTable_.cpp interpreterRuntime.hpp -+templateTable_.cpp interpreter.hpp -+templateTable_.cpp methodDataOop.hpp -+templateTable_.cpp objArrayKlass.hpp -+templateTable_.cpp oop.inline.hpp -+templateTable_.cpp sharedRuntime.hpp -+templateTable_.cpp stubRoutines.hpp -+templateTable_.cpp synchronizer.hpp -+templateTable_.cpp templateTable.hpp -+templateTable_.cpp universe.inline.hpp - --templateTable_.hpp generate_platform_dependent_include -+templateTable_.hpp generate_platform_dependent_include - - tenuredGeneration.cpp allocation.inline.hpp - tenuredGeneration.cpp blockOffsetTable.inline.hpp -@@ -4338,7 +4036,7 @@ - thread.cpp instanceKlass.hpp - thread.cpp interfaceSupport.hpp - thread.cpp interpreter.hpp --thread.cpp interpreter_.hpp -+thread.cpp interpreter.hpp - thread.cpp java.hpp - thread.cpp javaCalls.hpp - thread.cpp javaClasses.hpp -@@ -4541,6 +4239,7 @@ - universe.cpp cpCacheKlass.hpp - universe.cpp cpCacheOop.hpp - universe.cpp deoptimization.hpp -+universe.cpp dependencies.hpp - universe.cpp events.hpp - universe.cpp filemap.hpp - universe.cpp fprofiler.hpp -@@ -4553,11 +4252,11 @@ - universe.cpp instanceKlass.hpp - universe.cpp instanceKlassKlass.hpp - universe.cpp instanceRefKlass.hpp --universe.cpp interpreter_.hpp -+universe.cpp interpreter.hpp - universe.cpp java.hpp - universe.cpp javaCalls.hpp - universe.cpp javaClasses.hpp --universe.cpp jvmtiRedefineClasses.hpp -+universe.cpp jvmtiRedefineClassesTrace.hpp - universe.cpp klassKlass.hpp - universe.cpp klassOop.hpp - universe.cpp memoryService.hpp -@@ -4650,7 +4349,7 @@ - vframe.cpp debugInfoRec.hpp - vframe.cpp handles.inline.hpp - vframe.cpp instanceKlass.hpp --vframe.cpp interpreter_.hpp -+vframe.cpp interpreter.hpp - vframe.cpp javaClasses.hpp - vframe.cpp nmethod.hpp - vframe.cpp objectMonitor.hpp -@@ -4683,7 +4382,7 @@ - vframeArray.cpp allocation.inline.hpp - vframeArray.cpp events.hpp - vframeArray.cpp handles.inline.hpp --vframeArray.cpp interpreter_.hpp -+vframeArray.cpp interpreter.hpp - vframeArray.cpp jvmtiThreadState.hpp - vframeArray.cpp methodDataOop.hpp - vframeArray.cpp monitorChunk.hpp -@@ -4706,7 +4405,7 @@ - vframe_hp.cpp debugInfoRec.hpp - vframe_hp.cpp handles.inline.hpp - vframe_hp.cpp instanceKlass.hpp --vframe_hp.cpp interpreter_.hpp -+vframe_hp.cpp interpreter.hpp - vframe_hp.cpp monitorChunk.hpp - vframe_hp.cpp nmethod.hpp - vframe_hp.cpp oop.inline.hpp -@@ -4749,86 +4448,7 @@ - vmError_.cpp thread.hpp - vmError_.cpp vmError.hpp - --vmStructs.cpp arguments.hpp --vmStructs.cpp arrayKlass.hpp --vmStructs.cpp arrayKlassKlass.hpp --vmStructs.cpp arrayOop.hpp --vmStructs.cpp bytecodes.hpp --vmStructs.cpp cInterpreter.hpp --vmStructs.cpp cardTableRS.hpp --vmStructs.cpp codeBlob.hpp --vmStructs.cpp codeCache.hpp --vmStructs.cpp collectedHeap.hpp --vmStructs.cpp compactPermGen.hpp --vmStructs.cpp compiledICHolderKlass.hpp --vmStructs.cpp compiledICHolderOop.hpp --vmStructs.cpp compressedStream.hpp --vmStructs.cpp constMethodKlass.hpp --vmStructs.cpp constMethodOop.hpp --vmStructs.cpp constantPoolKlass.hpp --vmStructs.cpp constantPoolOop.hpp --vmStructs.cpp cpCacheKlass.hpp --vmStructs.cpp cpCacheOop.hpp --vmStructs.cpp defNewGeneration.hpp --vmStructs.cpp dictionary.hpp --vmStructs.cpp freeBlockDictionary.hpp --vmStructs.cpp genCollectedHeap.hpp --vmStructs.cpp generation.hpp --vmStructs.cpp generationSpec.hpp --vmStructs.cpp globalDefinitions.hpp --vmStructs.cpp globals.hpp --vmStructs.cpp hashtable.hpp --vmStructs.cpp heap.hpp --vmStructs.cpp immutableSpace.hpp --vmStructs.cpp instanceKlass.hpp --vmStructs.cpp instanceKlassKlass.hpp --vmStructs.cpp instanceOop.hpp --vmStructs.cpp interpreter.hpp --vmStructs.cpp java.hpp --vmStructs.cpp javaCalls.hpp --vmStructs.cpp javaClasses.hpp --vmStructs.cpp jvmtiAgentThread.hpp --vmStructs.cpp klass.hpp --vmStructs.cpp klassOop.hpp --vmStructs.cpp loaderConstraints.hpp --vmStructs.cpp location.hpp --vmStructs.cpp markOop.hpp --vmStructs.cpp markSweep.hpp --vmStructs.cpp methodDataKlass.hpp --vmStructs.cpp methodDataOop.hpp --vmStructs.cpp methodKlass.hpp --vmStructs.cpp methodOop.hpp --vmStructs.cpp mutableSpace.hpp --vmStructs.cpp nmethod.hpp --vmStructs.cpp objArrayKlass.hpp --vmStructs.cpp objArrayKlassKlass.hpp --vmStructs.cpp objArrayOop.hpp --vmStructs.cpp oop.hpp --vmStructs.cpp oopMap.hpp --vmStructs.cpp pcDesc.hpp --vmStructs.cpp perfMemory.hpp --vmStructs.cpp permGen.hpp --vmStructs.cpp placeholders.hpp --vmStructs.cpp sharedRuntime.hpp --vmStructs.cpp space.hpp --vmStructs.cpp stubRoutines.hpp --vmStructs.cpp stubs.hpp --vmStructs.cpp symbolKlass.hpp --vmStructs.cpp symbolOop.hpp --vmStructs.cpp symbolTable.hpp --vmStructs.cpp systemDictionary.hpp --vmStructs.cpp tenuredGeneration.hpp --vmStructs.cpp thread_.inline.hpp --vmStructs.cpp typeArrayKlass.hpp --vmStructs.cpp typeArrayKlassKlass.hpp --vmStructs.cpp typeArrayOop.hpp --vmStructs.cpp universe.hpp --vmStructs.cpp virtualspace.hpp --vmStructs.cpp vmStructs.hpp --vmStructs.cpp vmStructs_.hpp --vmStructs.cpp vmStructs_.hpp --vmStructs.cpp vmreg.hpp --vmStructs.cpp watermark.hpp -+// vmStructs is jck optional, put cpp deps in includeDB_features - - vmStructs.hpp debug.hpp - -@@ -4880,22 +4500,22 @@ - vm_version.cpp arguments.hpp - vm_version.cpp oop.inline.hpp - vm_version.cpp universe.hpp --vm_version.cpp vm_version_.hpp -+vm_version.cpp vm_version_.hpp - - vm_version.hpp allocation.hpp - vm_version.hpp ostream.hpp - --vm_version_.cpp assembler_.inline.hpp --vm_version_.cpp java.hpp --vm_version_.cpp os_.inline.hpp --vm_version_.cpp resourceArea.hpp --vm_version_.cpp stubCodeGenerator.hpp --vm_version_.cpp vm_version_.hpp -+vm_version_.cpp assembler_.inline.hpp -+vm_version_.cpp java.hpp -+vm_version_.cpp os_.inline.hpp -+vm_version_.cpp resourceArea.hpp -+vm_version_.cpp stubCodeGenerator.hpp -+vm_version_.cpp vm_version_.hpp - --vm_version_.hpp globals_extension.hpp --vm_version_.hpp vm_version.hpp -+vm_version_.hpp globals_extension.hpp -+vm_version_.hpp vm_version.hpp - --vm_version_.cpp vm_version_.hpp -+vm_version_.cpp vm_version_.hpp - - vmreg.cpp assembler.hpp - vmreg.cpp vmreg.hpp -@@ -4924,19 +4544,19 @@ - - vtableStubs.hpp allocation.hpp - --vtableStubs_.cpp assembler.hpp --vtableStubs_.cpp assembler_.inline.hpp --vtableStubs_.cpp instanceKlass.hpp --vtableStubs_.cpp interp_masm_.hpp --vtableStubs_.cpp klassVtable.hpp --vtableStubs_.cpp resourceArea.hpp --vtableStubs_.cpp sharedRuntime.hpp --vtableStubs_.cpp vmreg_.inline.hpp --vtableStubs_.cpp vtableStubs.hpp -+vtableStubs_.cpp assembler.hpp -+vtableStubs_.cpp assembler_.inline.hpp -+vtableStubs_.cpp instanceKlass.hpp -+vtableStubs_.cpp interp_masm_.hpp -+vtableStubs_.cpp klassVtable.hpp -+vtableStubs_.cpp resourceArea.hpp -+vtableStubs_.cpp sharedRuntime.hpp -+vtableStubs_.cpp vmreg_.inline.hpp -+vtableStubs_.cpp vtableStubs.hpp - - vtune.hpp allocation.hpp - --vtune_.cpp interpreter_.hpp -+vtune_.cpp interpreter.hpp - vtune_.cpp vtune.hpp - - watermark.hpp allocation.hpp -diff -ruNb openjdk6/hotspot/src/share/vm/includeDB_coreonly openjdk/hotspot/src/share/vm/includeDB_coreonly ---- openjdk6/hotspot/src/share/vm/includeDB_coreonly 2008-07-10 22:04:28.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/includeDB_coreonly 1970-01-01 01:00:00.000000000 +0100 -@@ -1,26 +0,0 @@ --// --// Copyright 2000-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, --// CA 95054 USA or visit www.sun.com if you need additional information or --// have any questions. --// --// -- --// NOTE: DO NOT CHANGE THIS COPYRIGHT TO NEW STYLE - IT WILL BREAK makeDeps! -- -diff -ruNb openjdk6/hotspot/src/share/vm/includeDB_features openjdk/hotspot/src/share/vm/includeDB_features ---- openjdk6/hotspot/src/share/vm/includeDB_features 1970-01-01 01:00:00.000000000 +0100 -+++ openjdk/hotspot/src/share/vm/includeDB_features 2007-12-14 08:57:02.000000000 +0100 -@@ -0,0 +1,319 @@ -+// -+// Copyright 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, -+// CA 95054 USA or visit www.sun.com if you need additional information or -+// have any questions. -+// -+// -+ -+attachListener.cpp arguments.hpp -+attachListener.cpp attachListener.hpp -+attachListener.cpp globals.hpp -+attachListener.cpp heapDumper.hpp -+attachListener.cpp java.hpp -+attachListener.cpp javaCalls.hpp -+attachListener.cpp javaClasses.hpp -+attachListener.cpp jvmtiExport.hpp -+attachListener.cpp os.hpp -+attachListener.cpp resourceArea.hpp -+attachListener.cpp systemDictionary.hpp -+attachListener.cpp vmGCOperations.hpp -+ -+attachListener_.cpp attachListener.hpp -+attachListener_.cpp dtraceAttacher.hpp -+attachListener_.cpp interfaceSupport.hpp -+attachListener_.cpp os.hpp -+ -+dump.cpp classify.hpp -+dump.cpp copy.hpp -+dump.cpp filemap.hpp -+dump.cpp javaCalls.hpp -+dump.cpp javaClasses.hpp -+dump.cpp loaderConstraints.hpp -+dump.cpp methodDataOop.hpp -+dump.cpp oop.hpp -+dump.cpp oopFactory.hpp -+dump.cpp resourceArea.hpp -+dump.cpp signature.hpp -+dump.cpp symbolTable.hpp -+dump.cpp systemDictionary.hpp -+dump.cpp vmThread.hpp -+dump.cpp vm_operations.hpp -+ -+dump_.cpp assembler_.inline.hpp -+dump_.cpp compactingPermGenGen.hpp -+ -+forte.cpp collectedHeap.inline.hpp -+forte.cpp debugInfoRec.hpp -+forte.cpp forte.hpp -+forte.cpp oop.inline.hpp -+forte.cpp oop.inline2.hpp -+forte.cpp pcDesc.hpp -+forte.cpp space.hpp -+forte.cpp thread.hpp -+forte.cpp universe.inline.hpp -+forte.cpp vframe.hpp -+forte.cpp vframeArray.hpp -+ -+fprofiler.cpp allocation.inline.hpp -+fprofiler.cpp classLoader.hpp -+fprofiler.cpp collectedHeap.inline.hpp -+fprofiler.cpp deoptimization.hpp -+fprofiler.cpp fprofiler.hpp -+fprofiler.cpp interpreter.hpp -+fprofiler.cpp macros.hpp -+fprofiler.cpp mutexLocker.hpp -+fprofiler.cpp oop.inline.hpp -+fprofiler.cpp oop.inline2.hpp -+fprofiler.cpp stubCodeGenerator.hpp -+fprofiler.cpp stubRoutines.hpp -+fprofiler.cpp symbolOop.hpp -+fprofiler.cpp task.hpp -+fprofiler.cpp universe.inline.hpp -+fprofiler.cpp vframe.hpp -+fprofiler.cpp vtableStubs.hpp -+ -+heapDumper.cpp genCollectedHeap.hpp -+heapDumper.cpp heapDumper.hpp -+heapDumper.cpp javaCalls.hpp -+heapDumper.cpp jniHandles.hpp -+heapDumper.cpp objArrayKlass.hpp -+heapDumper.cpp ostream.hpp -+heapDumper.cpp reflectionUtils.hpp -+heapDumper.cpp symbolTable.hpp -+heapDumper.cpp systemDictionary.hpp -+heapDumper.cpp universe.hpp -+heapDumper.cpp vframe.hpp -+heapDumper.cpp vmGCOperations.hpp -+heapDumper.cpp vmSymbols.hpp -+heapDumper.cpp vmThread.hpp -+heapDumper.cpp vm_operations.hpp -+ -+heapInspection.cpp collectedHeap.hpp -+heapInspection.cpp genCollectedHeap.hpp -+heapInspection.cpp globalDefinitions.hpp -+heapInspection.cpp heapInspection.hpp -+heapInspection.cpp klassOop.hpp -+heapInspection.cpp os.hpp -+heapInspection.cpp resourceArea.hpp -+ -+jniCheck.cpp fieldDescriptor.hpp -+jniCheck.cpp handles.hpp -+jniCheck.cpp instanceKlass.hpp -+jniCheck.cpp interfaceSupport.hpp -+jniCheck.cpp jfieldIDWorkaround.hpp -+jniCheck.cpp jni.h -+jniCheck.cpp jniCheck.hpp -+jniCheck.cpp jniTypes_.hpp -+jniCheck.cpp jvm_misc.hpp -+jniCheck.cpp oop.inline.hpp -+jniCheck.cpp symbolOop.hpp -+jniCheck.cpp systemDictionary.hpp -+jniCheck.cpp thread.hpp -+jniCheck.cpp vmSymbols.hpp -+ -+jvmtiCodeBlobEvents.cpp codeBlob.hpp -+jvmtiCodeBlobEvents.cpp codeCache.hpp -+jvmtiCodeBlobEvents.cpp handles.hpp -+jvmtiCodeBlobEvents.cpp handles.inline.hpp -+jvmtiCodeBlobEvents.cpp jvmtiCodeBlobEvents.hpp -+jvmtiCodeBlobEvents.cpp jvmtiExport.hpp -+jvmtiCodeBlobEvents.cpp oop.inline.hpp -+jvmtiCodeBlobEvents.cpp resourceArea.hpp -+jvmtiCodeBlobEvents.cpp scopeDesc.hpp -+jvmtiCodeBlobEvents.cpp vmThread.hpp -+ -+jvmtiCodeBlobEvents.hpp jvmti.h -+ -+jvmtiExtensions.cpp jvmtiExport.hpp -+jvmtiExtensions.cpp jvmtiExtensions.hpp -+ -+jvmtiExtensions.hpp allocation.hpp -+jvmtiExtensions.hpp jvmti.h -+jvmtiExtensions.hpp jvmtiEnv.hpp -+ -+jvmtiImpl.cpp exceptions.hpp -+jvmtiImpl.cpp handles.hpp -+jvmtiImpl.cpp handles.inline.hpp -+jvmtiImpl.cpp instanceKlass.hpp -+jvmtiImpl.cpp interfaceSupport.hpp -+jvmtiImpl.cpp interpreter.hpp -+jvmtiImpl.cpp javaCalls.hpp -+jvmtiImpl.cpp jvmtiAgentThread.hpp -+jvmtiImpl.cpp jvmtiEnv.hpp -+jvmtiImpl.cpp jvmtiEventController.inline.hpp -+jvmtiImpl.cpp jvmtiImpl.hpp -+jvmtiImpl.cpp jvmtiRedefineClasses.hpp -+jvmtiImpl.cpp resourceArea.hpp -+jvmtiImpl.cpp signature.hpp -+jvmtiImpl.cpp systemDictionary.hpp -+jvmtiImpl.cpp thread_.inline.hpp -+jvmtiImpl.cpp vframe.hpp -+jvmtiImpl.cpp vframe_hp.hpp -+jvmtiImpl.cpp vm_operations.hpp -+ -+jvmtiImpl.hpp jvmti.h -+jvmtiImpl.hpp jvmtiEnvThreadState.hpp -+jvmtiImpl.hpp jvmtiEventController.hpp -+jvmtiImpl.hpp jvmtiTrace.hpp -+jvmtiImpl.hpp jvmtiUtil.hpp -+jvmtiImpl.hpp objArrayOop.hpp -+jvmtiImpl.hpp stackValueCollection.hpp -+jvmtiImpl.hpp systemDictionary.hpp -+jvmtiImpl.hpp vm_operations.hpp -+ -+jvmtiTagMap.cpp biasedLocking.hpp -+jvmtiTagMap.cpp javaCalls.hpp -+jvmtiTagMap.cpp jniHandles.hpp -+jvmtiTagMap.cpp jvmtiEnv.hpp -+jvmtiTagMap.cpp jvmtiEventController.hpp -+jvmtiTagMap.cpp jvmtiEventController.inline.hpp -+jvmtiTagMap.cpp jvmtiExport.hpp -+jvmtiTagMap.cpp jvmtiImpl.hpp -+jvmtiTagMap.cpp jvmtiTagMap.hpp -+jvmtiTagMap.cpp mutex.hpp -+jvmtiTagMap.cpp mutexLocker.hpp -+jvmtiTagMap.cpp objArrayKlass.hpp -+jvmtiTagMap.cpp oop.inline2.hpp -+jvmtiTagMap.cpp reflectionUtils.hpp -+jvmtiTagMap.cpp serviceUtil.hpp -+jvmtiTagMap.cpp symbolTable.hpp -+jvmtiTagMap.cpp systemDictionary.hpp -+jvmtiTagMap.cpp vframe.hpp -+jvmtiTagMap.cpp vmSymbols.hpp -+jvmtiTagMap.cpp vmThread.hpp -+jvmtiTagMap.cpp vm_operations.hpp -+ -+jvmtiTagMap.hpp allocation.hpp -+jvmtiTagMap.hpp collectedHeap.hpp -+jvmtiTagMap.hpp genCollectedHeap.hpp -+jvmtiTagMap.hpp jvmti.h -+jvmtiTagMap.hpp jvmtiEnv.hpp -+jvmtiTagMap.hpp universe.hpp -+ -+jvmtiTrace.cpp jvmtiEnv.hpp -+jvmtiTrace.cpp jvmtiTrace.hpp -+ -+jvmtiTrace.hpp jvmti.h -+jvmtiTrace.hpp jvmtiEnvThreadState.hpp -+jvmtiTrace.hpp jvmtiEventController.hpp -+jvmtiTrace.hpp jvmtiUtil.hpp -+jvmtiTrace.hpp objArrayOop.hpp -+jvmtiTrace.hpp stackValueCollection.hpp -+jvmtiTrace.hpp systemDictionary.hpp -+jvmtiTrace.hpp vm_operations.hpp -+ -+restore.cpp filemap.hpp -+restore.cpp hashtable.inline.hpp -+restore.cpp oop.inline.hpp -+restore.cpp symbolTable.hpp -+restore.cpp systemDictionary.hpp -+ -+serialize.cpp classify.hpp -+serialize.cpp codeCache.hpp -+serialize.cpp compactingPermGenGen.hpp -+serialize.cpp compiledICHolderOop.hpp -+serialize.cpp methodDataOop.hpp -+serialize.cpp objArrayOop.hpp -+serialize.cpp oop.hpp -+serialize.cpp symbolTable.hpp -+serialize.cpp systemDictionary.hpp -+ -+vmStructs.cpp arguments.hpp -+vmStructs.cpp arrayKlass.hpp -+vmStructs.cpp arrayKlassKlass.hpp -+vmStructs.cpp arrayOop.hpp -+vmStructs.cpp bytecodes.hpp -+vmStructs.cpp bytecodeInterpreter.hpp -+vmStructs.cpp cardTableRS.hpp -+vmStructs.cpp codeBlob.hpp -+vmStructs.cpp codeCache.hpp -+vmStructs.cpp collectedHeap.hpp -+vmStructs.cpp compactPermGen.hpp -+vmStructs.cpp compiledICHolderKlass.hpp -+vmStructs.cpp compiledICHolderOop.hpp -+vmStructs.cpp compressedStream.hpp -+vmStructs.cpp constMethodKlass.hpp -+vmStructs.cpp constMethodOop.hpp -+vmStructs.cpp constantPoolKlass.hpp -+vmStructs.cpp constantPoolOop.hpp -+vmStructs.cpp cpCacheKlass.hpp -+vmStructs.cpp cpCacheOop.hpp -+vmStructs.cpp defNewGeneration.hpp -+vmStructs.cpp dictionary.hpp -+vmStructs.cpp freeBlockDictionary.hpp -+vmStructs.cpp genCollectedHeap.hpp -+vmStructs.cpp generation.hpp -+vmStructs.cpp generationSpec.hpp -+vmStructs.cpp globalDefinitions.hpp -+vmStructs.cpp globals.hpp -+vmStructs.cpp hashtable.hpp -+vmStructs.cpp heap.hpp -+vmStructs.cpp immutableSpace.hpp -+vmStructs.cpp instanceKlass.hpp -+vmStructs.cpp instanceKlassKlass.hpp -+vmStructs.cpp instanceOop.hpp -+vmStructs.cpp interpreter.hpp -+vmStructs.cpp java.hpp -+vmStructs.cpp javaCalls.hpp -+vmStructs.cpp javaClasses.hpp -+vmStructs.cpp jvmtiAgentThread.hpp -+vmStructs.cpp klass.hpp -+vmStructs.cpp klassOop.hpp -+vmStructs.cpp loaderConstraints.hpp -+vmStructs.cpp location.hpp -+vmStructs.cpp markOop.hpp -+vmStructs.cpp markSweep.hpp -+vmStructs.cpp methodDataKlass.hpp -+vmStructs.cpp methodDataOop.hpp -+vmStructs.cpp methodKlass.hpp -+vmStructs.cpp methodOop.hpp -+vmStructs.cpp mutableSpace.hpp -+vmStructs.cpp nmethod.hpp -+vmStructs.cpp objArrayKlass.hpp -+vmStructs.cpp objArrayKlassKlass.hpp -+vmStructs.cpp objArrayOop.hpp -+vmStructs.cpp oop.hpp -+vmStructs.cpp oopMap.hpp -+vmStructs.cpp pcDesc.hpp -+vmStructs.cpp perfMemory.hpp -+vmStructs.cpp permGen.hpp -+vmStructs.cpp placeholders.hpp -+vmStructs.cpp sharedRuntime.hpp -+vmStructs.cpp space.hpp -+vmStructs.cpp stubRoutines.hpp -+vmStructs.cpp stubs.hpp -+vmStructs.cpp symbolKlass.hpp -+vmStructs.cpp symbolOop.hpp -+vmStructs.cpp symbolTable.hpp -+vmStructs.cpp systemDictionary.hpp -+vmStructs.cpp tenuredGeneration.hpp -+vmStructs.cpp thread_.inline.hpp -+vmStructs.cpp typeArrayKlass.hpp -+vmStructs.cpp typeArrayKlassKlass.hpp -+vmStructs.cpp typeArrayOop.hpp -+vmStructs.cpp universe.hpp -+vmStructs.cpp virtualspace.hpp -+vmStructs.cpp vmStructs.hpp -+vmStructs.cpp vmStructs_.hpp -+vmStructs.cpp vmStructs_.hpp -+vmStructs.cpp vmreg.hpp -+vmStructs.cpp watermark.hpp -+ -+vmStructs.hpp debug.hpp -diff -ruNb openjdk6/hotspot/src/share/vm/includeDB_gc_parallel openjdk/hotspot/src/share/vm/includeDB_gc_parallel ---- openjdk6/hotspot/src/share/vm/includeDB_gc_parallel 2008-07-10 22:04:28.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/includeDB_gc_parallel 2007-12-14 08:57:02.000000000 +0100 -@@ -42,11 +42,14 @@ - instanceKlass.cpp psScavenge.inline.hpp - instanceKlass.cpp parOopClosures.inline.hpp - -+instanceKlassKlass.cpp cardTableRS.hpp -+instanceKlassKlass.cpp oop.pcgc.inline.hpp - instanceKlassKlass.cpp psPromotionManager.inline.hpp - instanceKlassKlass.cpp psScavenge.inline.hpp -+instanceKlassKlass.cpp parOopClosures.inline.hpp - --instanceRefKlass.cpp psPromotionManager.inline.hpp - instanceRefKlass.cpp oop.pcgc.inline.hpp -+instanceRefKlass.cpp psPromotionManager.inline.hpp - instanceRefKlass.cpp psScavenge.inline.hpp - instanceRefKlass.cpp parOopClosures.inline.hpp - -diff -ruNb openjdk6/hotspot/src/share/vm/includeDB_jvmti openjdk/hotspot/src/share/vm/includeDB_jvmti ---- openjdk6/hotspot/src/share/vm/includeDB_jvmti 1970-01-01 01:00:00.000000000 +0100 -+++ openjdk/hotspot/src/share/vm/includeDB_jvmti 2007-12-14 08:57:02.000000000 +0100 -@@ -0,0 +1,257 @@ -+// -+// Copyright 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, -+// CA 95054 USA or visit www.sun.com if you need additional information or -+// have any questions. -+// -+// -+ -+jvmtiAgentThread.hpp jvmtiEnv.hpp -+ -+jvmtiClassFileReconstituter.cpp bytecodeStream.hpp -+jvmtiClassFileReconstituter.cpp bytes_.hpp -+jvmtiClassFileReconstituter.cpp jvmtiClassFileReconstituter.hpp -+jvmtiClassFileReconstituter.cpp symbolTable.hpp -+ -+jvmtiClassFileReconstituter.hpp jvmtiEnv.hpp -+ -+// jvmtiCodeBlobEvents is jck optional, please put deps in includeDB_features -+ -+jvmtiEnter.cpp jvmtiEnter.hpp -+jvmtiEnter.cpp jvmtiUtil.hpp -+ -+jvmtiEnter.hpp interfaceSupport.hpp -+jvmtiEnter.hpp jvmtiEnv.hpp -+jvmtiEnter.hpp jvmtiImpl.hpp -+jvmtiEnter.hpp resourceArea.hpp -+jvmtiEnter.hpp systemDictionary.hpp -+ -+jvmtiEnterTrace.cpp jvmtiEnter.hpp -+jvmtiEnterTrace.cpp jvmtiUtil.hpp -+ -+jvmtiEnv.cpp arguments.hpp -+jvmtiEnv.cpp bytecodeStream.hpp -+jvmtiEnv.cpp cpCacheOop.hpp -+jvmtiEnv.cpp deoptimization.hpp -+jvmtiEnv.cpp exceptions.hpp -+jvmtiEnv.cpp instanceKlass.hpp -+jvmtiEnv.cpp interfaceSupport.hpp -+jvmtiEnv.cpp interpreter.hpp -+jvmtiEnv.cpp javaCalls.hpp -+jvmtiEnv.cpp jfieldIDWorkaround.hpp -+jvmtiEnv.cpp jniCheck.hpp -+jvmtiEnv.cpp jvm_misc.hpp -+jvmtiEnv.cpp jvmtiAgentThread.hpp -+jvmtiEnv.cpp jvmtiClassFileReconstituter.hpp -+jvmtiEnv.cpp jvmtiCodeBlobEvents.hpp -+jvmtiEnv.cpp jvmtiEnv.hpp -+jvmtiEnv.cpp jvmtiExtensions.hpp -+jvmtiEnv.cpp jvmtiGetLoadedClasses.hpp -+jvmtiEnv.cpp jvmtiImpl.hpp -+jvmtiEnv.cpp jvmtiManageCapabilities.hpp -+jvmtiEnv.cpp jvmtiRedefineClasses.hpp -+jvmtiEnv.cpp jvmtiTagMap.hpp -+jvmtiEnv.cpp jvmtiThreadState.inline.hpp -+jvmtiEnv.cpp jvmtiUtil.hpp -+jvmtiEnv.cpp objectMonitor.inline.hpp -+jvmtiEnv.cpp osThread.hpp -+jvmtiEnv.cpp preserveException.hpp -+jvmtiEnv.cpp reflectionUtils.hpp -+jvmtiEnv.cpp resourceArea.hpp -+jvmtiEnv.cpp signature.hpp -+jvmtiEnv.cpp systemDictionary.hpp -+jvmtiEnv.cpp threadService.hpp -+jvmtiEnv.cpp thread_.inline.hpp -+jvmtiEnv.cpp universe.inline.hpp -+jvmtiEnv.cpp vframe.hpp -+jvmtiEnv.cpp vmSymbols.hpp -+jvmtiEnv.cpp vmThread.hpp -+ -+jvmtiEnv.hpp jvmtiEnvBase.hpp -+ -+jvmtiEnvBase.cpp biasedLocking.hpp -+jvmtiEnvBase.cpp interfaceSupport.hpp -+jvmtiEnvBase.cpp jfieldIDWorkaround.hpp -+jvmtiEnvBase.cpp jvmtiEnv.hpp -+jvmtiEnvBase.cpp jvmtiEnvBase.hpp -+jvmtiEnvBase.cpp jvmtiEventController.inline.hpp -+jvmtiEnvBase.cpp jvmtiExtensions.hpp -+jvmtiEnvBase.cpp jvmtiImpl.hpp -+jvmtiEnvBase.cpp jvmtiManageCapabilities.hpp -+jvmtiEnvBase.cpp jvmtiTagMap.hpp -+jvmtiEnvBase.cpp jvmtiThreadState.inline.hpp -+jvmtiEnvBase.cpp objArrayKlass.hpp -+jvmtiEnvBase.cpp objArrayOop.hpp -+jvmtiEnvBase.cpp objectMonitor.hpp -+jvmtiEnvBase.cpp objectMonitor.inline.hpp -+jvmtiEnvBase.cpp signature.hpp -+jvmtiEnvBase.cpp systemDictionary.hpp -+jvmtiEnvBase.cpp vframe.hpp -+jvmtiEnvBase.cpp vframe_hp.hpp -+jvmtiEnvBase.cpp vmThread.hpp -+jvmtiEnvBase.cpp vm_operations.hpp -+ -+jvmtiEnvBase.hpp classLoader.hpp -+jvmtiEnvBase.hpp fieldDescriptor.hpp -+jvmtiEnvBase.hpp frame.hpp -+jvmtiEnvBase.hpp growableArray.hpp -+jvmtiEnvBase.hpp handles.inline.hpp -+jvmtiEnvBase.hpp jvmtiEnvThreadState.hpp -+jvmtiEnvBase.hpp jvmtiEventController.hpp -+jvmtiEnvBase.hpp jvmtiThreadState.hpp -+jvmtiEnvBase.hpp thread.hpp -+jvmtiEnvBase.hpp vm_operations.hpp -+ -+jvmtiEnvThreadState.cpp handles.hpp -+jvmtiEnvThreadState.cpp handles.inline.hpp -+jvmtiEnvThreadState.cpp interfaceSupport.hpp -+jvmtiEnvThreadState.cpp interpreter.hpp -+jvmtiEnvThreadState.cpp javaCalls.hpp -+jvmtiEnvThreadState.cpp jvmtiEnv.hpp -+jvmtiEnvThreadState.cpp jvmtiEnvThreadState.hpp -+jvmtiEnvThreadState.cpp jvmtiEventController.inline.hpp -+jvmtiEnvThreadState.cpp jvmtiImpl.hpp -+jvmtiEnvThreadState.cpp resourceArea.hpp -+jvmtiEnvThreadState.cpp signature.hpp -+jvmtiEnvThreadState.cpp systemDictionary.hpp -+jvmtiEnvThreadState.cpp vframe.hpp -+jvmtiEnvThreadState.cpp vm_operations.hpp -+ -+jvmtiEnvThreadState.hpp allocation.hpp -+jvmtiEnvThreadState.hpp allocation.inline.hpp -+jvmtiEnvThreadState.hpp globalDefinitions.hpp -+jvmtiEnvThreadState.hpp growableArray.hpp -+jvmtiEnvThreadState.hpp instanceKlass.hpp -+jvmtiEnvThreadState.hpp jvmti.h -+jvmtiEnvThreadState.hpp jvmtiEventController.hpp -+ -+jvmtiEventController.cpp frame.hpp -+jvmtiEventController.cpp interpreter.hpp -+jvmtiEventController.cpp jvmtiEnv.hpp -+jvmtiEventController.cpp jvmtiEventController.hpp -+jvmtiEventController.cpp jvmtiEventController.inline.hpp -+jvmtiEventController.cpp jvmtiExport.hpp -+jvmtiEventController.cpp jvmtiImpl.hpp -+jvmtiEventController.cpp jvmtiThreadState.inline.hpp -+jvmtiEventController.cpp resourceArea.hpp -+jvmtiEventController.cpp thread.hpp -+jvmtiEventController.cpp vframe.hpp -+jvmtiEventController.cpp vframe_hp.hpp -+jvmtiEventController.cpp vmThread.hpp -+jvmtiEventController.cpp vm_operations.hpp -+ -+jvmtiEventController.hpp allocation.hpp -+jvmtiEventController.hpp allocation.inline.hpp -+jvmtiEventController.hpp globalDefinitions.hpp -+jvmtiEventController.hpp jvmti.h -+ -+jvmtiEventController.inline.hpp jvmtiEventController.hpp -+jvmtiEventController.inline.hpp jvmtiImpl.hpp -+jvmtiEventController.inline.hpp jvmtiUtil.hpp -+ -+jvmtiExport.cpp arguments.hpp -+jvmtiExport.cpp attachListener.hpp -+jvmtiExport.cpp handles.hpp -+jvmtiExport.cpp interfaceSupport.hpp -+jvmtiExport.cpp interpreter.hpp -+jvmtiExport.cpp jvmtiCodeBlobEvents.hpp -+jvmtiExport.cpp jvmtiEnv.hpp -+jvmtiExport.cpp jvmtiEventController.hpp -+jvmtiExport.cpp jvmtiEventController.inline.hpp -+jvmtiExport.cpp jvmtiExport.hpp -+jvmtiExport.cpp jvmtiImpl.hpp -+jvmtiExport.cpp jvmtiManageCapabilities.hpp -+jvmtiExport.cpp jvmtiTagMap.hpp -+jvmtiExport.cpp jvmtiThreadState.inline.hpp -+jvmtiExport.cpp nmethod.hpp -+jvmtiExport.cpp objArrayKlass.hpp -+jvmtiExport.cpp objArrayOop.hpp -+jvmtiExport.cpp objectMonitor.inline.hpp -+jvmtiExport.cpp pcDesc.hpp -+jvmtiExport.cpp resourceArea.hpp -+jvmtiExport.cpp scopeDesc.hpp -+jvmtiExport.cpp serviceUtil.hpp -+jvmtiExport.cpp systemDictionary.hpp -+jvmtiExport.cpp thread.hpp -+jvmtiExport.cpp vframe.hpp -+ -+// jvmtiExtensions is jck optional, please put deps in includeDB_features -+ -+jvmtiGetLoadedClasses.cpp jvmtiGetLoadedClasses.hpp -+jvmtiGetLoadedClasses.cpp systemDictionary.hpp -+jvmtiGetLoadedClasses.cpp thread.hpp -+jvmtiGetLoadedClasses.cpp universe.inline.hpp -+ -+jvmtiGetLoadedClasses.hpp jvmtiEnv.hpp -+ -+// jvmtiImpl is jck optional, please put deps in includeDB_features -+ -+jvmtiManageCapabilities.cpp jvmtiEnv.hpp -+jvmtiManageCapabilities.cpp jvmtiExport.hpp -+jvmtiManageCapabilities.cpp jvmtiManageCapabilities.hpp -+ -+jvmtiManageCapabilities.hpp allocation.hpp -+jvmtiManageCapabilities.hpp jvmti.h -+ -+jvmtiRedefineClasses.cpp codeCache.hpp -+jvmtiRedefineClasses.cpp deoptimization.hpp -+jvmtiRedefineClasses.cpp gcLocker.hpp -+jvmtiRedefineClasses.cpp jvmtiImpl.hpp -+jvmtiRedefineClasses.cpp jvmtiRedefineClasses.hpp -+jvmtiRedefineClasses.cpp klassVtable.hpp -+jvmtiRedefineClasses.cpp methodComparator.hpp -+jvmtiRedefineClasses.cpp oopMapCache.hpp -+jvmtiRedefineClasses.cpp relocator.hpp -+jvmtiRedefineClasses.cpp rewriter.hpp -+jvmtiRedefineClasses.cpp systemDictionary.hpp -+jvmtiRedefineClasses.cpp universe.inline.hpp -+jvmtiRedefineClasses.cpp verifier.hpp -+ -+jvmtiRedefineClasses.hpp jvmtiEnv.hpp -+jvmtiRedefineClasses.hpp jvmtiRedefineClassesTrace.hpp -+jvmtiRedefineClasses.hpp objArrayKlass.hpp -+jvmtiRedefineClasses.hpp objArrayOop.hpp -+jvmtiRedefineClasses.hpp oopFactory.hpp -+jvmtiRedefineClasses.hpp resourceArea.hpp -+jvmtiRedefineClasses.hpp vm_operations.hpp -+ -+// jvmtiTagMap is jck optional, please put deps in includeDB_features -+// jvmtiTrace is jck optional, please put deps in includeDB_features -+ -+jvmtiThreadState.cpp gcLocker.hpp -+jvmtiThreadState.cpp jvmtiEnv.hpp -+jvmtiThreadState.cpp jvmtiEventController.inline.hpp -+jvmtiThreadState.cpp jvmtiImpl.hpp -+jvmtiThreadState.cpp jvmtiThreadState.inline.hpp -+jvmtiThreadState.cpp resourceArea.hpp -+jvmtiThreadState.cpp vframe.hpp -+ -+jvmtiThreadState.inline.hpp jvmtiEnvThreadState.hpp -+jvmtiThreadState.inline.hpp jvmtiThreadState.hpp -+ -+jvmtiUtil.cpp exceptions.hpp -+jvmtiUtil.cpp handles.hpp -+jvmtiUtil.cpp handles.inline.hpp -+jvmtiUtil.cpp interfaceSupport.hpp -+jvmtiUtil.cpp jvmtiUtil.hpp -+jvmtiUtil.cpp vm_operations.hpp -+ -+jvmtiUtil.hpp jvmti.h -+jvmtiUtil.hpp jvmtiEventController.hpp -+jvmtiUtil.hpp resourceArea.hpp -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp openjdk/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp ---- openjdk6/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp 1970-01-01 01:00:00.000000000 +0100 -+++ openjdk/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -0,0 +1,245 @@ -+/* -+ * Copyright 1997-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, -+ * CA 95054 USA or visit www.sun.com if you need additional information or -+ * have any questions. -+ * -+ */ -+ -+// This file contains the platform-independant parts -+// of the abstract interpreter and the abstract interpreter generator. -+ -+// Organization of the interpreter(s). There exists two different interpreters in hotpot -+// an assembly language version (aka template interpreter) and a high level language version -+// (aka c++ interpreter). Th division of labor is as follows: -+ -+// Template Interpreter C++ Interpreter Functionality -+// -+// templateTable* bytecodeInterpreter* actual interpretation of bytecodes -+// -+// templateInterpreter* cppInterpreter* generation of assembly code that creates -+// and manages interpreter runtime frames. -+// Also code for populating interpreter -+// frames created during deoptimization. -+// -+// For both template and c++ interpreter. There are common files for aspects of the interpreter -+// that are generic to both interpreters. This is the layout: -+// -+// abstractInterpreter.hpp: generic description of the interpreter. -+// interpreter*: generic frame creation and handling. -+// -+ -+//------------------------------------------------------------------------------------------------------------------------ -+// The C++ interface to the bytecode interpreter(s). -+ -+class AbstractInterpreter: AllStatic { -+ friend class VMStructs; -+ friend class Interpreter; -+ friend class CppInterpreterGenerator; -+ public: -+ enum MethodKind { -+ zerolocals, // method needs locals initialization -+ zerolocals_synchronized, // method needs locals initialization & is synchronized -+ native, // native method -+ native_synchronized, // native method & is synchronized -+ empty, // empty method (code: _return) -+ accessor, // accessor method (code: _aload_0, _getfield, _(a|i)return) -+ abstract, // abstract method (throws an AbstractMethodException) -+ java_lang_math_sin, // implementation of java.lang.Math.sin (x) -+ java_lang_math_cos, // implementation of java.lang.Math.cos (x) -+ java_lang_math_tan, // implementation of java.lang.Math.tan (x) -+ java_lang_math_abs, // implementation of java.lang.Math.abs (x) -+ java_lang_math_sqrt, // implementation of java.lang.Math.sqrt (x) -+ java_lang_math_log, // implementation of java.lang.Math.log (x) -+ java_lang_math_log10, // implementation of java.lang.Math.log10 (x) -+ number_of_method_entries, -+ invalid = -1 -+ }; -+ -+ enum SomeConstants { -+ number_of_result_handlers = 10 // number of result handlers for native calls -+ }; -+ -+ protected: -+ static StubQueue* _code; // the interpreter code (codelets) -+ -+ static bool _notice_safepoints; // true if safepoints are activated -+ -+ static address _native_entry_begin; // Region for native entry code -+ static address _native_entry_end; -+ -+ // method entry points -+ static address _entry_table[number_of_method_entries]; // entry points for a given method -+ static address _native_abi_to_tosca[number_of_result_handlers]; // for native method result handlers -+ static address _slow_signature_handler; // the native method generic (slow) signature handler -+ -+ static address _rethrow_exception_entry; // rethrows an activation in previous frame -+ -+ -+ -+ friend class AbstractInterpreterGenerator; -+ friend class InterpreterGenerator; -+ friend class InterpreterMacroAssembler; -+ -+ public: -+ // Initialization/debugging -+ static void initialize(); -+ static StubQueue* code() { return _code; } -+ -+ -+ // Method activation -+ static MethodKind method_kind(methodHandle m); -+ static address entry_for_kind(MethodKind k) { assert(0 <= k && k < number_of_method_entries, "illegal kind"); return _entry_table[k]; } -+ static address entry_for_method(methodHandle m) { return _entry_table[method_kind(m)]; } -+ -+ static void print_method_kind(MethodKind kind) PRODUCT_RETURN; -+ -+ // Runtime support -+ -+ // length = invoke bytecode length (to advance to next bytecode) -+ static address deopt_entry (TosState state, int length) { ShouldNotReachHere(); return NULL; } -+ static address return_entry (TosState state, int length) { ShouldNotReachHere(); return NULL; } -+ -+ static address rethrow_exception_entry() { return _rethrow_exception_entry; } -+ -+ // Activation size in words for a method that is just being called. -+ // Parameters haven't been pushed so count them too. -+ static int size_top_interpreter_activation(methodOop method); -+ -+ // Deoptimization support -+ static address continuation_for(methodOop method, -+ address bcp, -+ int callee_parameters, -+ bool is_top_frame, -+ bool& use_next_mdp); -+ -+ // share implementation of size_activation and layout_activation: -+ static int size_activation(methodOop method, -+ int temps, -+ int popframe_args, -+ int monitors, -+ int callee_params, -+ int callee_locals, -+ bool is_top_frame); -+ -+ static int layout_activation(methodOop method, -+ int temps, -+ int popframe_args, -+ int monitors, -+ int callee_params, -+ int callee_locals, -+ frame* caller, -+ frame* interpreter_frame, -+ bool is_top_frame); -+ -+ // Runtime support -+ static bool is_not_reached( methodHandle method, int bci); -+ // Safepoint support -+ static void notice_safepoints() { ShouldNotReachHere(); } // stops the thread when reaching a safepoint -+ static void ignore_safepoints() { ShouldNotReachHere(); } // ignores safepoints -+ -+ // Support for native calls -+ static address slow_signature_handler() { return _slow_signature_handler; } -+ static address result_handler(BasicType type) { return _native_abi_to_tosca[BasicType_as_index(type)]; } -+ static int BasicType_as_index(BasicType type); // computes index into result_handler_by_index table -+ static bool in_native_entry(address pc) { return _native_entry_begin <= pc && pc < _native_entry_end; } -+ // Debugging/printing -+ static void print(); // prints the interpreter code -+ -+ // Support for Tagged Stacks -+ // -+ // Tags are stored on the Java Expression stack above the value: -+ // -+ // tag -+ // value -+ // -+ // For double values: -+ // -+ // tag2 -+ // high word -+ // tag1 -+ // low word -+ -+ public: -+ static int stackElementWords() { return TaggedStackInterpreter ? 2 : 1; } -+ static int stackElementSize() { return stackElementWords()*wordSize; } -+ static int logStackElementSize() { return -+ TaggedStackInterpreter? LogBytesPerWord+1 : LogBytesPerWord; } -+ -+ // Tag is at pointer, value is one below for a stack growing down -+ // (or above for stack growing up) -+ static int value_offset_in_bytes() { -+ return TaggedStackInterpreter ? -+ frame::interpreter_frame_expression_stack_direction() * wordSize : 0; -+ } -+ static int tag_offset_in_bytes() { -+ assert(TaggedStackInterpreter, "should not call this"); -+ return 0; -+ } -+ -+ // Tagged Locals -+ // Locals are stored relative to Llocals: -+ // -+ // tag <- Llocals[n] -+ // value -+ // -+ // Category 2 types are indexed as: -+ // -+ // tag <- Llocals[-n] -+ // high word -+ // tag <- Llocals[-n+1] -+ // low word -+ // -+ -+ // Local values relative to locals[n] -+ static int local_offset_in_bytes(int n) { -+ return ((frame::interpreter_frame_expression_stack_direction() * n) * -+ stackElementSize()) + value_offset_in_bytes(); -+ } -+ static int local_tag_offset_in_bytes(int n) { -+ assert(TaggedStackInterpreter, "should not call this"); -+ return ((frame::interpreter_frame_expression_stack_direction() * n) * -+ stackElementSize()) + tag_offset_in_bytes(); -+ } -+ -+}; -+ -+//------------------------------------------------------------------------------------------------------------------------ -+// The interpreter generator. -+ -+class Template; -+class AbstractInterpreterGenerator: public StackObj { -+ protected: -+ InterpreterMacroAssembler* _masm; -+ -+ // shared code sequences -+ // Converter for native abi result to tosca result -+ address generate_result_handler_for(BasicType type); -+ address generate_slow_signature_handler(); -+ -+ // entry point generator -+ address generate_method_entry(AbstractInterpreter::MethodKind kind); -+ -+ void bang_stack_shadow_pages(bool native_call); -+ -+ void generate_all(); -+ -+ public: -+ AbstractInterpreterGenerator(StubQueue* _code); -+}; -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/bytecode.cpp openjdk/hotspot/src/share/vm/interpreter/bytecode.cpp ---- openjdk6/hotspot/src/share/vm/interpreter/bytecode.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/interpreter/bytecode.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)bytecode.cpp 1.69 07/05/05 17:05:36 JVM" --#endif - /* - * Copyright 1997-2002 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -206,4 +203,3 @@ - } - - #endif -- -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/bytecode.hpp openjdk/hotspot/src/share/vm/interpreter/bytecode.hpp ---- openjdk6/hotspot/src/share/vm/interpreter/bytecode.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/interpreter/bytecode.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)bytecode.hpp 1.67 07/05/05 17:05:36 JVM" --#endif - /* - * Copyright 1997-2002 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/bytecodeHistogram.cpp openjdk/hotspot/src/share/vm/interpreter/bytecodeHistogram.cpp ---- openjdk6/hotspot/src/share/vm/interpreter/bytecodeHistogram.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/interpreter/bytecodeHistogram.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)bytecodeHistogram.cpp 1.29 07/05/05 17:05:36 JVM" --#endif - /* - * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/bytecodeHistogram.hpp openjdk/hotspot/src/share/vm/interpreter/bytecodeHistogram.hpp ---- openjdk6/hotspot/src/share/vm/interpreter/bytecodeHistogram.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/interpreter/bytecodeHistogram.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)bytecodeHistogram.hpp 1.27 07/05/05 17:05:36 JVM" --#endif - /* - * Copyright 1997-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -32,11 +29,8 @@ - NOT_PRODUCT(static int _counter_value;) - NOT_PRODUCT(static jlong _reset_time;) - -- friend class AbstractInterpreterGenerator; -- friend class InterpreterGenerator; --#ifdef CC_INTERP -- friend class cInterpreter; --#endif -+ friend class TemplateInterpreterGenerator; -+ friend class BytecodeInterpreter; - - public: - // Initialization -@@ -58,11 +52,9 @@ - private: - NOT_PRODUCT(static int _counters[Bytecodes::number_of_codes];) // a counter for each bytecode - -- friend class AbstractInterpreterGenerator; -+ friend class TemplateInterpreterGenerator; - friend class InterpreterGenerator; --#ifdef CC_INTERP -- friend class cInterpreter; --#endif -+ friend class BytecodeInterpreter; - - public: - // Initialization -@@ -88,7 +80,7 @@ - NOT_PRODUCT(static int _index;) // new bytecode is shifted in - used to index into _counters - NOT_PRODUCT(static int _counters[number_of_pairs];) // a counter for each pair - -- friend class AbstractInterpreterGenerator; -+ friend class TemplateInterpreterGenerator; - friend class InterpreterGenerator; - - public: -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp openjdk/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp ---- openjdk6/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp 1970-01-01 01:00:00.000000000 +0100 -+++ openjdk/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -0,0 +1,3047 @@ -+/* -+ * Copyright 2002-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, -+ * CA 95054 USA or visit www.sun.com if you need additional information or -+ * have any questions. -+ * -+ */ -+ -+ -+// no precompiled headers -+#include "incls/_bytecodeInterpreter.cpp.incl" -+ -+#ifdef CC_INTERP -+ -+/* -+ * USELABELS - If using GCC, then use labels for the opcode dispatching -+ * rather -then a switch statement. This improves performance because it -+ * gives us the oportunity to have the instructions that calculate the -+ * next opcode to jump to be intermixed with the rest of the instructions -+ * that implement the opcode (see UPDATE_PC_AND_TOS_AND_CONTINUE macro). -+ */ -+#undef USELABELS -+#ifdef __GNUC__ -+/* -+ ASSERT signifies debugging. It is much easier to step thru bytecodes if we -+ don't use the computed goto approach. -+*/ -+#ifndef ASSERT -+#define USELABELS -+#endif -+#endif -+ -+#undef CASE -+#ifdef USELABELS -+#define CASE(opcode) opc ## opcode -+#define DEFAULT opc_default -+#else -+#define CASE(opcode) case Bytecodes:: opcode -+#define DEFAULT default -+#endif -+ -+/* -+ * PREFETCH_OPCCODE - Some compilers do better if you prefetch the next -+ * opcode before going back to the top of the while loop, rather then having -+ * the top of the while loop handle it. This provides a better opportunity -+ * for instruction scheduling. Some compilers just do this prefetch -+ * automatically. Some actually end up with worse performance if you -+ * force the prefetch. Solaris gcc seems to do better, but cc does worse. -+ */ -+#undef PREFETCH_OPCCODE -+#define PREFETCH_OPCCODE -+ -+/* -+ Interpreter safepoint: it is expected that the interpreter will have no live -+ handles of its own creation live at an interpreter safepoint. Therefore we -+ run a HandleMarkCleaner and trash all handles allocated in the call chain -+ since the JavaCalls::call_helper invocation that initiated the chain. -+ There really shouldn't be any handles remaining to trash but this is cheap -+ in relation to a safepoint. -+*/ -+#define SAFEPOINT \ -+ if ( SafepointSynchronize::is_synchronizing()) { \ -+ { \ -+ /* zap freed handles rather than GC'ing them */ \ -+ HandleMarkCleaner __hmc(THREAD); \ -+ } \ -+ CALL_VM(SafepointSynchronize::block(THREAD), handle_exception); \ -+ } -+ -+/* -+ * VM_JAVA_ERROR - Macro for throwing a java exception from -+ * the interpreter loop. Should really be a CALL_VM but there -+ * is no entry point to do the transition to vm so we just -+ * do it by hand here. -+ */ -+#define VM_JAVA_ERROR_NO_JUMP(name, msg) \ -+ DECACHE_STATE(); \ -+ SET_LAST_JAVA_FRAME(); \ -+ { \ -+ ThreadInVMfromJava trans(THREAD); \ -+ Exceptions::_throw_msg(THREAD, __FILE__, __LINE__, name, msg); \ -+ } \ -+ RESET_LAST_JAVA_FRAME(); \ -+ CACHE_STATE(); -+ -+// Normal throw of a java error -+#define VM_JAVA_ERROR(name, msg) \ -+ VM_JAVA_ERROR_NO_JUMP(name, msg) \ -+ goto handle_exception; -+ -+#ifdef PRODUCT -+#define DO_UPDATE_INSTRUCTION_COUNT(opcode) -+#else -+#define DO_UPDATE_INSTRUCTION_COUNT(opcode) \ -+{ \ -+ BytecodeCounter::_counter_value++; \ -+ BytecodeHistogram::_counters[(Bytecodes::Code)opcode]++; \ -+ if (StopInterpreterAt && StopInterpreterAt == BytecodeCounter::_counter_value) os::breakpoint(); \ -+ if (TraceBytecodes) { \ -+ CALL_VM((void)SharedRuntime::trace_bytecode(THREAD, 0, \ -+ topOfStack[Interpreter::expr_index_at(1)], \ -+ topOfStack[Interpreter::expr_index_at(2)]), \ -+ handle_exception); \ -+ } \ -+} -+#endif -+ -+#undef DEBUGGER_SINGLE_STEP_NOTIFY -+#ifdef VM_JVMTI -+/* NOTE: (kbr) This macro must be called AFTER the PC has been -+ incremented. JvmtiExport::at_single_stepping_point() may cause a -+ breakpoint opcode to get inserted at the current PC to allow the -+ debugger to coalesce single-step events. -+ -+ As a result if we call at_single_stepping_point() we refetch opcode -+ to get the current opcode. This will override any other prefetching -+ that might have occurred. -+*/ -+#define DEBUGGER_SINGLE_STEP_NOTIFY() \ -+{ \ -+ if (_jvmti_interp_events) { \ -+ if (JvmtiExport::should_post_single_step()) { \ -+ DECACHE_STATE(); \ -+ SET_LAST_JAVA_FRAME(); \ -+ ThreadInVMfromJava trans(THREAD); \ -+ JvmtiExport::at_single_stepping_point(THREAD, \ -+ istate->method(), \ -+ pc); \ -+ RESET_LAST_JAVA_FRAME(); \ -+ CACHE_STATE(); \ -+ if (THREAD->pop_frame_pending() && \ -+ !THREAD->pop_frame_in_process()) { \ -+ goto handle_Pop_Frame; \ -+ } \ -+ opcode = *pc; \ -+ } \ -+ } \ -+} -+#else -+#define DEBUGGER_SINGLE_STEP_NOTIFY() -+#endif -+ -+/* -+ * CONTINUE - Macro for executing the next opcode. -+ */ -+#undef CONTINUE -+#ifdef USELABELS -+// Have to do this dispatch this way in C++ because otherwise gcc complains about crossing an -+// initialization (which is is the initialization of the table pointer...) -+#define DISPATCH(opcode) goto *dispatch_table[opcode] -+#define CONTINUE { \ -+ opcode = *pc; \ -+ DO_UPDATE_INSTRUCTION_COUNT(opcode); \ -+ DEBUGGER_SINGLE_STEP_NOTIFY(); \ -+ DISPATCH(opcode); \ -+ } -+#else -+#ifdef PREFETCH_OPCCODE -+#define CONTINUE { \ -+ opcode = *pc; \ -+ DO_UPDATE_INSTRUCTION_COUNT(opcode); \ -+ DEBUGGER_SINGLE_STEP_NOTIFY(); \ -+ continue; \ -+ } -+#else -+#define CONTINUE { \ -+ DO_UPDATE_INSTRUCTION_COUNT(opcode); \ -+ DEBUGGER_SINGLE_STEP_NOTIFY(); \ -+ continue; \ -+ } -+#endif -+#endif -+ -+// JavaStack Implementation -+#define MORE_STACK(count) \ -+ (topOfStack -= ((count) * Interpreter::stackElementWords())) -+ -+ -+#define UPDATE_PC(opsize) {pc += opsize; } -+/* -+ * UPDATE_PC_AND_TOS - Macro for updating the pc and topOfStack. -+ */ -+#undef UPDATE_PC_AND_TOS -+#define UPDATE_PC_AND_TOS(opsize, stack) \ -+ {pc += opsize; MORE_STACK(stack); } -+ -+/* -+ * UPDATE_PC_AND_TOS_AND_CONTINUE - Macro for updating the pc and topOfStack, -+ * and executing the next opcode. It's somewhat similar to the combination -+ * of UPDATE_PC_AND_TOS and CONTINUE, but with some minor optimizations. -+ */ -+#undef UPDATE_PC_AND_TOS_AND_CONTINUE -+#ifdef USELABELS -+#define UPDATE_PC_AND_TOS_AND_CONTINUE(opsize, stack) { \ -+ pc += opsize; opcode = *pc; MORE_STACK(stack); \ -+ DO_UPDATE_INSTRUCTION_COUNT(opcode); \ -+ DEBUGGER_SINGLE_STEP_NOTIFY(); \ -+ DISPATCH(opcode); \ -+ } -+ -+#define UPDATE_PC_AND_CONTINUE(opsize) { \ -+ pc += opsize; opcode = *pc; \ -+ DO_UPDATE_INSTRUCTION_COUNT(opcode); \ -+ DEBUGGER_SINGLE_STEP_NOTIFY(); \ -+ DISPATCH(opcode); \ -+ } -+#else -+#ifdef PREFETCH_OPCCODE -+#define UPDATE_PC_AND_TOS_AND_CONTINUE(opsize, stack) { \ -+ pc += opsize; opcode = *pc; MORE_STACK(stack); \ -+ DO_UPDATE_INSTRUCTION_COUNT(opcode); \ -+ DEBUGGER_SINGLE_STEP_NOTIFY(); \ -+ goto do_continue; \ -+ } -+ -+#define UPDATE_PC_AND_CONTINUE(opsize) { \ -+ pc += opsize; opcode = *pc; \ -+ DO_UPDATE_INSTRUCTION_COUNT(opcode); \ -+ DEBUGGER_SINGLE_STEP_NOTIFY(); \ -+ goto do_continue; \ -+ } -+#else -+#define UPDATE_PC_AND_TOS_AND_CONTINUE(opsize, stack) { \ -+ pc += opsize; MORE_STACK(stack); \ -+ DO_UPDATE_INSTRUCTION_COUNT(opcode); \ -+ DEBUGGER_SINGLE_STEP_NOTIFY(); \ -+ goto do_continue; \ -+ } -+ -+#define UPDATE_PC_AND_CONTINUE(opsize) { \ -+ pc += opsize; \ -+ DO_UPDATE_INSTRUCTION_COUNT(opcode); \ -+ DEBUGGER_SINGLE_STEP_NOTIFY(); \ -+ goto do_continue; \ -+ } -+#endif /* PREFETCH_OPCCODE */ -+#endif /* USELABELS */ -+ -+// About to call a new method, update the save the adjusted pc and return to frame manager -+#define UPDATE_PC_AND_RETURN(opsize) \ -+ DECACHE_TOS(); \ -+ istate->set_bcp(pc+opsize); \ -+ return; -+ -+ -+#define METHOD istate->method() -+#define INVOCATION_COUNT METHOD->invocation_counter() -+#define BACKEDGE_COUNT METHOD->backedge_counter() -+ -+ -+#define INCR_INVOCATION_COUNT INVOCATION_COUNT->increment() -+#define OSR_REQUEST(res, branch_pc) \ -+ CALL_VM(res=InterpreterRuntime::frequency_counter_overflow(THREAD, branch_pc), handle_exception); -+/* -+ * For those opcodes that need to have a GC point on a backwards branch -+ */ -+ -+// Backedge counting is kind of strange. The asm interpreter will increment -+// the backedge counter as a separate counter but it does it's comparisons -+// to the sum (scaled) of invocation counter and backedge count to make -+// a decision. Seems kind of odd to sum them together like that -+ -+// skip is delta from current bcp/bci for target, branch_pc is pre-branch bcp -+ -+ -+#define DO_BACKEDGE_CHECKS(skip, branch_pc) \ -+ if ((skip) <= 0) { \ -+ if (UseCompiler && UseLoopCounter) { \ -+ bool do_OSR = UseOnStackReplacement; \ -+ BACKEDGE_COUNT->increment(); \ -+ if (do_OSR) do_OSR = BACKEDGE_COUNT->reached_InvocationLimit(); \ -+ if (do_OSR) { \ -+ nmethod* osr_nmethod; \ -+ OSR_REQUEST(osr_nmethod, branch_pc); \ -+ if (osr_nmethod != NULL && osr_nmethod->osr_entry_bci() != InvalidOSREntryBci) { \ -+ intptr_t* buf; \ -+ CALL_VM(buf=SharedRuntime::OSR_migration_begin(THREAD), handle_exception); \ -+ istate->set_msg(do_osr); \ -+ istate->set_osr_buf((address)buf); \ -+ istate->set_osr_entry(osr_nmethod->osr_entry()); \ -+ return; \ -+ } \ -+ } else { \ -+ INCR_INVOCATION_COUNT; \ -+ SAFEPOINT; \ -+ } \ -+ } /* UseCompiler ... */ \ -+ INCR_INVOCATION_COUNT; \ -+ SAFEPOINT; \ -+ } -+ -+/* -+ * For those opcodes that need to have a GC point on a backwards branch -+ */ -+ -+/* -+ * Macros for caching and flushing the interpreter state. Some local -+ * variables need to be flushed out to the frame before we do certain -+ * things (like pushing frames or becomming gc safe) and some need to -+ * be recached later (like after popping a frame). We could use one -+ * macro to cache or decache everything, but this would be less then -+ * optimal because we don't always need to cache or decache everything -+ * because some things we know are already cached or decached. -+ */ -+#undef DECACHE_TOS -+#undef CACHE_TOS -+#undef CACHE_PREV_TOS -+#define DECACHE_TOS() istate->set_stack(topOfStack); -+ -+#define CACHE_TOS() topOfStack = (intptr_t *)istate->stack(); -+ -+#undef DECACHE_PC -+#undef CACHE_PC -+#define DECACHE_PC() istate->set_bcp(pc); -+#define CACHE_PC() pc = istate->bcp(); -+#define CACHE_CP() cp = istate->constants(); -+#define CACHE_LOCALS() locals = istate->locals(); -+#undef CACHE_FRAME -+#define CACHE_FRAME() -+ -+/* -+ * CHECK_NULL - Macro for throwing a NullPointerException if the object -+ * passed is a null ref. -+ * On some architectures/platforms it should be possible to do this implicitly -+ */ -+#undef CHECK_NULL -+#define CHECK_NULL(obj_) \ -+ if ((obj_) == 0) { \ -+ VM_JAVA_ERROR(vmSymbols::java_lang_NullPointerException(), ""); \ -+ } -+ -+#define VMdoubleConstZero() 0.0 -+#define VMdoubleConstOne() 1.0 -+#define VMlongConstZero() (max_jlong-max_jlong) -+#define VMlongConstOne() ((max_jlong-max_jlong)+1) -+ -+/* -+ * Alignment -+ */ -+#define VMalignWordUp(val) (((uintptr_t)(val) + 3) & ~3) -+ -+// Decache the interpreter state that interpreter modifies directly (i.e. GC is indirect mod) -+#define DECACHE_STATE() DECACHE_PC(); DECACHE_TOS(); -+ -+// Reload interpreter state after calling the VM or a possible GC -+#define CACHE_STATE() \ -+ CACHE_TOS(); \ -+ CACHE_PC(); \ -+ CACHE_CP(); \ -+ CACHE_LOCALS(); -+ -+// Call the VM don't check for pending exceptions -+#define CALL_VM_NOCHECK(func) \ -+ DECACHE_STATE(); \ -+ SET_LAST_JAVA_FRAME(); \ -+ func; \ -+ RESET_LAST_JAVA_FRAME(); \ -+ CACHE_STATE(); \ -+ if (THREAD->pop_frame_pending() && \ -+ !THREAD->pop_frame_in_process()) { \ -+ goto handle_Pop_Frame; \ -+ } -+ -+// Call the VM and check for pending exceptions -+#define CALL_VM(func, label) { \ -+ CALL_VM_NOCHECK(func); \ -+ if (THREAD->has_pending_exception()) goto label; \ -+ } -+ -+/* -+ * BytecodeInterpreter::run(interpreterState istate) -+ * BytecodeInterpreter::runWithChecks(interpreterState istate) -+ * -+ * The real deal. This is where byte codes actually get interpreted. -+ * Basically it's a big while loop that iterates until we return from -+ * the method passed in. -+ * -+ * The runWithChecks is used if JVMTI is enabled. -+ * -+ */ -+#if defined(VM_JVMTI) -+void -+BytecodeInterpreter::runWithChecks(interpreterState istate) { -+#else -+void -+BytecodeInterpreter::run(interpreterState istate) { -+#endif -+ -+ // In order to simplify some tests based on switches set at runtime -+ // we invoke the interpreter a single time after switches are enabled -+ // and set simpler to to test variables rather than method calls or complex -+ // boolean expressions. -+ -+ static int initialized = 0; -+ static int checkit = 0; -+ static intptr_t* c_addr = NULL; -+ static intptr_t c_value; -+ -+ if (checkit && *c_addr != c_value) { -+ os::breakpoint(); -+ } -+#ifdef VM_JVMTI -+ static bool _jvmti_interp_events = 0; -+#endif -+ -+ static int _compiling; // (UseCompiler || CountCompiledCalls) -+ -+#ifdef ASSERT -+ if (istate->_msg != initialize) { -+ assert(abs(istate->_stack_base - istate->_stack_limit) == (istate->_method->max_stack() + 1), "bad stack limit"); -+ IA32_ONLY(assert(istate->_stack_limit == istate->_thread->last_Java_sp() + 1, "wrong")); -+ } -+ // Verify linkages. -+ interpreterState l = istate; -+ do { -+ assert(l == l->_self_link, "bad link"); -+ l = l->_prev_link; -+ } while (l != NULL); -+ // Screwups with stack management usually cause us to overwrite istate -+ // save a copy so we can verify it. -+ interpreterState orig = istate; -+#endif -+ -+ static volatile jbyte* _byte_map_base; // adjusted card table base for oop store barrier -+ -+ register intptr_t* topOfStack = (intptr_t *)istate->stack(); /* access with STACK macros */ -+ register address pc = istate->bcp(); -+ register jubyte opcode; -+ register intptr_t* locals = istate->locals(); -+ register constantPoolCacheOop cp = istate->constants(); // method()->constants()->cache() -+#ifdef LOTS_OF_REGS -+ register JavaThread* THREAD = istate->thread(); -+ register volatile jbyte* BYTE_MAP_BASE = _byte_map_base; -+#else -+#undef THREAD -+#define THREAD istate->thread() -+#undef BYTE_MAP_BASE -+#define BYTE_MAP_BASE _byte_map_base -+#endif -+ -+#ifdef USELABELS -+ const static void* const opclabels_data[256] = { -+/* 0x00 */ &&opc_nop, &&opc_aconst_null,&&opc_iconst_m1,&&opc_iconst_0, -+/* 0x04 */ &&opc_iconst_1,&&opc_iconst_2, &&opc_iconst_3, &&opc_iconst_4, -+/* 0x08 */ &&opc_iconst_5,&&opc_lconst_0, &&opc_lconst_1, &&opc_fconst_0, -+/* 0x0C */ &&opc_fconst_1,&&opc_fconst_2, &&opc_dconst_0, &&opc_dconst_1, -+ -+/* 0x10 */ &&opc_bipush, &&opc_sipush, &&opc_ldc, &&opc_ldc_w, -+/* 0x14 */ &&opc_ldc2_w, &&opc_iload, &&opc_lload, &&opc_fload, -+/* 0x18 */ &&opc_dload, &&opc_aload, &&opc_iload_0,&&opc_iload_1, -+/* 0x1C */ &&opc_iload_2,&&opc_iload_3,&&opc_lload_0,&&opc_lload_1, -+ -+/* 0x20 */ &&opc_lload_2,&&opc_lload_3,&&opc_fload_0,&&opc_fload_1, -+/* 0x24 */ &&opc_fload_2,&&opc_fload_3,&&opc_dload_0,&&opc_dload_1, -+/* 0x28 */ &&opc_dload_2,&&opc_dload_3,&&opc_aload_0,&&opc_aload_1, -+/* 0x2C */ &&opc_aload_2,&&opc_aload_3,&&opc_iaload, &&opc_laload, -+ -+/* 0x30 */ &&opc_faload, &&opc_daload, &&opc_aaload, &&opc_baload, -+/* 0x34 */ &&opc_caload, &&opc_saload, &&opc_istore, &&opc_lstore, -+/* 0x38 */ &&opc_fstore, &&opc_dstore, &&opc_astore, &&opc_istore_0, -+/* 0x3C */ &&opc_istore_1,&&opc_istore_2,&&opc_istore_3,&&opc_lstore_0, -+ -+/* 0x40 */ &&opc_lstore_1,&&opc_lstore_2,&&opc_lstore_3,&&opc_fstore_0, -+/* 0x44 */ &&opc_fstore_1,&&opc_fstore_2,&&opc_fstore_3,&&opc_dstore_0, -+/* 0x48 */ &&opc_dstore_1,&&opc_dstore_2,&&opc_dstore_3,&&opc_astore_0, -+/* 0x4C */ &&opc_astore_1,&&opc_astore_2,&&opc_astore_3,&&opc_iastore, -+ -+/* 0x50 */ &&opc_lastore,&&opc_fastore,&&opc_dastore,&&opc_aastore, -+/* 0x54 */ &&opc_bastore,&&opc_castore,&&opc_sastore,&&opc_pop, -+/* 0x58 */ &&opc_pop2, &&opc_dup, &&opc_dup_x1, &&opc_dup_x2, -+/* 0x5C */ &&opc_dup2, &&opc_dup2_x1,&&opc_dup2_x2,&&opc_swap, -+ -+/* 0x60 */ &&opc_iadd,&&opc_ladd,&&opc_fadd,&&opc_dadd, -+/* 0x64 */ &&opc_isub,&&opc_lsub,&&opc_fsub,&&opc_dsub, -+/* 0x68 */ &&opc_imul,&&opc_lmul,&&opc_fmul,&&opc_dmul, -+/* 0x6C */ &&opc_idiv,&&opc_ldiv,&&opc_fdiv,&&opc_ddiv, -+ -+/* 0x70 */ &&opc_irem, &&opc_lrem, &&opc_frem,&&opc_drem, -+/* 0x74 */ &&opc_ineg, &&opc_lneg, &&opc_fneg,&&opc_dneg, -+/* 0x78 */ &&opc_ishl, &&opc_lshl, &&opc_ishr,&&opc_lshr, -+/* 0x7C */ &&opc_iushr,&&opc_lushr,&&opc_iand,&&opc_land, -+ -+/* 0x80 */ &&opc_ior, &&opc_lor,&&opc_ixor,&&opc_lxor, -+/* 0x84 */ &&opc_iinc,&&opc_i2l,&&opc_i2f, &&opc_i2d, -+/* 0x88 */ &&opc_l2i, &&opc_l2f,&&opc_l2d, &&opc_f2i, -+/* 0x8C */ &&opc_f2l, &&opc_f2d,&&opc_d2i, &&opc_d2l, -+ -+/* 0x90 */ &&opc_d2f, &&opc_i2b, &&opc_i2c, &&opc_i2s, -+/* 0x94 */ &&opc_lcmp, &&opc_fcmpl,&&opc_fcmpg,&&opc_dcmpl, -+/* 0x98 */ &&opc_dcmpg,&&opc_ifeq, &&opc_ifne, &&opc_iflt, -+/* 0x9C */ &&opc_ifge, &&opc_ifgt, &&opc_ifle, &&opc_if_icmpeq, -+ -+/* 0xA0 */ &&opc_if_icmpne,&&opc_if_icmplt,&&opc_if_icmpge, &&opc_if_icmpgt, -+/* 0xA4 */ &&opc_if_icmple,&&opc_if_acmpeq,&&opc_if_acmpne, &&opc_goto, -+/* 0xA8 */ &&opc_jsr, &&opc_ret, &&opc_tableswitch,&&opc_lookupswitch, -+/* 0xAC */ &&opc_ireturn, &&opc_lreturn, &&opc_freturn, &&opc_dreturn, -+ -+/* 0xB0 */ &&opc_areturn, &&opc_return, &&opc_getstatic, &&opc_putstatic, -+/* 0xB4 */ &&opc_getfield, &&opc_putfield, &&opc_invokevirtual,&&opc_invokespecial, -+/* 0xB8 */ &&opc_invokestatic,&&opc_invokeinterface,NULL, &&opc_new, -+/* 0xBC */ &&opc_newarray, &&opc_anewarray, &&opc_arraylength, &&opc_athrow, -+ -+/* 0xC0 */ &&opc_checkcast, &&opc_instanceof, &&opc_monitorenter, &&opc_monitorexit, -+/* 0xC4 */ &&opc_wide, &&opc_multianewarray, &&opc_ifnull, &&opc_ifnonnull, -+/* 0xC8 */ &&opc_goto_w, &&opc_jsr_w, &&opc_breakpoint, &&opc_fast_igetfield, -+/* 0xCC */ &&opc_fastagetfield,&&opc_fast_aload_0, &&opc_fast_iaccess_0, &&opc__fast_aaccess_0, -+ -+/* 0xD0 */ &&opc_fast_linearswitch, &&opc_fast_binaryswitch, &&opc_return_register_finalizer, &&opc_default, -+/* 0xD4 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, -+/* 0xD8 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, -+/* 0xDC */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, -+ -+/* 0xE0 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, -+/* 0xE4 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, -+/* 0xE8 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, -+/* 0xEC */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, -+ -+/* 0xF0 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, -+/* 0xF4 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, -+/* 0xF8 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, -+/* 0xFC */ &&opc_default, &&opc_default, &&opc_default, &&opc_default -+ }; -+ register uintptr_t *dispatch_table = (uintptr_t*)&opclabels_data[0]; -+#endif /* USELABELS */ -+ -+#ifdef ASSERT -+ // this will trigger a VERIFY_OOP on entry -+ if (istate->msg() != initialize && ! METHOD->is_static()) { -+ oop rcvr = LOCALS_OBJECT(0); -+ } -+#endif -+// #define HACK -+#ifdef HACK -+ bool interesting = false; -+#endif // HACK -+ -+ /* QQQ this should be a stack method so we don't know actual direction */ -+ assert(istate->msg() == initialize || -+ topOfStack >= istate->stack_limit() && -+ topOfStack < istate->stack_base(), -+ "Stack top out of range"); -+ -+ switch (istate->msg()) { -+ case initialize: { -+ if (initialized++) ShouldNotReachHere(); // Only one initialize call -+ _compiling = (UseCompiler || CountCompiledCalls); -+#ifdef VM_JVMTI -+ _jvmti_interp_events = JvmtiExport::can_post_interpreter_events(); -+#endif -+ BarrierSet* bs = Universe::heap()->barrier_set(); -+ assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind"); -+ _byte_map_base = (volatile jbyte*)(((CardTableModRefBS*)bs)->byte_map_base); -+ return; -+ } -+ break; -+ case method_entry: { -+ THREAD->set_do_not_unlock(); -+ // count invocations -+ assert(initialized, "Interpreter not initialized"); -+ if (_compiling) { -+ if (ProfileInterpreter) { -+ METHOD->increment_interpreter_invocation_count(); -+ } -+ INCR_INVOCATION_COUNT; -+ if (INVOCATION_COUNT->reached_InvocationLimit()) { -+ CALL_VM((void)InterpreterRuntime::frequency_counter_overflow(THREAD, NULL), handle_exception); -+ -+ // We no longer retry on a counter overflow -+ -+ // istate->set_msg(retry_method); -+ // THREAD->clr_do_not_unlock(); -+ // return; -+ } -+ SAFEPOINT; -+ } -+ -+ if ((istate->_stack_base - istate->_stack_limit) != istate->method()->max_stack() + 1) { -+ // initialize -+ os::breakpoint(); -+ } -+ -+#ifdef HACK -+ { -+ ResourceMark rm; -+ char *method_name = istate->method()->name_and_sig_as_C_string(); -+ if (strstr(method_name, "runThese$TestRunner.run()V") != NULL) { -+ tty->print_cr("entering: depth %d bci: %d", -+ (istate->_stack_base - istate->_stack), -+ istate->_bcp - istate->_method->code_base()); -+ interesting = true; -+ } -+ } -+#endif // HACK -+ -+ -+ // lock method if synchronized -+ if (METHOD->is_synchronized()) { -+ // oop rcvr = locals[0].j.r; -+ oop rcvr; -+ if (METHOD->is_static()) { -+ rcvr = METHOD->constants()->pool_holder()->klass_part()->java_mirror(); -+ } else { -+ rcvr = LOCALS_OBJECT(0); -+ } -+ // The initial monitor is ours for the taking -+ BasicObjectLock* mon = &istate->monitor_base()[-1]; -+ oop monobj = mon->obj(); -+ assert(mon->obj() == rcvr, "method monitor mis-initialized"); -+ -+ bool success = UseBiasedLocking; -+ if (UseBiasedLocking) { -+ markOop mark = rcvr->mark(); -+ if (mark->has_bias_pattern()) { -+ // The bias pattern is present in the object's header. Need to check -+ // whether the bias owner and the epoch are both still current. -+ intptr_t xx = ((intptr_t) THREAD) ^ (intptr_t) mark; -+ xx = (intptr_t) rcvr->klass()->klass_part()->prototype_header() ^ xx; -+ intptr_t yy = (xx & ~((int) markOopDesc::age_mask_in_place)); -+ if (yy != 0 ) { -+ // At this point we know that the header has the bias pattern and -+ // that we are not the bias owner in the current epoch. We need to -+ // figure out more details about the state of the header in order to -+ // know what operations can be legally performed on the object's -+ // header. -+ -+ // If the low three bits in the xor result aren't clear, that means -+ // the prototype header is no longer biased and we have to revoke -+ // the bias on this object. -+ -+ if (yy & markOopDesc::biased_lock_mask_in_place == 0 ) { -+ // Biasing is still enabled for this data type. See whether the -+ // epoch of the current bias is still valid, meaning that the epoch -+ // bits of the mark word are equal to the epoch bits of the -+ // prototype header. (Note that the prototype header's epoch bits -+ // only change at a safepoint.) If not, attempt to rebias the object -+ // toward the current thread. Note that we must be absolutely sure -+ // that the current epoch is invalid in order to do this because -+ // otherwise the manipulations it performs on the mark word are -+ // illegal. -+ if (yy & markOopDesc::epoch_mask_in_place == 0) { -+ // The epoch of the current bias is still valid but we know nothing -+ // about the owner; it might be set or it might be clear. Try to -+ // acquire the bias of the object using an atomic operation. If this -+ // fails we will go in to the runtime to revoke the object's bias. -+ // Note that we first construct the presumed unbiased header so we -+ // don't accidentally blow away another thread's valid bias. -+ intptr_t unbiased = (intptr_t) mark & (markOopDesc::biased_lock_mask_in_place | -+ markOopDesc::age_mask_in_place | -+ markOopDesc::epoch_mask_in_place); -+ if (Atomic::cmpxchg_ptr((intptr_t)THREAD | unbiased, (intptr_t*) rcvr->mark_addr(), unbiased) != unbiased) { -+ CALL_VM(InterpreterRuntime::monitorenter(THREAD, mon), handle_exception); -+ } -+ } else { -+ try_rebias: -+ // At this point we know the epoch has expired, meaning that the -+ // current "bias owner", if any, is actually invalid. Under these -+ // circumstances _only_, we are allowed to use the current header's -+ // value as the comparison value when doing the cas to acquire the -+ // bias in the current epoch. In other words, we allow transfer of -+ // the bias from one thread to another directly in this situation. -+ xx = (intptr_t) rcvr->klass()->klass_part()->prototype_header() | (intptr_t) THREAD; -+ if (Atomic::cmpxchg_ptr((intptr_t)THREAD | (intptr_t) rcvr->klass()->klass_part()->prototype_header(), -+ (intptr_t*) rcvr->mark_addr(), -+ (intptr_t) mark) != (intptr_t) mark) { -+ CALL_VM(InterpreterRuntime::monitorenter(THREAD, mon), handle_exception); -+ } -+ } -+ } else { -+ try_revoke_bias: -+ // The prototype mark in the klass doesn't have the bias bit set any -+ // more, indicating that objects of this data type are not supposed -+ // to be biased any more. We are going to try to reset the mark of -+ // this object to the prototype value and fall through to the -+ // CAS-based locking scheme. Note that if our CAS fails, it means -+ // that another thread raced us for the privilege of revoking the -+ // bias of this particular object, so it's okay to continue in the -+ // normal locking code. -+ // -+ xx = (intptr_t) rcvr->klass()->klass_part()->prototype_header() | (intptr_t) THREAD; -+ if (Atomic::cmpxchg_ptr(rcvr->klass()->klass_part()->prototype_header(), -+ (intptr_t*) rcvr->mark_addr(), -+ mark) == mark) { -+ // (*counters->revoked_lock_entry_count_addr())++; -+ success = false; -+ } -+ } -+ } -+ } else { -+ cas_label: -+ success = false; -+ } -+ } -+ if (!success) { -+ markOop displaced = rcvr->mark()->set_unlocked(); -+ mon->lock()->set_displaced_header(displaced); -+ if (Atomic::cmpxchg_ptr(mon, rcvr->mark_addr(), displaced) != displaced) { -+ // Is it simple recursive case? -+ if (THREAD->is_lock_owned((address) displaced->clear_lock_bits())) { -+ mon->lock()->set_displaced_header(NULL); -+ } else { -+ CALL_VM(InterpreterRuntime::monitorenter(THREAD, mon), handle_exception); -+ } -+ } -+ } -+ } -+ THREAD->clr_do_not_unlock(); -+ -+ // Notify jvmti -+#ifdef VM_JVMTI -+ if (_jvmti_interp_events) { -+ // Whenever JVMTI puts a thread in interp_only_mode, method -+ // entry/exit events are sent for that thread to track stack depth. -+ if (THREAD->is_interp_only_mode()) { -+ CALL_VM(InterpreterRuntime::post_method_entry(THREAD), -+ handle_exception); -+ } -+ } -+#endif /* VM_JVMTI */ -+ -+ goto run; -+ } -+ -+ case popping_frame: { -+ // returned from a java call to pop the frame, restart the call -+ // clear the message so we don't confuse ourselves later -+ assert(THREAD->pop_frame_in_process(), "wrong frame pop state"); -+ istate->set_msg(no_request); -+ THREAD->clr_pop_frame_in_process(); -+ goto run; -+ } -+ -+ case method_resume: { -+ if ((istate->_stack_base - istate->_stack_limit) != istate->method()->max_stack() + 1) { -+ // resume -+ os::breakpoint(); -+ } -+#ifdef HACK -+ { -+ ResourceMark rm; -+ char *method_name = istate->method()->name_and_sig_as_C_string(); -+ if (strstr(method_name, "runThese$TestRunner.run()V") != NULL) { -+ tty->print_cr("resume: depth %d bci: %d", -+ (istate->_stack_base - istate->_stack) , -+ istate->_bcp - istate->_method->code_base()); -+ interesting = true; -+ } -+ } -+#endif // HACK -+ // returned from a java call, continue executing. -+ if (THREAD->pop_frame_pending() && !THREAD->pop_frame_in_process()) { -+ goto handle_Pop_Frame; -+ } -+ -+ if (THREAD->has_pending_exception()) goto handle_exception; -+ // Update the pc by the saved amount of the invoke bytecode size -+ UPDATE_PC(istate->bcp_advance()); -+ goto run; -+ } -+ -+ case deopt_resume2: { -+ // Returned from an opcode that will reexecute. Deopt was -+ // a result of a PopFrame request. -+ // -+ goto run; -+ } -+ -+ case deopt_resume: { -+ // Returned from an opcode that has completed. The stack has -+ // the result all we need to do is skip across the bytecode -+ // and continue (assuming there is no exception pending) -+ // -+ // compute continuation length -+ // -+ // Note: it is possible to deopt at a return_register_finalizer opcode -+ // because this requires entering the vm to do the registering. While the -+ // opcode is complete we can't advance because there are no more opcodes -+ // much like trying to deopt at a poll return. In that has we simply -+ // get out of here -+ // -+ if ( Bytecodes::code_at(pc, METHOD) == Bytecodes::_return_register_finalizer) { -+ // this will do the right thing even if an exception is pending. -+ goto handle_return; -+ } -+ UPDATE_PC(Bytecodes::length_at(pc)); -+ if (THREAD->has_pending_exception()) goto handle_exception; -+ goto run; -+ } -+ case got_monitors: { -+ // continue locking now that we have a monitor to use -+ // we expect to find newly allocated monitor at the "top" of the monitor stack. -+ oop lockee = STACK_OBJECT(-1); -+ // derefing's lockee ought to provoke implicit null check -+ // find a free monitor -+ BasicObjectLock* entry = (BasicObjectLock*) istate->stack_base(); -+ assert(entry->obj() == NULL, "Frame manager didn't allocate the monitor"); -+ entry->set_obj(lockee); -+ -+ markOop displaced = lockee->mark()->set_unlocked(); -+ entry->lock()->set_displaced_header(displaced); -+ if (Atomic::cmpxchg_ptr(entry, lockee->mark_addr(), displaced) != displaced) { -+ // Is it simple recursive case? -+ if (THREAD->is_lock_owned((address) displaced->clear_lock_bits())) { -+ entry->lock()->set_displaced_header(NULL); -+ } else { -+ CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception); -+ } -+ } -+ UPDATE_PC_AND_TOS(1, -1); -+ goto run; -+ } -+ default: { -+ fatal("Unexpected message from frame manager"); -+ } -+ } -+ -+run: -+ -+ DO_UPDATE_INSTRUCTION_COUNT(*pc) -+ DEBUGGER_SINGLE_STEP_NOTIFY(); -+#ifdef PREFETCH_OPCCODE -+ opcode = *pc; /* prefetch first opcode */ -+#endif -+ -+#ifndef USELABELS -+ while (1) -+#endif -+ { -+#ifndef PREFETCH_OPCCODE -+ opcode = *pc; -+#endif -+ // Seems like this happens twice per opcode. At worst this is only -+ // need at entry to the loop. -+ // DEBUGGER_SINGLE_STEP_NOTIFY(); -+ /* Using this labels avoids double breakpoints when quickening and -+ * when returing from transition frames. -+ */ -+ opcode_switch: -+ assert(istate == orig, "Corrupted istate"); -+ /* QQQ Hmm this has knowledge of direction, ought to be a stack method */ -+ assert(topOfStack >= istate->stack_limit(), "Stack overrun"); -+ assert(topOfStack < istate->stack_base(), "Stack underrun"); -+ -+#ifdef USELABELS -+ DISPATCH(opcode); -+#else -+ switch (opcode) -+#endif -+ { -+ CASE(_nop): -+ UPDATE_PC_AND_CONTINUE(1); -+ -+ /* Push miscellaneous constants onto the stack. */ -+ -+ CASE(_aconst_null): -+ SET_STACK_OBJECT(NULL, 0); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); -+ -+#undef OPC_CONST_n -+#define OPC_CONST_n(opcode, const_type, value) \ -+ CASE(opcode): \ -+ SET_STACK_ ## const_type(value, 0); \ -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); -+ -+ OPC_CONST_n(_iconst_m1, INT, -1); -+ OPC_CONST_n(_iconst_0, INT, 0); -+ OPC_CONST_n(_iconst_1, INT, 1); -+ OPC_CONST_n(_iconst_2, INT, 2); -+ OPC_CONST_n(_iconst_3, INT, 3); -+ OPC_CONST_n(_iconst_4, INT, 4); -+ OPC_CONST_n(_iconst_5, INT, 5); -+ OPC_CONST_n(_fconst_0, FLOAT, 0.0); -+ OPC_CONST_n(_fconst_1, FLOAT, 1.0); -+ OPC_CONST_n(_fconst_2, FLOAT, 2.0); -+ -+#undef OPC_CONST2_n -+#define OPC_CONST2_n(opcname, value, key, kind) \ -+ CASE(_##opcname): \ -+ { \ -+ SET_STACK_ ## kind(VM##key##Const##value(), 1); \ -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); \ -+ } -+ OPC_CONST2_n(dconst_0, Zero, double, DOUBLE); -+ OPC_CONST2_n(dconst_1, One, double, DOUBLE); -+ OPC_CONST2_n(lconst_0, Zero, long, LONG); -+ OPC_CONST2_n(lconst_1, One, long, LONG); -+ -+ /* Load constant from constant pool: */ -+ -+ /* Push a 1-byte signed integer value onto the stack. */ -+ CASE(_bipush): -+ SET_STACK_INT((jbyte)(pc[1]), 0); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(2, 1); -+ -+ /* Push a 2-byte signed integer constant onto the stack. */ -+ CASE(_sipush): -+ SET_STACK_INT((int16_t)Bytes::get_Java_u2(pc + 1), 0); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(3, 1); -+ -+ /* load from local variable */ -+ -+ CASE(_aload): -+ SET_STACK_OBJECT(LOCALS_OBJECT(pc[1]), 0); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(2, 1); -+ -+ CASE(_iload): -+ CASE(_fload): -+ SET_STACK_SLOT(LOCALS_SLOT(pc[1]), 0); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(2, 1); -+ -+ CASE(_lload): -+ SET_STACK_LONG_FROM_ADDR(LOCALS_LONG_AT(pc[1]), 1); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(2, 2); -+ -+ CASE(_dload): -+ SET_STACK_DOUBLE_FROM_ADDR(LOCALS_DOUBLE_AT(pc[1]), 1); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(2, 2); -+ -+#undef OPC_LOAD_n -+#define OPC_LOAD_n(num) \ -+ CASE(_aload_##num): \ -+ SET_STACK_OBJECT(LOCALS_OBJECT(num), 0); \ -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); \ -+ \ -+ CASE(_iload_##num): \ -+ CASE(_fload_##num): \ -+ SET_STACK_SLOT(LOCALS_SLOT(num), 0); \ -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); \ -+ \ -+ CASE(_lload_##num): \ -+ SET_STACK_LONG_FROM_ADDR(LOCALS_LONG_AT(num), 1); \ -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); \ -+ CASE(_dload_##num): \ -+ SET_STACK_DOUBLE_FROM_ADDR(LOCALS_DOUBLE_AT(num), 1); \ -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); -+ -+ OPC_LOAD_n(0); -+ OPC_LOAD_n(1); -+ OPC_LOAD_n(2); -+ OPC_LOAD_n(3); -+ -+ /* store to a local variable */ -+ -+ CASE(_astore): -+ astore(topOfStack, -1, locals, pc[1]); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(2, -1); -+ -+ CASE(_istore): -+ CASE(_fstore): -+ SET_LOCALS_SLOT(STACK_SLOT(-1), pc[1]); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(2, -1); -+ -+ CASE(_lstore): -+ SET_LOCALS_LONG(STACK_LONG(-1), pc[1]); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(2, -2); -+ -+ CASE(_dstore): -+ SET_LOCALS_DOUBLE(STACK_DOUBLE(-1), pc[1]); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(2, -2); -+ -+ CASE(_wide): { -+ uint16_t reg = Bytes::get_Java_u2(pc + 2); -+ -+ opcode = pc[1]; -+ switch(opcode) { -+ case Bytecodes::_aload: -+ SET_STACK_OBJECT(LOCALS_OBJECT(reg), 0); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(4, 1); -+ -+ case Bytecodes::_iload: -+ case Bytecodes::_fload: -+ SET_STACK_SLOT(LOCALS_SLOT(reg), 0); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(4, 1); -+ -+ case Bytecodes::_lload: -+ SET_STACK_LONG_FROM_ADDR(LOCALS_LONG_AT(reg), 1); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(4, 2); -+ -+ case Bytecodes::_dload: -+ SET_STACK_DOUBLE_FROM_ADDR(LOCALS_LONG_AT(reg), 1); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(4, 2); -+ -+ case Bytecodes::_astore: -+ astore(topOfStack, -1, locals, reg); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(4, -1); -+ -+ case Bytecodes::_istore: -+ case Bytecodes::_fstore: -+ SET_LOCALS_SLOT(STACK_SLOT(-1), reg); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(4, -1); -+ -+ case Bytecodes::_lstore: -+ SET_LOCALS_LONG(STACK_LONG(-1), reg); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(4, -2); -+ -+ case Bytecodes::_dstore: -+ SET_LOCALS_DOUBLE(STACK_DOUBLE(-1), reg); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(4, -2); -+ -+ case Bytecodes::_iinc: { -+ int16_t offset = (int16_t)Bytes::get_Java_u2(pc+4); -+ // Be nice to see what this generates.... QQQ -+ SET_LOCALS_INT(LOCALS_INT(reg) + offset, reg); -+ UPDATE_PC_AND_CONTINUE(6); -+ } -+ case Bytecodes::_ret: -+ pc = istate->method()->code_base() + (intptr_t)(LOCALS_ADDR(reg)); -+ UPDATE_PC_AND_CONTINUE(0); -+ default: -+ VM_JAVA_ERROR(vmSymbols::java_lang_InternalError(), "undefined opcode"); -+ } -+ } -+ -+ -+#undef OPC_STORE_n -+#define OPC_STORE_n(num) \ -+ CASE(_astore_##num): \ -+ astore(topOfStack, -1, locals, num); \ -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); \ -+ CASE(_istore_##num): \ -+ CASE(_fstore_##num): \ -+ SET_LOCALS_SLOT(STACK_SLOT(-1), num); \ -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); -+ -+ OPC_STORE_n(0); -+ OPC_STORE_n(1); -+ OPC_STORE_n(2); -+ OPC_STORE_n(3); -+ -+#undef OPC_DSTORE_n -+#define OPC_DSTORE_n(num) \ -+ CASE(_dstore_##num): \ -+ SET_LOCALS_DOUBLE(STACK_DOUBLE(-1), num); \ -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -2); \ -+ CASE(_lstore_##num): \ -+ SET_LOCALS_LONG(STACK_LONG(-1), num); \ -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -2); -+ -+ OPC_DSTORE_n(0); -+ OPC_DSTORE_n(1); -+ OPC_DSTORE_n(2); -+ OPC_DSTORE_n(3); -+ -+ /* stack pop, dup, and insert opcodes */ -+ -+ -+ CASE(_pop): /* Discard the top item on the stack */ -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); -+ -+ -+ CASE(_pop2): /* Discard the top 2 items on the stack */ -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -2); -+ -+ -+ CASE(_dup): /* Duplicate the top item on the stack */ -+ dup(topOfStack); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); -+ -+ CASE(_dup2): /* Duplicate the top 2 items on the stack */ -+ dup2(topOfStack); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); -+ -+ CASE(_dup_x1): /* insert top word two down */ -+ dup_x1(topOfStack); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); -+ -+ CASE(_dup_x2): /* insert top word three down */ -+ dup_x2(topOfStack); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); -+ -+ CASE(_dup2_x1): /* insert top 2 slots three down */ -+ dup2_x1(topOfStack); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); -+ -+ CASE(_dup2_x2): /* insert top 2 slots four down */ -+ dup2_x2(topOfStack); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); -+ -+ CASE(_swap): { /* swap top two elements on the stack */ -+ swap(topOfStack); -+ UPDATE_PC_AND_CONTINUE(1); -+ } -+ -+ /* Perform various binary integer operations */ -+ -+#undef OPC_INT_BINARY -+#define OPC_INT_BINARY(opcname, opname, test) \ -+ CASE(_i##opcname): \ -+ if (test && (STACK_INT(-1) == 0)) { \ -+ VM_JAVA_ERROR(vmSymbols::java_lang_ArithmeticException(), \ -+ "/ by int zero"); \ -+ } \ -+ SET_STACK_INT(VMint##opname(STACK_INT(-2), \ -+ STACK_INT(-1)), \ -+ -2); \ -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); \ -+ CASE(_l##opcname): \ -+ { \ -+ if (test) { \ -+ jlong l1 = STACK_LONG(-1); \ -+ if (VMlongEqz(l1)) { \ -+ VM_JAVA_ERROR(vmSymbols::java_lang_ArithmeticException(), \ -+ "/ by long zero"); \ -+ } \ -+ } \ -+ /* First long at (-1,-2) next long at (-3,-4) */ \ -+ SET_STACK_LONG(VMlong##opname(STACK_LONG(-3), \ -+ STACK_LONG(-1)), \ -+ -3); \ -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -2); \ -+ } -+ -+ OPC_INT_BINARY(add, Add, 0); -+ OPC_INT_BINARY(sub, Sub, 0); -+ OPC_INT_BINARY(mul, Mul, 0); -+ OPC_INT_BINARY(and, And, 0); -+ OPC_INT_BINARY(or, Or, 0); -+ OPC_INT_BINARY(xor, Xor, 0); -+ OPC_INT_BINARY(div, Div, 1); -+ OPC_INT_BINARY(rem, Rem, 1); -+ -+ -+ /* Perform various binary floating number operations */ -+ /* On some machine/platforms/compilers div zero check can be implicit */ -+ -+#undef OPC_FLOAT_BINARY -+#define OPC_FLOAT_BINARY(opcname, opname) \ -+ CASE(_d##opcname): { \ -+ SET_STACK_DOUBLE(VMdouble##opname(STACK_DOUBLE(-3), \ -+ STACK_DOUBLE(-1)), \ -+ -3); \ -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -2); \ -+ } \ -+ CASE(_f##opcname): \ -+ SET_STACK_FLOAT(VMfloat##opname(STACK_FLOAT(-2), \ -+ STACK_FLOAT(-1)), \ -+ -2); \ -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); -+ -+ -+ OPC_FLOAT_BINARY(add, Add); -+ OPC_FLOAT_BINARY(sub, Sub); -+ OPC_FLOAT_BINARY(mul, Mul); -+ OPC_FLOAT_BINARY(div, Div); -+ OPC_FLOAT_BINARY(rem, Rem); -+ -+ /* Shift operations -+ * Shift left int and long: ishl, lshl -+ * Logical shift right int and long w/zero extension: iushr, lushr -+ * Arithmetic shift right int and long w/sign extension: ishr, lshr -+ */ -+ -+#undef OPC_SHIFT_BINARY -+#define OPC_SHIFT_BINARY(opcname, opname) \ -+ CASE(_i##opcname): \ -+ SET_STACK_INT(VMint##opname(STACK_INT(-2), \ -+ STACK_INT(-1)), \ -+ -2); \ -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); \ -+ CASE(_l##opcname): \ -+ { \ -+ SET_STACK_LONG(VMlong##opname(STACK_LONG(-2), \ -+ STACK_INT(-1)), \ -+ -2); \ -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); \ -+ } -+ -+ OPC_SHIFT_BINARY(shl, Shl); -+ OPC_SHIFT_BINARY(shr, Shr); -+ OPC_SHIFT_BINARY(ushr, Ushr); -+ -+ /* Increment local variable by constant */ -+ CASE(_iinc): -+ { -+ // locals[pc[1]].j.i += (jbyte)(pc[2]); -+ SET_LOCALS_INT(LOCALS_INT(pc[1]) + (jbyte)(pc[2]), pc[1]); -+ UPDATE_PC_AND_CONTINUE(3); -+ } -+ -+ /* negate the value on the top of the stack */ -+ -+ CASE(_ineg): -+ SET_STACK_INT(VMintNeg(STACK_INT(-1)), -1); -+ UPDATE_PC_AND_CONTINUE(1); -+ -+ CASE(_fneg): -+ SET_STACK_FLOAT(VMfloatNeg(STACK_FLOAT(-1)), -1); -+ UPDATE_PC_AND_CONTINUE(1); -+ -+ CASE(_lneg): -+ { -+ SET_STACK_LONG(VMlongNeg(STACK_LONG(-1)), -1); -+ UPDATE_PC_AND_CONTINUE(1); -+ } -+ -+ CASE(_dneg): -+ { -+ SET_STACK_DOUBLE(VMdoubleNeg(STACK_DOUBLE(-1)), -1); -+ UPDATE_PC_AND_CONTINUE(1); -+ } -+ -+ /* Conversion operations */ -+ -+ CASE(_i2f): /* convert top of stack int to float */ -+ SET_STACK_FLOAT(VMint2Float(STACK_INT(-1)), -1); -+ UPDATE_PC_AND_CONTINUE(1); -+ -+ CASE(_i2l): /* convert top of stack int to long */ -+ { -+ // this is ugly QQQ -+ jlong r = VMint2Long(STACK_INT(-1)); -+ MORE_STACK(-1); // Pop -+ SET_STACK_LONG(r, 1); -+ -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); -+ } -+ -+ CASE(_i2d): /* convert top of stack int to double */ -+ { -+ // this is ugly QQQ (why cast to jlong?? ) -+ jdouble r = (jlong)STACK_INT(-1); -+ MORE_STACK(-1); // Pop -+ SET_STACK_DOUBLE(r, 1); -+ -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); -+ } -+ -+ CASE(_l2i): /* convert top of stack long to int */ -+ { -+ jint r = VMlong2Int(STACK_LONG(-1)); -+ MORE_STACK(-2); // Pop -+ SET_STACK_INT(r, 0); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); -+ } -+ -+ CASE(_l2f): /* convert top of stack long to float */ -+ { -+ jlong r = STACK_LONG(-1); -+ MORE_STACK(-2); // Pop -+ SET_STACK_FLOAT(VMlong2Float(r), 0); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); -+ } -+ -+ CASE(_l2d): /* convert top of stack long to double */ -+ { -+ jlong r = STACK_LONG(-1); -+ MORE_STACK(-2); // Pop -+ SET_STACK_DOUBLE(VMlong2Double(r), 1); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); -+ } -+ -+ CASE(_f2i): /* Convert top of stack float to int */ -+ SET_STACK_INT(SharedRuntime::f2i(STACK_FLOAT(-1)), -1); -+ UPDATE_PC_AND_CONTINUE(1); -+ -+ CASE(_f2l): /* convert top of stack float to long */ -+ { -+ jlong r = SharedRuntime::f2l(STACK_FLOAT(-1)); -+ MORE_STACK(-1); // POP -+ SET_STACK_LONG(r, 1); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); -+ } -+ -+ CASE(_f2d): /* convert top of stack float to double */ -+ { -+ jfloat f; -+ jdouble r; -+ f = STACK_FLOAT(-1); -+#ifdef IA64 -+ // IA64 gcc bug -+ r = ( f == 0.0f ) ? (jdouble) f : (jdouble) f + ia64_double_zero; -+#else -+ r = (jdouble) f; -+#endif -+ MORE_STACK(-1); // POP -+ SET_STACK_DOUBLE(r, 1); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); -+ } -+ -+ CASE(_d2i): /* convert top of stack double to int */ -+ { -+ jint r1 = SharedRuntime::d2i(STACK_DOUBLE(-1)); -+ MORE_STACK(-2); -+ SET_STACK_INT(r1, 0); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); -+ } -+ -+ CASE(_d2f): /* convert top of stack double to float */ -+ { -+ jfloat r1 = VMdouble2Float(STACK_DOUBLE(-1)); -+ MORE_STACK(-2); -+ SET_STACK_FLOAT(r1, 0); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); -+ } -+ -+ CASE(_d2l): /* convert top of stack double to long */ -+ { -+ jlong r1 = SharedRuntime::d2l(STACK_DOUBLE(-1)); -+ MORE_STACK(-2); -+ SET_STACK_LONG(r1, 1); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); -+ } -+ -+ CASE(_i2b): -+ SET_STACK_INT(VMint2Byte(STACK_INT(-1)), -1); -+ UPDATE_PC_AND_CONTINUE(1); -+ -+ CASE(_i2c): -+ SET_STACK_INT(VMint2Char(STACK_INT(-1)), -1); -+ UPDATE_PC_AND_CONTINUE(1); -+ -+ CASE(_i2s): -+ SET_STACK_INT(VMint2Short(STACK_INT(-1)), -1); -+ UPDATE_PC_AND_CONTINUE(1); -+ -+ /* comparison operators */ -+ -+ -+#define COMPARISON_OP(name, comparison) \ -+ CASE(_if_icmp##name): { \ -+ int skip = (STACK_INT(-2) comparison STACK_INT(-1)) \ -+ ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3; \ -+ address branch_pc = pc; \ -+ UPDATE_PC_AND_TOS(skip, -2); \ -+ DO_BACKEDGE_CHECKS(skip, branch_pc); \ -+ CONTINUE; \ -+ } \ -+ CASE(_if##name): { \ -+ int skip = (STACK_INT(-1) comparison 0) \ -+ ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3; \ -+ address branch_pc = pc; \ -+ UPDATE_PC_AND_TOS(skip, -1); \ -+ DO_BACKEDGE_CHECKS(skip, branch_pc); \ -+ CONTINUE; \ -+ } -+ -+#define COMPARISON_OP2(name, comparison) \ -+ COMPARISON_OP(name, comparison) \ -+ CASE(_if_acmp##name): { \ -+ int skip = (STACK_OBJECT(-2) comparison STACK_OBJECT(-1)) \ -+ ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3; \ -+ address branch_pc = pc; \ -+ UPDATE_PC_AND_TOS(skip, -2); \ -+ DO_BACKEDGE_CHECKS(skip, branch_pc); \ -+ CONTINUE; \ -+ } -+ -+#define NULL_COMPARISON_NOT_OP(name) \ -+ CASE(_if##name): { \ -+ int skip = (!(STACK_OBJECT(-1) == 0)) \ -+ ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3; \ -+ address branch_pc = pc; \ -+ UPDATE_PC_AND_TOS(skip, -1); \ -+ DO_BACKEDGE_CHECKS(skip, branch_pc); \ -+ CONTINUE; \ -+ } -+ -+#define NULL_COMPARISON_OP(name) \ -+ CASE(_if##name): { \ -+ int skip = ((STACK_OBJECT(-1) == 0)) \ -+ ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3; \ -+ address branch_pc = pc; \ -+ UPDATE_PC_AND_TOS(skip, -1); \ -+ DO_BACKEDGE_CHECKS(skip, branch_pc); \ -+ CONTINUE; \ -+ } -+ COMPARISON_OP(lt, <); -+ COMPARISON_OP(gt, >); -+ COMPARISON_OP(le, <=); -+ COMPARISON_OP(ge, >=); -+ COMPARISON_OP2(eq, ==); /* include ref comparison */ -+ COMPARISON_OP2(ne, !=); /* include ref comparison */ -+ NULL_COMPARISON_OP(null); -+ NULL_COMPARISON_NOT_OP(nonnull); -+ -+ /* Goto pc at specified offset in switch table. */ -+ -+ CASE(_tableswitch): { -+ jint* lpc = (jint*)VMalignWordUp(pc+1); -+ int32_t key = STACK_INT(-1); -+ int32_t low = Bytes::get_Java_u4((address)&lpc[1]); -+ int32_t high = Bytes::get_Java_u4((address)&lpc[2]); -+ int32_t skip; -+ key -= low; -+ skip = ((uint32_t) key > (uint32_t)(high - low)) -+ ? Bytes::get_Java_u4((address)&lpc[0]) -+ : Bytes::get_Java_u4((address)&lpc[key + 3]); -+ // Does this really need a full backedge check (osr?) -+ address branch_pc = pc; -+ UPDATE_PC_AND_TOS(skip, -1); -+ DO_BACKEDGE_CHECKS(skip, branch_pc); -+ CONTINUE; -+ } -+ -+ /* Goto pc whose table entry matches specified key */ -+ -+ CASE(_lookupswitch): { -+ jint* lpc = (jint*)VMalignWordUp(pc+1); -+ int32_t key = STACK_INT(-1); -+ int32_t skip = Bytes::get_Java_u4((address) lpc); /* default amount */ -+ int32_t npairs = Bytes::get_Java_u4((address) &lpc[1]); -+ while (--npairs >= 0) { -+ lpc += 2; -+ if (key == (int32_t)Bytes::get_Java_u4((address)lpc)) { -+ skip = Bytes::get_Java_u4((address)&lpc[1]); -+ break; -+ } -+ } -+ address branch_pc = pc; -+ UPDATE_PC_AND_TOS(skip, -1); -+ DO_BACKEDGE_CHECKS(skip, branch_pc); -+ CONTINUE; -+ } -+ -+ CASE(_fcmpl): -+ CASE(_fcmpg): -+ { -+ SET_STACK_INT(VMfloatCompare(STACK_FLOAT(-2), -+ STACK_FLOAT(-1), -+ (opcode == Bytecodes::_fcmpl ? -1 : 1)), -+ -2); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); -+ } -+ -+ CASE(_dcmpl): -+ CASE(_dcmpg): -+ { -+ int r = VMdoubleCompare(STACK_DOUBLE(-3), -+ STACK_DOUBLE(-1), -+ (opcode == Bytecodes::_dcmpl ? -1 : 1)); -+ MORE_STACK(-4); // Pop -+ SET_STACK_INT(r, 0); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); -+ } -+ -+ CASE(_lcmp): -+ { -+ int r = VMlongCompare(STACK_LONG(-3), STACK_LONG(-1)); -+ MORE_STACK(-4); -+ SET_STACK_INT(r, 0); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); -+ } -+ -+ -+ /* Return from a method */ -+ -+ CASE(_areturn): -+ CASE(_ireturn): -+ CASE(_freturn): -+ { -+ // Allow a safepoint before returning to frame manager. -+ SAFEPOINT; -+ -+ goto handle_return; -+ } -+ -+ CASE(_lreturn): -+ CASE(_dreturn): -+ { -+ // Allow a safepoint before returning to frame manager. -+ SAFEPOINT; -+ goto handle_return; -+ } -+ -+ CASE(_return_register_finalizer): { -+ -+ oop rcvr = LOCALS_OBJECT(0); -+ if (rcvr->klass()->klass_part()->has_finalizer()) { -+ CALL_VM(InterpreterRuntime::register_finalizer(THREAD, rcvr), handle_exception); -+ } -+ goto handle_return; -+ } -+ CASE(_return): { -+ -+ // Allow a safepoint before returning to frame manager. -+ SAFEPOINT; -+ goto handle_return; -+ } -+ -+ /* Array access byte-codes */ -+ -+ /* Every array access byte-code starts out like this */ -+// arrayOopDesc* arrObj = (arrayOopDesc*)STACK_OBJECT(arrayOff); -+#define ARRAY_INTRO(arrayOff) \ -+ arrayOop arrObj = (arrayOop)STACK_OBJECT(arrayOff); \ -+ jint index = STACK_INT(arrayOff + 1); \ -+ char message[jintAsStringSize]; \ -+ CHECK_NULL(arrObj); \ -+ if ((uint32_t)index >= (uint32_t)arrObj->length()) { \ -+ sprintf(message, "%d", index); \ -+ VM_JAVA_ERROR(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), \ -+ message); \ -+ } -+ -+ /* 32-bit loads. These handle conversion from < 32-bit types */ -+#define ARRAY_LOADTO32(T, T2, format, stackRes, extra) \ -+ { \ -+ ARRAY_INTRO(-2); \ -+ extra; \ -+ SET_ ## stackRes(*(T2 *)(((address) arrObj->base(T)) + index * sizeof(T2)), \ -+ -2); \ -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); \ -+ } -+ -+ /* 64-bit loads */ -+#define ARRAY_LOADTO64(T,T2, stackRes, extra) \ -+ { \ -+ ARRAY_INTRO(-2); \ -+ SET_ ## stackRes(*(T2 *)(((address) arrObj->base(T)) + index * sizeof(T2)), -1); \ -+ extra; \ -+ UPDATE_PC_AND_CONTINUE(1); \ -+ } -+ -+ CASE(_iaload): -+ ARRAY_LOADTO32(T_INT, jint, "%d", STACK_INT, 0); -+ CASE(_faload): -+ ARRAY_LOADTO32(T_FLOAT, jfloat, "%f", STACK_FLOAT, 0); -+ CASE(_aaload): -+ ARRAY_LOADTO32(T_OBJECT, oop, INTPTR_FORMAT, STACK_OBJECT, 0); -+ CASE(_baload): -+ ARRAY_LOADTO32(T_BYTE, jbyte, "%d", STACK_INT, 0); -+ CASE(_caload): -+ ARRAY_LOADTO32(T_CHAR, jchar, "%d", STACK_INT, 0); -+ CASE(_saload): -+ ARRAY_LOADTO32(T_SHORT, jshort, "%d", STACK_INT, 0); -+ CASE(_laload): -+ ARRAY_LOADTO64(T_LONG, jlong, STACK_LONG, 0); -+ CASE(_daload): -+ ARRAY_LOADTO64(T_DOUBLE, jdouble, STACK_DOUBLE, 0); -+ -+ /* 32-bit stores. These handle conversion to < 32-bit types */ -+#define ARRAY_STOREFROM32(T, T2, format, stackSrc, extra) \ -+ { \ -+ ARRAY_INTRO(-3); \ -+ extra; \ -+ *(T2 *)(((address) arrObj->base(T)) + index * sizeof(T2)) = stackSrc( -1); \ -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -3); \ -+ } -+ -+ /* 64-bit stores */ -+#define ARRAY_STOREFROM64(T, T2, stackSrc, extra) \ -+ { \ -+ ARRAY_INTRO(-4); \ -+ extra; \ -+ *(T2 *)(((address) arrObj->base(T)) + index * sizeof(T2)) = stackSrc( -1); \ -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -4); \ -+ } -+ -+ CASE(_iastore): -+ ARRAY_STOREFROM32(T_INT, jint, "%d", STACK_INT, 0); -+ CASE(_fastore): -+ ARRAY_STOREFROM32(T_FLOAT, jfloat, "%f", STACK_FLOAT, 0); -+ /* -+ * This one looks different because of the assignability check -+ */ -+ CASE(_aastore): { -+ oop rhsObject = STACK_OBJECT(-1); -+ ARRAY_INTRO( -3); -+ // arrObj, index are set -+ if (rhsObject != NULL) { -+ /* Check assignability of rhsObject into arrObj */ -+ klassOop rhsKlassOop = rhsObject->klass(); // EBX (subclass) -+ assert(arrObj->klass()->klass()->klass_part()->oop_is_objArrayKlass(), "Ack not an objArrayKlass"); -+ klassOop elemKlassOop = ((objArrayKlass*) arrObj->klass()->klass_part())->element_klass(); // superklass EAX -+ // -+ // Check for compatibilty. This check must not GC!! -+ // Seems way more expensive now that we must dispatch -+ // -+ if (rhsKlassOop != elemKlassOop && !rhsKlassOop->klass_part()->is_subtype_of(elemKlassOop)) { // ebx->is... -+ VM_JAVA_ERROR(vmSymbols::java_lang_ArrayStoreException(), ""); -+ } -+ } -+ oop* elem_loc = (oop*)(((address) arrObj->base(T_OBJECT)) + index * sizeof(oop)); -+ // *(oop*)(((address) arrObj->base(T_OBJECT)) + index * sizeof(oop)) = rhsObject; -+ *elem_loc = rhsObject; -+ // Mark the card -+ OrderAccess::release_store(&BYTE_MAP_BASE[(uintptr_t)elem_loc >> CardTableModRefBS::card_shift], 0); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -3); -+ } -+ CASE(_bastore): -+ ARRAY_STOREFROM32(T_BYTE, jbyte, "%d", STACK_INT, 0); -+ CASE(_castore): -+ ARRAY_STOREFROM32(T_CHAR, jchar, "%d", STACK_INT, 0); -+ CASE(_sastore): -+ ARRAY_STOREFROM32(T_SHORT, jshort, "%d", STACK_INT, 0); -+ CASE(_lastore): -+ ARRAY_STOREFROM64(T_LONG, jlong, STACK_LONG, 0); -+ CASE(_dastore): -+ ARRAY_STOREFROM64(T_DOUBLE, jdouble, STACK_DOUBLE, 0); -+ -+ CASE(_arraylength): -+ { -+ arrayOop ary = (arrayOop) STACK_OBJECT(-1); -+ CHECK_NULL(ary); -+ SET_STACK_INT(ary->length(), -1); -+ UPDATE_PC_AND_CONTINUE(1); -+ } -+ -+ /* monitorenter and monitorexit for locking/unlocking an object */ -+ -+ CASE(_monitorenter): { -+ oop lockee = STACK_OBJECT(-1); -+ // derefing's lockee ought to provoke implicit null check -+ CHECK_NULL(lockee); -+ // find a free monitor or one already allocated for this object -+ // if we find a matching object then we need a new monitor -+ // since this is recursive enter -+ BasicObjectLock* limit = istate->monitor_base(); -+ BasicObjectLock* most_recent = (BasicObjectLock*) istate->stack_base(); -+ BasicObjectLock* entry = NULL; -+ while (most_recent != limit ) { -+ if (most_recent->obj() == NULL) entry = most_recent; -+ else if (most_recent->obj() == lockee) break; -+ most_recent++; -+ } -+ if (entry != NULL) { -+ entry->set_obj(lockee); -+ markOop displaced = lockee->mark()->set_unlocked(); -+ entry->lock()->set_displaced_header(displaced); -+ if (Atomic::cmpxchg_ptr(entry, lockee->mark_addr(), displaced) != displaced) { -+ // Is it simple recursive case? -+ if (THREAD->is_lock_owned((address) displaced->clear_lock_bits())) { -+ entry->lock()->set_displaced_header(NULL); -+ } else { -+ CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception); -+ } -+ } -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); -+ } else { -+ istate->set_msg(more_monitors); -+ UPDATE_PC_AND_RETURN(0); // Re-execute -+ } -+ } -+ -+ CASE(_monitorexit): { -+ oop lockee = STACK_OBJECT(-1); -+ CHECK_NULL(lockee); -+ // derefing's lockee ought to provoke implicit null check -+ // find our monitor slot -+ BasicObjectLock* limit = istate->monitor_base(); -+ BasicObjectLock* most_recent = (BasicObjectLock*) istate->stack_base(); -+ while (most_recent != limit ) { -+ if ((most_recent)->obj() == lockee) { -+ BasicLock* lock = most_recent->lock(); -+ markOop header = lock->displaced_header(); -+ most_recent->set_obj(NULL); -+ // If it isn't recursive we either must swap old header or call the runtime -+ if (header != NULL) { -+ if (Atomic::cmpxchg_ptr(header, lockee->mark_addr(), lock) != lock) { -+ // restore object for the slow case -+ most_recent->set_obj(lockee); -+ CALL_VM(InterpreterRuntime::monitorexit(THREAD, most_recent), handle_exception); -+ } -+ } -+ UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); -+ } -+ most_recent++; -+ } -+ // Need to throw illegal monitor state exception -+ CALL_VM(InterpreterRuntime::throw_illegal_monitor_state_exception(THREAD), handle_exception); -+ // Should never reach here... -+ assert(false, "Should have thrown illegal monitor exception"); -+ } -+ -+ /* All of the non-quick opcodes. */ -+ -+ /* -Set clobbersCpIndex true if the quickened opcode clobbers the -+ * constant pool index in the instruction. -+ */ -+ CASE(_getfield): -+ CASE(_getstatic): -+ { -+ u2 index; -+ ConstantPoolCacheEntry* cache; -+ index = Bytes::get_native_u2(pc+1); -+ -+ // QQQ Need to make this as inlined as possible. Probably need to -+ // split all the bytecode cases out so c++ compiler has a chance -+ // for constant prop to fold everything possible away. -+ -+ cache = cp->entry_at(index); -+ if (!cache->is_resolved((Bytecodes::Code)opcode)) { -+ CALL_VM(InterpreterRuntime::resolve_get_put(THREAD, (Bytecodes::Code)opcode), -+ handle_exception); -+ cache = cp->entry_at(index); -+ } -+ -+#ifdef VM_JVMTI -+ if (_jvmti_interp_events) { -+ int *count_addr; -+ oop obj; -+ // Check to see if a field modification watch has been set -+ // before we take the time to call into the VM. -+ count_addr = (int *)JvmtiExport::get_field_access_count_addr(); -+ if ( *count_addr > 0 ) { -+ if ((Bytecodes::Code)opcode == Bytecodes::_getstatic) { -+ obj = (oop)NULL; -+ } else { -+ obj = (oop) STACK_OBJECT(-1); -+ } -+ CALL_VM(InterpreterRuntime::post_field_access(THREAD, -+ obj, -+ cache), -+ handle_exception); -+ } -+ } -+#endif /* VM_JVMTI */ -+ -+ oop obj; -+ if ((Bytecodes::Code)opcode == Bytecodes::_getstatic) { -+ obj = (oop) cache->f1(); -+ MORE_STACK(1); // Assume single slot push -+ } else { -+ obj = (oop) STACK_OBJECT(-1); -+ CHECK_NULL(obj); -+ } -+ -+ // -+ // Now store the result on the stack -+ // -+ TosState tos_type = cache->flag_state(); -+ int field_offset = cache->f2(); -+ if (cache->is_volatile()) { -+ if (tos_type == atos) { -+ SET_STACK_OBJECT(obj->obj_field_acquire(field_offset), -1); -+ } else if (tos_type == itos) { -+ SET_STACK_INT(obj->int_field_acquire(field_offset), -1); -+ } else if (tos_type == ltos) { -+ SET_STACK_LONG(obj->long_field_acquire(field_offset), 0); -+ MORE_STACK(1); -+ } else if (tos_type == btos) { -+ SET_STACK_INT(obj->byte_field_acquire(field_offset), -1); -+ } else if (tos_type == ctos) { -+ SET_STACK_INT(obj->char_field_acquire(field_offset), -1); -+ } else if (tos_type == stos) { -+ SET_STACK_INT(obj->short_field_acquire(field_offset), -1); -+ } else if (tos_type == ftos) { -+ SET_STACK_FLOAT(obj->float_field_acquire(field_offset), -1); -+ } else { -+ SET_STACK_DOUBLE(obj->double_field_acquire(field_offset), 0); -+ MORE_STACK(1); -+ } -+ } else { -+ if (tos_type == atos) { -+ SET_STACK_OBJECT(obj->obj_field(field_offset), -1); -+ } else if (tos_type == itos) { -+ SET_STACK_INT(obj->int_field(field_offset), -1); -+ } else if (tos_type == ltos) { -+ SET_STACK_LONG(obj->long_field(field_offset), 0); -+ MORE_STACK(1); -+ } else if (tos_type == btos) { -+ SET_STACK_INT(obj->byte_field(field_offset), -1); -+ } else if (tos_type == ctos) { -+ SET_STACK_INT(obj->char_field(field_offset), -1); -+ } else if (tos_type == stos) { -+ SET_STACK_INT(obj->short_field(field_offset), -1); -+ } else if (tos_type == ftos) { -+ SET_STACK_FLOAT(obj->float_field(field_offset), -1); -+ } else { -+ SET_STACK_DOUBLE(obj->double_field(field_offset), 0); -+ MORE_STACK(1); -+ } -+ } -+ -+ UPDATE_PC_AND_CONTINUE(3); -+ } -+ -+ CASE(_putfield): -+ CASE(_putstatic): -+ { -+ u2 index = Bytes::get_native_u2(pc+1); -+ ConstantPoolCacheEntry* cache = cp->entry_at(index); -+ if (!cache->is_resolved((Bytecodes::Code)opcode)) { -+ CALL_VM(InterpreterRuntime::resolve_get_put(THREAD, (Bytecodes::Code)opcode), -+ handle_exception); -+ cache = cp->entry_at(index); -+ } -+ -+#ifdef VM_JVMTI -+ if (_jvmti_interp_events) { -+ int *count_addr; -+ oop obj; -+ // Check to see if a field modification watch has been set -+ // before we take the time to call into the VM. -+ count_addr = (int *)JvmtiExport::get_field_modification_count_addr(); -+ if ( *count_addr > 0 ) { -+ if ((Bytecodes::Code)opcode == Bytecodes::_putstatic) { -+ obj = (oop)NULL; -+ } -+ else { -+ if (cache->is_long() || cache->is_double()) { -+ obj = (oop) STACK_OBJECT(-3); -+ } else { -+ obj = (oop) STACK_OBJECT(-2); -+ } -+ } -+ -+ CALL_VM(InterpreterRuntime::post_field_modification(THREAD, -+ obj, -+ cache, -+ (jvalue *)STACK_SLOT(-1)), -+ handle_exception); -+ } -+ } -+#endif /* VM_JVMTI */ -+ -+ // QQQ Need to make this as inlined as possible. Probably need to split all the bytecode cases -+ // out so c++ compiler has a chance for constant prop to fold everything possible away. -+ -+ oop obj; -+ int count; -+ TosState tos_type = cache->flag_state(); -+ -+ count = -1; -+ if (tos_type == ltos || tos_type == dtos) { -+ --count; -+ } -+ if ((Bytecodes::Code)opcode == Bytecodes::_putstatic) { -+ obj = (oop) cache->f1(); -+ } else { -+ --count; -+ obj = (oop) STACK_OBJECT(count); -+ CHECK_NULL(obj); -+ } -+ -+ // -+ // Now store the result -+ // -+ int field_offset = cache->f2(); -+ if (cache->is_volatile()) { -+ if (tos_type == itos) { -+ obj->release_int_field_put(field_offset, STACK_INT(-1)); -+ } else if (tos_type == atos) { -+ obj->release_obj_field_put(field_offset, STACK_OBJECT(-1)); -+ OrderAccess::release_store(&BYTE_MAP_BASE[(uintptr_t)obj >> CardTableModRefBS::card_shift], 0); -+ } else if (tos_type == btos) { -+ obj->release_byte_field_put(field_offset, STACK_INT(-1)); -+ } else if (tos_type == ltos) { -+ obj->release_long_field_put(field_offset, STACK_LONG(-1)); -+ } else if (tos_type == ctos) { -+ obj->release_char_field_put(field_offset, STACK_INT(-1)); -+ } else if (tos_type == stos) { -+ obj->release_short_field_put(field_offset, STACK_INT(-1)); -+ } else if (tos_type == ftos) { -+ obj->release_float_field_put(field_offset, STACK_FLOAT(-1)); -+ } else { -+ obj->release_double_field_put(field_offset, STACK_DOUBLE(-1)); -+ } -+ OrderAccess::storeload(); -+ } else { -+ if (tos_type == itos) { -+ obj->int_field_put(field_offset, STACK_INT(-1)); -+ } else if (tos_type == atos) { -+ obj->obj_field_put(field_offset, STACK_OBJECT(-1)); -+ OrderAccess::release_store(&BYTE_MAP_BASE[(uintptr_t)obj >> CardTableModRefBS::card_shift], 0); -+ } else if (tos_type == btos) { -+ obj->byte_field_put(field_offset, STACK_INT(-1)); -+ } else if (tos_type == ltos) { -+ obj->long_field_put(field_offset, STACK_LONG(-1)); -+ } else if (tos_type == ctos) { -+ obj->char_field_put(field_offset, STACK_INT(-1)); -+ } else if (tos_type == stos) { -+ obj->short_field_put(field_offset, STACK_INT(-1)); -+ } else if (tos_type == ftos) { -+ obj->float_field_put(field_offset, STACK_FLOAT(-1)); -+ } else { -+ obj->double_field_put(field_offset, STACK_DOUBLE(-1)); -+ } -+ } -+ -+ UPDATE_PC_AND_TOS_AND_CONTINUE(3, count); -+ } -+ -+ CASE(_new): { -+ u2 index = Bytes::get_Java_u2(pc+1); -+ constantPoolOop constants = istate->method()->constants(); -+ if (!constants->tag_at(index).is_unresolved_klass()) { -+ // Make sure klass is initialized and doesn't have a finalizer -+ oop entry = (klassOop) *constants->obj_at_addr(index); -+ assert(entry->is_klass(), "Should be resolved klass"); -+ klassOop k_entry = (klassOop) entry; -+ assert(k_entry->klass_part()->oop_is_instance(), "Should be instanceKlass"); -+ instanceKlass* ik = (instanceKlass*) k_entry->klass_part(); -+ if ( ik->is_initialized() && ik->can_be_fastpath_allocated() ) { -+ size_t obj_size = ik->size_helper(); -+ oop result = NULL; -+ // If the TLAB isn't pre-zeroed then we'll have to do it -+ bool need_zero = !ZeroTLAB; -+ if (UseTLAB) { -+ result = (oop) THREAD->tlab().allocate(obj_size); -+ } -+ if (result == NULL) { -+ need_zero = true; -+ // Try allocate in shared eden -+ retry: -+ HeapWord* compare_to = *Universe::heap()->top_addr(); -+ HeapWord* new_top = compare_to + obj_size; -+ if (new_top <= *Universe::heap()->end_addr()) { -+ if (Atomic::cmpxchg_ptr(new_top, Universe::heap()->top_addr(), compare_to) != compare_to) { -+ goto retry; -+ } -+ result = (oop) compare_to; -+ } -+ } -+ if (result != NULL) { -+ // Initialize object (if nonzero size and need) and then the header -+ if (need_zero ) { -+ HeapWord* to_zero = (HeapWord*) result + sizeof(oopDesc) / oopSize; -+ obj_size -= sizeof(oopDesc) / oopSize; -+ if (obj_size > 0 ) { -+ memset(to_zero, 0, obj_size * HeapWordSize); -+ } -+ } -+ if (UseBiasedLocking) { -+ result->set_mark(ik->prototype_header()); -+ } else { -+ result->set_mark(markOopDesc::prototype()); -+ } -+ result->set_klass(k_entry); -+ SET_STACK_OBJECT(result, 0); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(3, 1); -+ } -+ } -+ } -+ // Slow case allocation -+ CALL_VM(InterpreterRuntime::_new(THREAD, METHOD->constants(), index), -+ handle_exception); -+ SET_STACK_OBJECT(THREAD->vm_result(), 0); -+ THREAD->set_vm_result(NULL); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(3, 1); -+ } -+ CASE(_anewarray): { -+ u2 index = Bytes::get_Java_u2(pc+1); -+ jint size = STACK_INT(-1); -+ CALL_VM(InterpreterRuntime::anewarray(THREAD, METHOD->constants(), index, size), -+ handle_exception); -+ SET_STACK_OBJECT(THREAD->vm_result(), -1); -+ THREAD->set_vm_result(NULL); -+ UPDATE_PC_AND_CONTINUE(3); -+ } -+ CASE(_multianewarray): { -+ jint dims = *(pc+3); -+ jint size = STACK_INT(-1); -+ // stack grows down, dimensions are up! -+ jint *dimarray = -+ (jint*)&topOfStack[dims * Interpreter::stackElementWords()+ -+ Interpreter::stackElementWords()-1]; -+ //adjust pointer to start of stack element -+ CALL_VM(InterpreterRuntime::multianewarray(THREAD, dimarray), -+ handle_exception); -+ SET_STACK_OBJECT(THREAD->vm_result(), -dims); -+ THREAD->set_vm_result(NULL); -+ UPDATE_PC_AND_TOS_AND_CONTINUE(4, -(dims-1)); -+ } -+ CASE(_checkcast): -+ if (STACK_OBJECT(-1) != NULL) { -+ u2 index = Bytes::get_Java_u2(pc+1); -+ if (ProfileInterpreter) { -+ // needs Profile_checkcast QQQ -+ ShouldNotReachHere(); -+ } -+ // Constant pool may have actual klass or unresolved klass. If it is -+ // unresolved we must resolve it -+ if (METHOD->constants()->tag_at(index).is_unresolved_klass()) { -+ CALL_VM(InterpreterRuntime::quicken_io_cc(THREAD), handle_exception); -+ } -+ klassOop klassOf = (klassOop) *(METHOD->constants()->obj_at_addr(index)); -+ klassOop objKlassOop = STACK_OBJECT(-1)->klass(); //ebx -+ // -+ // Check for compatibilty. This check must not GC!! -+ // Seems way more expensive now that we must dispatch -+ // -+ if (objKlassOop != klassOf && -+ !objKlassOop->klass_part()->is_subtype_of(klassOf)) { -+ ResourceMark rm(THREAD); -+ const char* objName = Klass::cast(objKlassOop)->external_name(); -+ const char* klassName = Klass::cast(klassOf)->external_name(); -+ char* message = SharedRuntime::generate_class_cast_message( -+ objName, klassName); -+ VM_JAVA_ERROR(vmSymbols::java_lang_ClassCastException(), message); -+ } -+ } else { -+ if (UncommonNullCast) { -+// istate->method()->set_null_cast_seen(); -+// [RGV] Not sure what to do here! -+ -+ } -+ } -+ UPDATE_PC_AND_CONTINUE(3); -+ -+ CASE(_instanceof): -+ if (STACK_OBJECT(-1) == NULL) { -+ SET_STACK_INT(0, -1); -+ } else { -+ u2 index = Bytes::get_Java_u2(pc+1); -+ // Constant pool may have actual klass or unresolved klass. If it is -+ // unresolved we must resolve it -+ if (METHOD->constants()->tag_at(index).is_unresolved_klass()) { -+ CALL_VM(InterpreterRuntime::quicken_io_cc(THREAD), handle_exception); -+ } -+ klassOop klassOf = (klassOop) *(METHOD->constants()->obj_at_addr(index)); -+ klassOop objKlassOop = STACK_OBJECT(-1)->klass(); -+ // -+ // Check for compatibilty. This check must not GC!! -+ // Seems way more expensive now that we must dispatch -+ // -+ if ( objKlassOop == klassOf || objKlassOop->klass_part()->is_subtype_of(klassOf)) { -+ SET_STACK_INT(1, -1); -+ } else { -+ SET_STACK_INT(0, -1); -+ } -+ } -+ UPDATE_PC_AND_CONTINUE(3); -+ -+ CASE(_ldc_w): -+ CASE(_ldc): -+ { -+ u2 index; -+ bool wide = false; -+ int incr = 2; // frequent case -+ if (opcode == Bytecodes::_ldc) { -+ index = pc[1]; -+ } else { -+ index = Bytes::get_Java_u2(pc+1); -+ incr = 3; -+ wide = true; -+ } -+ -+ constantPoolOop constants = METHOD->constants(); -+ switch (constants->tag_at(index).value()) { -+ case JVM_CONSTANT_Integer: -+ SET_STACK_INT(constants->int_at(index), 0); -+ break; -+ -+ case JVM_CONSTANT_Float: -+ SET_STACK_FLOAT(constants->float_at(index), 0); -+ break; -+ -+ case JVM_CONSTANT_String: -+ SET_STACK_OBJECT(constants->resolved_string_at(index), 0); -+ break; -+ -+ case JVM_CONSTANT_Class: -+ SET_STACK_OBJECT(constants->resolved_klass_at(index)->klass_part()->java_mirror(), 0); -+ break; -+ -+ case JVM_CONSTANT_UnresolvedString: -+ case JVM_CONSTANT_UnresolvedClass: -+ case JVM_CONSTANT_UnresolvedClassInError: -+ CALL_VM(InterpreterRuntime::ldc(THREAD, wide), handle_exception); -+ SET_STACK_OBJECT(THREAD->vm_result(), 0); -+ THREAD->set_vm_result(NULL); -+ break; -+ -+#if 0 -+ CASE(_fast_igetfield): -+ CASE(_fastagetfield): -+ CASE(_fast_aload_0): -+ CASE(_fast_iaccess_0): -+ CASE(__fast_aaccess_0): -+ CASE(_fast_linearswitch): -+ CASE(_fast_binaryswitch): -+ fatal("unsupported fast bytecode"); -+#endif -+ -+ default: ShouldNotReachHere(); -+ } -+ UPDATE_PC_AND_TOS_AND_CONTINUE(incr, 1); -+ } -+ -+ CASE(_ldc2_w): -+ { -+ u2 index = Bytes::get_Java_u2(pc+1); -+ -+ constantPoolOop constants = METHOD->constants(); -+ switch (constants->tag_at(index).value()) { -+ -+ case JVM_CONSTANT_Long: -+ SET_STACK_LONG(constants->long_at(index), 1); -+ break; -+ -+ case JVM_CONSTANT_Double: -+ SET_STACK_DOUBLE(constants->double_at(index), 1); -+ break; -+ default: ShouldNotReachHere(); -+ } -+ UPDATE_PC_AND_TOS_AND_CONTINUE(3, 2); -+ } -+ -+ CASE(_invokeinterface): { -+ u2 index = Bytes::get_native_u2(pc+1); -+ -+ // QQQ Need to make this as inlined as possible. Probably need to split all the bytecode cases -+ // out so c++ compiler has a chance for constant prop to fold everything possible away. -+ -+ ConstantPoolCacheEntry* cache = cp->entry_at(index); -+ if (!cache->is_resolved((Bytecodes::Code)opcode)) { -+ CALL_VM(InterpreterRuntime::resolve_invoke(THREAD, (Bytecodes::Code)opcode), -+ handle_exception); -+ cache = cp->entry_at(index); -+ } -+ -+ istate->set_msg(call_method); -+ -+ // Special case of invokeinterface called for virtual method of -+ // java.lang.Object. See cpCacheOop.cpp for details. -+ // This code isn't produced by javac, but could be produced by -+ // another compliant java compiler. -+ if (cache->is_methodInterface()) { -+ methodOop callee; -+ CHECK_NULL(STACK_OBJECT(-(cache->parameter_size()))); -+ if (cache->is_vfinal()) { -+ callee = (methodOop) cache->f2(); -+ } else { -+ // get receiver -+ int parms = cache->parameter_size(); -+ // Same comments as invokevirtual apply here -+ instanceKlass* rcvrKlass = (instanceKlass*) -+ STACK_OBJECT(-parms)->klass()->klass_part(); -+ callee = (methodOop) rcvrKlass->start_of_vtable()[ cache->f2()]; -+ } -+ istate->set_callee(callee); -+ istate->set_callee_entry_point(callee->from_interpreted_entry()); -+#ifdef VM_JVMTI -+ if (JvmtiExport::can_post_interpreter_events() && THREAD->is_interp_only_mode()) { -+ istate->set_callee_entry_point(callee->interpreter_entry()); -+ } -+#endif /* VM_JVMTI */ -+ istate->set_bcp_advance(5); -+ UPDATE_PC_AND_RETURN(0); // I'll be back... -+ } -+ -+ // this could definitely be cleaned up QQQ -+ methodOop callee; -+ klassOop iclass = (klassOop)cache->f1(); -+ // instanceKlass* interface = (instanceKlass*) iclass->klass_part(); -+ // get receiver -+ int parms = cache->parameter_size(); -+ oop rcvr = STACK_OBJECT(-parms); -+ CHECK_NULL(rcvr); -+ instanceKlass* int2 = (instanceKlass*) rcvr->klass()->klass_part(); -+ itableOffsetEntry* ki = (itableOffsetEntry*) int2->start_of_itable(); -+ int i; -+ for ( i = 0 ; i < int2->itable_length() ; i++, ki++ ) { -+ if (ki->interface_klass() == iclass) break; -+ } -+ // If the interface isn't found, this class doesn't implement this -+ // interface. The link resolver checks this but only for the first -+ // time this interface is called. -+ if (i == int2->itable_length()) { -+ VM_JAVA_ERROR(vmSymbols::java_lang_IncompatibleClassChangeError(), ""); -+ } -+ int mindex = cache->f2(); -+ itableMethodEntry* im = ki->first_method_entry(rcvr->klass()); -+ callee = im[mindex].method(); -+ if (callee == NULL) { -+ VM_JAVA_ERROR(vmSymbols::java_lang_AbstractMethodError(), ""); -+ } -+ -+ istate->set_callee(callee); -+ istate->set_callee_entry_point(callee->from_interpreted_entry()); -+#ifdef VM_JVMTI -+ if (JvmtiExport::can_post_interpreter_events() && THREAD->is_interp_only_mode()) { -+ istate->set_callee_entry_point(callee->interpreter_entry()); -+ } -+#endif /* VM_JVMTI */ -+ istate->set_bcp_advance(5); -+ UPDATE_PC_AND_RETURN(0); // I'll be back... -+ } -+ -+ CASE(_invokevirtual): -+ CASE(_invokespecial): -+ CASE(_invokestatic): { -+ u2 index = Bytes::get_native_u2(pc+1); -+ -+ ConstantPoolCacheEntry* cache = cp->entry_at(index); -+ // QQQ Need to make this as inlined as possible. Probably need to split all the bytecode cases -+ // out so c++ compiler has a chance for constant prop to fold everything possible away. -+ -+ if (!cache->is_resolved((Bytecodes::Code)opcode)) { -+ CALL_VM(InterpreterRuntime::resolve_invoke(THREAD, (Bytecodes::Code)opcode), -+ handle_exception); -+ cache = cp->entry_at(index); -+ } -+ -+ istate->set_msg(call_method); -+ { -+ methodOop callee; -+ if ((Bytecodes::Code)opcode == Bytecodes::_invokevirtual) { -+ CHECK_NULL(STACK_OBJECT(-(cache->parameter_size()))); -+ if (cache->is_vfinal()) callee = (methodOop) cache->f2(); -+ else { -+ // get receiver -+ int parms = cache->parameter_size(); -+ // this works but needs a resourcemark and seems to create a vtable on every call: -+ // methodOop callee = rcvr->klass()->klass_part()->vtable()->method_at(cache->f2()); -+ // -+ // this fails with an assert -+ // instanceKlass* rcvrKlass = instanceKlass::cast(STACK_OBJECT(-parms)->klass()); -+ // but this works -+ instanceKlass* rcvrKlass = (instanceKlass*) STACK_OBJECT(-parms)->klass()->klass_part(); -+ /* -+ Executing this code in java.lang.String: -+ public String(char value[]) { -+ this.count = value.length; -+ this.value = (char[])value.clone(); -+ } -+ -+ a find on rcvr->klass()->klass_part() reports: -+ {type array char}{type array class} -+ - klass: {other class} -+ -+ but using instanceKlass::cast(STACK_OBJECT(-parms)->klass()) causes in assertion failure -+ because rcvr->klass()->klass_part()->oop_is_instance() == 0 -+ However it seems to have a vtable in the right location. Huh? -+ -+ */ -+ callee = (methodOop) rcvrKlass->start_of_vtable()[ cache->f2()]; -+ } -+ } else { -+ if ((Bytecodes::Code)opcode == Bytecodes::_invokespecial) { -+ CHECK_NULL(STACK_OBJECT(-(cache->parameter_size()))); -+ } -+ callee = (methodOop) cache->f1(); -+ } -+ -+ istate->set_callee(callee); -+ istate->set_callee_entry_point(callee->from_interpreted_entry()); -+#ifdef VM_JVMTI -+ if (JvmtiExport::can_post_interpreter_events() && THREAD->is_interp_only_mode()) { -+ istate->set_callee_entry_point(callee->interpreter_entry()); -+ } -+#endif /* VM_JVMTI */ -+ istate->set_bcp_advance(3); -+ UPDATE_PC_AND_RETURN(0); // I'll be back... -+ } -+ } -+ -+ /* Allocate memory for a new java object. */ -+ -+ CASE(_newarray): { -+ BasicType atype = (BasicType) *(pc+1); -+ jint size = STACK_INT(-1); -+ CALL_VM(InterpreterRuntime::newarray(THREAD, atype, size), -+ handle_exception); -+ SET_STACK_OBJECT(THREAD->vm_result(), -1); -+ THREAD->set_vm_result(NULL); -+ -+ UPDATE_PC_AND_CONTINUE(2); -+ } -+ -+ /* Throw an exception. */ -+ -+ CASE(_athrow): { -+ oop except_oop = STACK_OBJECT(-1); -+ CHECK_NULL(except_oop); -+ // set pending_exception so we use common code -+ THREAD->set_pending_exception(except_oop, NULL, 0); -+ goto handle_exception; -+ } -+ -+ /* goto and jsr. They are exactly the same except jsr pushes -+ * the address of the next instruction first. -+ */ -+ -+ CASE(_jsr): { -+ /* push bytecode index on stack */ -+ SET_STACK_ADDR(((address)pc - (intptr_t)(istate->method()->code_base()) + 3), 0); -+ MORE_STACK(1); -+ /* FALL THROUGH */ -+ } -+ -+ CASE(_goto): -+ { -+ int16_t offset = (int16_t)Bytes::get_Java_u2(pc + 1); -+ address branch_pc = pc; -+ UPDATE_PC(offset); -+ DO_BACKEDGE_CHECKS(offset, branch_pc); -+ CONTINUE; -+ } -+ -+ CASE(_jsr_w): { -+ /* push return address on the stack */ -+ SET_STACK_ADDR(((address)pc - (intptr_t)(istate->method()->code_base()) + 5), 0); -+ MORE_STACK(1); -+ /* FALL THROUGH */ -+ } -+ -+ CASE(_goto_w): -+ { -+ int32_t offset = Bytes::get_Java_u4(pc + 1); -+ address branch_pc = pc; -+ UPDATE_PC(offset); -+ DO_BACKEDGE_CHECKS(offset, branch_pc); -+ CONTINUE; -+ } -+ -+ /* return from a jsr or jsr_w */ -+ -+ CASE(_ret): { -+ pc = istate->method()->code_base() + (intptr_t)(LOCALS_ADDR(pc[1])); -+ UPDATE_PC_AND_CONTINUE(0); -+ } -+ -+ /* debugger breakpoint */ -+ -+ CASE(_breakpoint): { -+ Bytecodes::Code original_bytecode; -+ DECACHE_STATE(); -+ SET_LAST_JAVA_FRAME(); -+ original_bytecode = InterpreterRuntime::get_original_bytecode_at(THREAD, -+ METHOD, pc); -+ RESET_LAST_JAVA_FRAME(); -+ CACHE_STATE(); -+ if (THREAD->has_pending_exception()) goto handle_exception; -+ CALL_VM(InterpreterRuntime::_breakpoint(THREAD, METHOD, pc), -+ handle_exception); -+ -+ opcode = (jubyte)original_bytecode; -+ goto opcode_switch; -+ } -+ -+ DEFAULT: -+ fatal2("\t*** Unimplemented opcode: %d = %s\n", -+ opcode, Bytecodes::name((Bytecodes::Code)opcode)); -+ goto finish; -+ -+ } /* switch(opc) */ -+ -+ -+#ifdef USELABELS -+ check_for_exception: -+#endif -+ { -+ if (!THREAD->has_pending_exception()) { -+ CONTINUE; -+ } -+ /* We will be gcsafe soon, so flush our state. */ -+ DECACHE_PC(); -+ goto handle_exception; -+ } -+ do_continue: ; -+ -+ } /* while (1) interpreter loop */ -+ -+ -+ // An exception exists in the thread state see whether this activation can handle it -+ handle_exception: { -+ -+ HandleMarkCleaner __hmc(THREAD); -+ Handle except_oop(THREAD, THREAD->pending_exception()); -+ // Prevent any subsequent HandleMarkCleaner in the VM -+ // from freeing the except_oop handle. -+ HandleMark __hm(THREAD); -+ -+ THREAD->clear_pending_exception(); -+ assert(except_oop(), "No exception to process"); -+ intptr_t continuation_bci; -+ // expression stack is emptied -+ topOfStack = istate->stack_base() - Interpreter::stackElementWords(); -+ CALL_VM(continuation_bci = (intptr_t)InterpreterRuntime::exception_handler_for_exception(THREAD, except_oop()), -+ handle_exception); -+ -+ except_oop = (oop) THREAD->vm_result(); -+ THREAD->set_vm_result(NULL); -+ if (continuation_bci >= 0) { -+ // Place exception on top of stack -+ SET_STACK_OBJECT(except_oop(), 0); -+ MORE_STACK(1); -+ pc = METHOD->code_base() + continuation_bci; -+ if (TraceExceptions) { -+ ttyLocker ttyl; -+ ResourceMark rm; -+ tty->print_cr("Exception <%s> (" INTPTR_FORMAT ")", except_oop->print_value_string(), except_oop()); -+ tty->print_cr(" thrown in interpreter method <%s>", METHOD->print_value_string()); -+ tty->print_cr(" at bci %d, continuing at %d for thread " INTPTR_FORMAT, -+ pc - (intptr_t)METHOD->code_base(), -+ continuation_bci, THREAD); -+ } -+ // for AbortVMOnException flag -+ NOT_PRODUCT(Exceptions::debug_check_abort(except_oop)); -+ goto run; -+ } -+ if (TraceExceptions) { -+ ttyLocker ttyl; -+ ResourceMark rm; -+ tty->print_cr("Exception <%s> (" INTPTR_FORMAT ")", except_oop->print_value_string(), except_oop()); -+ tty->print_cr(" thrown in interpreter method <%s>", METHOD->print_value_string()); -+ tty->print_cr(" at bci %d, unwinding for thread " INTPTR_FORMAT, -+ pc - (intptr_t) METHOD->code_base(), -+ THREAD); -+ } -+ // for AbortVMOnException flag -+ NOT_PRODUCT(Exceptions::debug_check_abort(except_oop)); -+ // No handler in this activation, unwind and try again -+ THREAD->set_pending_exception(except_oop(), NULL, 0); -+ goto handle_return; -+ } /* handle_exception: */ -+ -+ -+ -+ // Return from an interpreter invocation with the result of the interpretation -+ // on the top of the Java Stack (or a pending exception) -+ -+handle_Pop_Frame: -+ -+ // We don't really do anything special here except we must be aware -+ // that we can get here without ever locking the method (if sync). -+ // Also we skip the notification of the exit. -+ -+ istate->set_msg(popping_frame); -+ // Clear pending so while the pop is in process -+ // we don't start another one if a call_vm is done. -+ THREAD->clr_pop_frame_pending(); -+ // Let interpreter (only) see the we're in the process of popping a frame -+ THREAD->set_pop_frame_in_process(); -+ -+handle_return: -+ { -+ DECACHE_STATE(); -+ -+ bool suppress_error = istate->msg() == popping_frame; -+ bool suppress_exit_event = THREAD->has_pending_exception() || suppress_error; -+ Handle original_exception(THREAD, THREAD->pending_exception()); -+ Handle illegal_state_oop(THREAD, NULL); -+ -+ // We'd like a HandleMark here to prevent any subsequent HandleMarkCleaner -+ // in any following VM entries from freeing our live handles, but illegal_state_oop -+ // isn't really allocated yet and so doesn't become live until later and -+ // in unpredicatable places. Instead we must protect the places where we enter the -+ // VM. It would be much simpler (and safer) if we could allocate a real handle with -+ // a NULL oop in it and then overwrite the oop later as needed. This isn't -+ // unfortunately isn't possible. -+ -+ THREAD->clear_pending_exception(); -+ -+ // -+ // As far as we are concerned we have returned. If we have a pending exception -+ // that will be returned as this invocation's result. However if we get any -+ // exception(s) while checking monitor state one of those IllegalMonitorStateExceptions -+ // will be our final result (i.e. monitor exception trumps a pending exception). -+ // -+ -+ // If we never locked the method (or really passed the point where we would have), -+ // there is no need to unlock it (or look for other monitors), since that -+ // could not have happened. -+ -+ if (THREAD->do_not_unlock()) { -+ -+ // Never locked, reset the flag now because obviously any caller must -+ // have passed their point of locking for us to have gotten here. -+ -+ THREAD->clr_do_not_unlock(); -+ } else { -+ // At this point we consider that we have returned. We now check that the -+ // locks were properly block structured. If we find that they were not -+ // used properly we will return with an illegal monitor exception. -+ // The exception is checked by the caller not the callee since this -+ // checking is considered to be part of the invocation and therefore -+ // in the callers scope (JVM spec 8.13). -+ // -+ // Another weird thing to watch for is if the method was locked -+ // recursively and then not exited properly. This means we must -+ // examine all the entries in reverse time(and stack) order and -+ // unlock as we find them. If we find the method monitor before -+ // we are at the initial entry then we should throw an exception. -+ // It is not clear the template based interpreter does this -+ // correctly -+ -+ BasicObjectLock* base = istate->monitor_base(); -+ BasicObjectLock* end = (BasicObjectLock*) istate->stack_base(); -+ bool method_unlock_needed = METHOD->is_synchronized(); -+ // We know the initial monitor was used for the method don't check that -+ // slot in the loop -+ if (method_unlock_needed) base--; -+ -+ // Check all the monitors to see they are unlocked. Install exception if found to be locked. -+ while (end < base) { -+ oop lockee = end->obj(); -+ if (lockee != NULL) { -+ BasicLock* lock = end->lock(); -+ markOop header = lock->displaced_header(); -+ end->set_obj(NULL); -+ // If it isn't recursive we either must swap old header or call the runtime -+ if (header != NULL) { -+ if (Atomic::cmpxchg_ptr(header, lockee->mark_addr(), lock) != lock) { -+ // restore object for the slow case -+ end->set_obj(lockee); -+ { -+ // Prevent any HandleMarkCleaner from freeing our live handles -+ HandleMark __hm(THREAD); -+ CALL_VM_NOCHECK(InterpreterRuntime::monitorexit(THREAD, end)); -+ } -+ } -+ } -+ // One error is plenty -+ if (illegal_state_oop() == NULL && !suppress_error) { -+ { -+ // Prevent any HandleMarkCleaner from freeing our live handles -+ HandleMark __hm(THREAD); -+ CALL_VM_NOCHECK(InterpreterRuntime::throw_illegal_monitor_state_exception(THREAD)); -+ } -+ assert(THREAD->has_pending_exception(), "Lost our exception!"); -+ illegal_state_oop = THREAD->pending_exception(); -+ THREAD->clear_pending_exception(); -+ } -+ } -+ end++; -+ } -+ // Unlock the method if needed -+ if (method_unlock_needed) { -+ if (base->obj() == NULL) { -+ // The method is already unlocked this is not good. -+ if (illegal_state_oop() == NULL && !suppress_error) { -+ { -+ // Prevent any HandleMarkCleaner from freeing our live handles -+ HandleMark __hm(THREAD); -+ CALL_VM_NOCHECK(InterpreterRuntime::throw_illegal_monitor_state_exception(THREAD)); -+ } -+ assert(THREAD->has_pending_exception(), "Lost our exception!"); -+ illegal_state_oop = THREAD->pending_exception(); -+ THREAD->clear_pending_exception(); -+ } -+ } else { -+ // -+ // The initial monitor is always used for the method -+ // However if that slot is no longer the oop for the method it was unlocked -+ // and reused by something that wasn't unlocked! -+ // -+ // deopt can come in with rcvr dead because c2 knows -+ // its value is preserved in the monitor. So we can't use locals[0] at all -+ // and must use first monitor slot. -+ // -+ oop rcvr = base->obj(); -+ if (rcvr == NULL) { -+ if (!suppress_error) { -+ VM_JAVA_ERROR_NO_JUMP(vmSymbols::java_lang_NullPointerException(), ""); -+ illegal_state_oop = THREAD->pending_exception(); -+ THREAD->clear_pending_exception(); -+ } -+ } else { -+ BasicLock* lock = base->lock(); -+ markOop header = lock->displaced_header(); -+ base->set_obj(NULL); -+ // If it isn't recursive we either must swap old header or call the runtime -+ if (header != NULL) { -+ if (Atomic::cmpxchg_ptr(header, rcvr->mark_addr(), lock) != lock) { -+ // restore object for the slow case -+ base->set_obj(rcvr); -+ { -+ // Prevent any HandleMarkCleaner from freeing our live handles -+ HandleMark __hm(THREAD); -+ CALL_VM_NOCHECK(InterpreterRuntime::monitorexit(THREAD, base)); -+ } -+ if (THREAD->has_pending_exception()) { -+ if (!suppress_error) illegal_state_oop = THREAD->pending_exception(); -+ THREAD->clear_pending_exception(); -+ } -+ } -+ } -+ } -+ } -+ } -+ } -+ -+ // -+ // Notify jvmti/jvmdi -+ // -+ // NOTE: we do not notify a method_exit if we have a pending exception, -+ // including an exception we generate for unlocking checks. In the former -+ // case, JVMDI has already been notified by our call for the exception handler -+ // and in both cases as far as JVMDI is concerned we have already returned. -+ // If we notify it again JVMDI will be all confused about how many frames -+ // are still on the stack (4340444). -+ // -+ // NOTE Further! It turns out the the JVMTI spec in fact expects to see -+ // method_exit events whenever we leave an activation unless it was done -+ // for popframe. This is nothing like jvmdi. However we are passing the -+ // tests at the moment (apparently because they are jvmdi based) so rather -+ // than change this code and possibly fail tests we will leave it alone -+ // (with this note) in anticipation of changing the vm and the tests -+ // simultaneously. -+ -+ -+ // -+ suppress_exit_event = suppress_exit_event || illegal_state_oop() != NULL; -+ -+ -+ -+#ifdef VM_JVMTI -+ if (_jvmti_interp_events) { -+ // Whenever JVMTI puts a thread in interp_only_mode, method -+ // entry/exit events are sent for that thread to track stack depth. -+ if ( !suppress_exit_event && THREAD->is_interp_only_mode() ) { -+ { -+ // Prevent any HandleMarkCleaner from freeing our live handles -+ HandleMark __hm(THREAD); -+ CALL_VM_NOCHECK(InterpreterRuntime::post_method_exit(THREAD)); -+ } -+ } -+ } -+#endif /* VM_JVMTI */ -+ -+ // -+ // See if we are returning any exception -+ // A pending exception that was pending prior to a possible popping frame -+ // overrides the popping frame. -+ // -+ assert(!suppress_error || suppress_error && illegal_state_oop() == NULL, "Error was not suppressed"); -+ if (illegal_state_oop() != NULL || original_exception() != NULL) { -+ // inform the frame manager we have no result -+ istate->set_msg(throwing_exception); -+ if (illegal_state_oop() != NULL) -+ THREAD->set_pending_exception(illegal_state_oop(), NULL, 0); -+ else -+ THREAD->set_pending_exception(original_exception(), NULL, 0); -+ istate->set_return_kind((Bytecodes::Code)opcode); -+ UPDATE_PC_AND_RETURN(0); -+ } -+ -+ if (istate->msg() == popping_frame) { -+ // Make it simpler on the assembly code and set the message for the frame pop. -+ // returns -+ if (istate->prev() == NULL) { -+ // We must be returning to a deoptimized frame (because popframe only happens between -+ // two interpreted frames). We need to save the current arguments in C heap so that -+ // the deoptimized frame when it restarts can copy the arguments to its expression -+ // stack and re-execute the call. We also have to notify deoptimization that this -+ // has occured and to pick the preerved args copy them to the deoptimized frame's -+ // java expression stack. Yuck. -+ // -+ THREAD->popframe_preserve_args(in_ByteSize(METHOD->size_of_parameters() * wordSize), -+ LOCALS_SLOT(METHOD->size_of_parameters() - 1)); -+ THREAD->set_popframe_condition_bit(JavaThread::popframe_force_deopt_reexecution_bit); -+ } -+ UPDATE_PC_AND_RETURN(1); -+ } else { -+ // Normal return -+ // Advance the pc and return to frame manager -+ istate->set_msg(return_from_method); -+ istate->set_return_kind((Bytecodes::Code)opcode); -+ UPDATE_PC_AND_RETURN(1); -+ } -+ } /* handle_return: */ -+ -+// This is really a fatal error return -+ -+finish: -+ DECACHE_TOS(); -+ DECACHE_PC(); -+ -+ return; -+} -+ -+/* -+ * All the code following this point is only produced once and is not present -+ * in the JVMTI version of the interpreter -+*/ -+ -+#ifndef VM_JVMTI -+ -+// This constructor should only be used to contruct the object to signal -+// interpreter initialization. All other instances should be created by -+// the frame manager. -+BytecodeInterpreter::BytecodeInterpreter(messages msg) { -+ if (msg != initialize) ShouldNotReachHere(); -+ _msg = msg; -+ _self_link = this; -+ _prev_link = NULL; -+} -+ -+// Inline static functions for Java Stack and Local manipulation -+ -+// The implementations are platform dependent. We have to worry about alignment -+// issues on some machines which can change on the same platform depending on -+// whether it is an LP64 machine also. -+#ifdef ASSERT -+void BytecodeInterpreter::verify_stack_tag(intptr_t *tos, frame::Tag tag, int offset) { -+ if (TaggedStackInterpreter) { -+ frame::Tag t = (frame::Tag)tos[Interpreter::expr_tag_index_at(-offset)]; -+ assert(t == tag, "stack tag mismatch"); -+ } -+} -+#endif // ASSERT -+ -+address BytecodeInterpreter::stack_slot(intptr_t *tos, int offset) { -+ debug_only(verify_stack_tag(tos, frame::TagValue, offset)); -+ return (address) tos[Interpreter::expr_index_at(-offset)]; -+} -+ -+jint BytecodeInterpreter::stack_int(intptr_t *tos, int offset) { -+ debug_only(verify_stack_tag(tos, frame::TagValue, offset)); -+ return *((jint*) &tos[Interpreter::expr_index_at(-offset)]); -+} -+ -+jfloat BytecodeInterpreter::stack_float(intptr_t *tos, int offset) { -+ debug_only(verify_stack_tag(tos, frame::TagValue, offset)); -+ return *((jfloat *) &tos[Interpreter::expr_index_at(-offset)]); -+} -+ -+oop BytecodeInterpreter::stack_object(intptr_t *tos, int offset) { -+ debug_only(verify_stack_tag(tos, frame::TagReference, offset)); -+ return (oop)tos [Interpreter::expr_index_at(-offset)]; -+} -+ -+jdouble BytecodeInterpreter::stack_double(intptr_t *tos, int offset) { -+ debug_only(verify_stack_tag(tos, frame::TagValue, offset)); -+ debug_only(verify_stack_tag(tos, frame::TagValue, offset-1)); -+ return ((VMJavaVal64*) &tos[Interpreter::expr_index_at(-offset)])->d; -+} -+ -+jlong BytecodeInterpreter::stack_long(intptr_t *tos, int offset) { -+ debug_only(verify_stack_tag(tos, frame::TagValue, offset)); -+ debug_only(verify_stack_tag(tos, frame::TagValue, offset-1)); -+ return ((VMJavaVal64 *) &tos[Interpreter::expr_index_at(-offset)])->l; -+} -+ -+void BytecodeInterpreter::tag_stack(intptr_t *tos, frame::Tag tag, int offset) { -+ if (TaggedStackInterpreter) -+ tos[Interpreter::expr_tag_index_at(-offset)] = (intptr_t)tag; -+} -+ -+// only used for value types -+void BytecodeInterpreter::set_stack_slot(intptr_t *tos, address value, -+ int offset) { -+ tag_stack(tos, frame::TagValue, offset); -+ *((address *)&tos[Interpreter::expr_index_at(-offset)]) = value; -+} -+ -+void BytecodeInterpreter::set_stack_int(intptr_t *tos, int value, -+ int offset) { -+ tag_stack(tos, frame::TagValue, offset); -+ *((jint *)&tos[Interpreter::expr_index_at(-offset)]) = value; -+} -+ -+void BytecodeInterpreter::set_stack_float(intptr_t *tos, jfloat value, -+ int offset) { -+ tag_stack(tos, frame::TagValue, offset); -+ *((jfloat *)&tos[Interpreter::expr_index_at(-offset)]) = value; -+} -+ -+void BytecodeInterpreter::set_stack_object(intptr_t *tos, oop value, -+ int offset) { -+ tag_stack(tos, frame::TagReference, offset); -+ *((oop *)&tos[Interpreter::expr_index_at(-offset)]) = value; -+} -+ -+// needs to be platform dep for the 32 bit platforms. -+void BytecodeInterpreter::set_stack_double(intptr_t *tos, jdouble value, -+ int offset) { -+ tag_stack(tos, frame::TagValue, offset); -+ tag_stack(tos, frame::TagValue, offset-1); -+ ((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset)])->d = value; -+} -+ -+void BytecodeInterpreter::set_stack_double_from_addr(intptr_t *tos, -+ address addr, int offset) { -+ tag_stack(tos, frame::TagValue, offset); -+ tag_stack(tos, frame::TagValue, offset-1); -+ (((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset)])->d = -+ ((VMJavaVal64*)addr)->d); -+} -+ -+void BytecodeInterpreter::set_stack_long(intptr_t *tos, jlong value, -+ int offset) { -+ tag_stack(tos, frame::TagValue, offset); -+ ((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset+1)])->l = 0xdeedbeeb; -+ tag_stack(tos, frame::TagValue, offset-1); -+ ((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset)])->l = value; -+} -+ -+void BytecodeInterpreter::set_stack_long_from_addr(intptr_t *tos, -+ address addr, int offset) { -+ tag_stack(tos, frame::TagValue, offset); -+ ((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset+1)])->l = 0xdeedbeeb; -+ tag_stack(tos, frame::TagValue, offset-1); -+ ((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset)])->l = -+ ((VMJavaVal64*)addr)->l; -+} -+ -+// Locals -+ -+#ifdef ASSERT -+void BytecodeInterpreter::verify_locals_tag(intptr_t *locals, frame::Tag tag, -+ int offset) { -+ if (TaggedStackInterpreter) { -+ frame::Tag t = (frame::Tag)locals[Interpreter::local_tag_index_at(-offset)]; -+ assert(t == tag, "locals tag mismatch"); -+ } -+} -+#endif // ASSERT -+address BytecodeInterpreter::locals_slot(intptr_t* locals, int offset) { -+ debug_only(verify_locals_tag(locals, frame::TagValue, offset)); -+ return (address)locals[Interpreter::local_index_at(-offset)]; -+} -+jint BytecodeInterpreter::locals_int(intptr_t* locals, int offset) { -+ debug_only(verify_locals_tag(locals, frame::TagValue, offset)); -+ return (jint)locals[Interpreter::local_index_at(-offset)]; -+} -+jfloat BytecodeInterpreter::locals_float(intptr_t* locals, int offset) { -+ debug_only(verify_locals_tag(locals, frame::TagValue, offset)); -+ return (jfloat)locals[Interpreter::local_index_at(-offset)]; -+} -+oop BytecodeInterpreter::locals_object(intptr_t* locals, int offset) { -+ debug_only(verify_locals_tag(locals, frame::TagReference, offset)); -+ return (oop)locals[Interpreter::local_index_at(-offset)]; -+} -+jdouble BytecodeInterpreter::locals_double(intptr_t* locals, int offset) { -+ debug_only(verify_locals_tag(locals, frame::TagValue, offset)); -+ debug_only(verify_locals_tag(locals, frame::TagValue, offset)); -+ return ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->d; -+} -+jlong BytecodeInterpreter::locals_long(intptr_t* locals, int offset) { -+ debug_only(verify_locals_tag(locals, frame::TagValue, offset)); -+ debug_only(verify_locals_tag(locals, frame::TagValue, offset+1)); -+ return ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->l; -+} -+ -+// Returns the address of locals value. -+address BytecodeInterpreter::locals_long_at(intptr_t* locals, int offset) { -+ debug_only(verify_locals_tag(locals, frame::TagValue, offset)); -+ debug_only(verify_locals_tag(locals, frame::TagValue, offset+1)); -+ return ((address)&locals[Interpreter::local_index_at(-(offset+1))]); -+} -+address BytecodeInterpreter::locals_double_at(intptr_t* locals, int offset) { -+ debug_only(verify_locals_tag(locals, frame::TagValue, offset)); -+ debug_only(verify_locals_tag(locals, frame::TagValue, offset+1)); -+ return ((address)&locals[Interpreter::local_index_at(-(offset+1))]); -+} -+ -+void BytecodeInterpreter::tag_locals(intptr_t *locals, frame::Tag tag, int offset) { -+ if (TaggedStackInterpreter) -+ locals[Interpreter::local_tag_index_at(-offset)] = (intptr_t)tag; -+} -+ -+// Used for local value or returnAddress -+void BytecodeInterpreter::set_locals_slot(intptr_t *locals, -+ address value, int offset) { -+ tag_locals(locals, frame::TagValue, offset); -+ *((address*)&locals[Interpreter::local_index_at(-offset)]) = value; -+} -+void BytecodeInterpreter::set_locals_int(intptr_t *locals, -+ jint value, int offset) { -+ tag_locals(locals, frame::TagValue, offset); -+ *((jint *)&locals[Interpreter::local_index_at(-offset)]) = value; -+} -+void BytecodeInterpreter::set_locals_float(intptr_t *locals, -+ jfloat value, int offset) { -+ tag_locals(locals, frame::TagValue, offset); -+ *((jfloat *)&locals[Interpreter::local_index_at(-offset)]) = value; -+} -+void BytecodeInterpreter::set_locals_object(intptr_t *locals, -+ oop value, int offset) { -+ tag_locals(locals, frame::TagReference, offset); -+ *((oop *)&locals[Interpreter::local_index_at(-offset)]) = value; -+} -+void BytecodeInterpreter::set_locals_double(intptr_t *locals, -+ jdouble value, int offset) { -+ tag_locals(locals, frame::TagValue, offset); -+ tag_locals(locals, frame::TagValue, offset+1); -+ ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->d = value; -+} -+void BytecodeInterpreter::set_locals_long(intptr_t *locals, -+ jlong value, int offset) { -+ tag_locals(locals, frame::TagValue, offset); -+ tag_locals(locals, frame::TagValue, offset+1); -+ ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->l = value; -+} -+void BytecodeInterpreter::set_locals_double_from_addr(intptr_t *locals, -+ address addr, int offset) { -+ tag_locals(locals, frame::TagValue, offset); -+ tag_locals(locals, frame::TagValue, offset+1); -+ ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->d = ((VMJavaVal64*)addr)->d; -+} -+void BytecodeInterpreter::set_locals_long_from_addr(intptr_t *locals, -+ address addr, int offset) { -+ tag_locals(locals, frame::TagValue, offset); -+ tag_locals(locals, frame::TagValue, offset+1); -+ ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->l = ((VMJavaVal64*)addr)->l; -+} -+ -+void BytecodeInterpreter::astore(intptr_t* tos, int stack_offset, -+ intptr_t* locals, int locals_offset) { -+ // Copy tag from stack to locals. astore's operand can be returnAddress -+ // and may not be TagReference -+ if (TaggedStackInterpreter) { -+ frame::Tag t = (frame::Tag) tos[Interpreter::expr_tag_index_at(-stack_offset)]; -+ locals[Interpreter::local_tag_index_at(-locals_offset)] = (intptr_t)t; -+ } -+ intptr_t value = tos[Interpreter::expr_index_at(-stack_offset)]; -+ locals[Interpreter::local_index_at(-locals_offset)] = value; -+} -+ -+ -+void BytecodeInterpreter::copy_stack_slot(intptr_t *tos, int from_offset, -+ int to_offset) { -+ if (TaggedStackInterpreter) { -+ tos[Interpreter::expr_tag_index_at(-to_offset)] = -+ (intptr_t)tos[Interpreter::expr_tag_index_at(-from_offset)]; -+ } -+ tos[Interpreter::expr_index_at(-to_offset)] = -+ (intptr_t)tos[Interpreter::expr_index_at(-from_offset)]; -+} -+ -+void BytecodeInterpreter::dup(intptr_t *tos) { -+ copy_stack_slot(tos, -1, 0); -+} -+void BytecodeInterpreter::dup2(intptr_t *tos) { -+ copy_stack_slot(tos, -2, 0); -+ copy_stack_slot(tos, -1, 1); -+} -+ -+void BytecodeInterpreter::dup_x1(intptr_t *tos) { -+ /* insert top word two down */ -+ copy_stack_slot(tos, -1, 0); -+ copy_stack_slot(tos, -2, -1); -+ copy_stack_slot(tos, 0, -2); -+} -+ -+void BytecodeInterpreter::dup_x2(intptr_t *tos) { -+ /* insert top word three down */ -+ copy_stack_slot(tos, -1, 0); -+ copy_stack_slot(tos, -2, -1); -+ copy_stack_slot(tos, -3, -2); -+ copy_stack_slot(tos, 0, -3); -+} -+void BytecodeInterpreter::dup2_x1(intptr_t *tos) { -+ /* insert top 2 slots three down */ -+ copy_stack_slot(tos, -1, 1); -+ copy_stack_slot(tos, -2, 0); -+ copy_stack_slot(tos, -3, -1); -+ copy_stack_slot(tos, 1, -2); -+ copy_stack_slot(tos, 0, -3); -+} -+void BytecodeInterpreter::dup2_x2(intptr_t *tos) { -+ /* insert top 2 slots four down */ -+ copy_stack_slot(tos, -1, 1); -+ copy_stack_slot(tos, -2, 0); -+ copy_stack_slot(tos, -3, -1); -+ copy_stack_slot(tos, -4, -2); -+ copy_stack_slot(tos, 1, -3); -+ copy_stack_slot(tos, 0, -4); -+} -+ -+ -+void BytecodeInterpreter::swap(intptr_t *tos) { -+ // swap top two elements -+ intptr_t val = tos[Interpreter::expr_index_at(1)]; -+ frame::Tag t; -+ if (TaggedStackInterpreter) { -+ t = (frame::Tag) tos[Interpreter::expr_tag_index_at(1)]; -+ } -+ // Copy -2 entry to -1 -+ copy_stack_slot(tos, -2, -1); -+ // Store saved -1 entry into -2 -+ if (TaggedStackInterpreter) { -+ tos[Interpreter::expr_tag_index_at(2)] = (intptr_t)t; -+ } -+ tos[Interpreter::expr_index_at(2)] = val; -+} -+// -------------------------------------------------------------------------------- -+// Non-product code -+#ifndef PRODUCT -+ -+const char* BytecodeInterpreter::C_msg(BytecodeInterpreter::messages msg) { -+ switch (msg) { -+ case BytecodeInterpreter::no_request: return("no_request"); -+ case BytecodeInterpreter::initialize: return("initialize"); -+ // status message to C++ interpreter -+ case BytecodeInterpreter::method_entry: return("method_entry"); -+ case BytecodeInterpreter::method_resume: return("method_resume"); -+ case BytecodeInterpreter::got_monitors: return("got_monitors"); -+ case BytecodeInterpreter::rethrow_exception: return("rethrow_exception"); -+ // requests to frame manager from C++ interpreter -+ case BytecodeInterpreter::call_method: return("call_method"); -+ case BytecodeInterpreter::return_from_method: return("return_from_method"); -+ case BytecodeInterpreter::more_monitors: return("more_monitors"); -+ case BytecodeInterpreter::throwing_exception: return("throwing_exception"); -+ case BytecodeInterpreter::popping_frame: return("popping_frame"); -+ case BytecodeInterpreter::do_osr: return("do_osr"); -+ // deopt -+ case BytecodeInterpreter::deopt_resume: return("deopt_resume"); -+ case BytecodeInterpreter::deopt_resume2: return("deopt_resume2"); -+ default: return("BAD MSG"); -+ } -+} -+void -+BytecodeInterpreter::print() { -+ tty->print_cr("thread: " INTPTR_FORMAT, (uintptr_t) this->_thread); -+ tty->print_cr("bcp: " INTPTR_FORMAT, (uintptr_t) this->_bcp); -+ tty->print_cr("locals: " INTPTR_FORMAT, (uintptr_t) this->_locals); -+ tty->print_cr("constants: " INTPTR_FORMAT, (uintptr_t) this->_constants); -+ { -+ ResourceMark rm; -+ char *method_name = _method->name_and_sig_as_C_string(); -+ tty->print_cr("method: " INTPTR_FORMAT "[ %s ]", (uintptr_t) this->_method, method_name); -+ } -+ tty->print_cr("mdx: " INTPTR_FORMAT, (uintptr_t) this->_mdx); -+ tty->print_cr("stack: " INTPTR_FORMAT, (uintptr_t) this->_stack); -+ tty->print_cr("msg: %s", C_msg(this->_msg)); -+ tty->print_cr("result_to_call._callee: " INTPTR_FORMAT, (uintptr_t) this->_result._to_call._callee); -+ tty->print_cr("result_to_call._callee_entry_point: " INTPTR_FORMAT, (uintptr_t) this->_result._to_call._callee_entry_point); -+ tty->print_cr("result_to_call._bcp_advance: %d ", this->_result._to_call._bcp_advance); -+ tty->print_cr("osr._osr_buf: " INTPTR_FORMAT, (uintptr_t) this->_result._osr._osr_buf); -+ tty->print_cr("osr._osr_entry: " INTPTR_FORMAT, (uintptr_t) this->_result._osr._osr_entry); -+ tty->print_cr("result_return_kind 0x%x ", (int) this->_result._return_kind); -+ tty->print_cr("prev_link: " INTPTR_FORMAT, (uintptr_t) this->_prev_link); -+ tty->print_cr("native_mirror: " INTPTR_FORMAT, (uintptr_t) this->_oop_temp); -+ tty->print_cr("stack_base: " INTPTR_FORMAT, (uintptr_t) this->_stack_base); -+ tty->print_cr("stack_limit: " INTPTR_FORMAT, (uintptr_t) this->_stack_limit); -+ tty->print_cr("monitor_base: " INTPTR_FORMAT, (uintptr_t) this->_monitor_base); -+#ifdef SPARC -+ tty->print_cr("last_Java_pc: " INTPTR_FORMAT, (uintptr_t) this->_last_Java_pc); -+ tty->print_cr("frame_bottom: " INTPTR_FORMAT, (uintptr_t) this->_frame_bottom); -+ tty->print_cr("&native_fresult: " INTPTR_FORMAT, (uintptr_t) &this->_native_fresult); -+ tty->print_cr("native_lresult: " INTPTR_FORMAT, (uintptr_t) this->_native_lresult); -+#endif -+#ifdef IA64 -+ tty->print_cr("last_Java_fp: " INTPTR_FORMAT, (uintptr_t) this->_last_Java_fp); -+#endif // IA64 -+ tty->print_cr("self_link: " INTPTR_FORMAT, (uintptr_t) this->_self_link); -+} -+ -+extern "C" { -+ void PI(uintptr_t arg) { -+ ((BytecodeInterpreter*)arg)->print(); -+ } -+} -+#endif // PRODUCT -+ -+#endif // JVMTI -+#endif // CC_INTERP -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/bytecodeInterpreter.hpp openjdk/hotspot/src/share/vm/interpreter/bytecodeInterpreter.hpp ---- openjdk6/hotspot/src/share/vm/interpreter/bytecodeInterpreter.hpp 1970-01-01 01:00:00.000000000 +0100 -+++ openjdk/hotspot/src/share/vm/interpreter/bytecodeInterpreter.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -0,0 +1,572 @@ -+/* -+ * Copyright 2002-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, -+ * CA 95054 USA or visit www.sun.com if you need additional information or -+ * have any questions. -+ * -+ */ -+ -+#ifdef CC_INTERP -+ -+// CVM definitions find hotspot equivalents... -+ -+union VMJavaVal64 { -+ jlong l; -+ jdouble d; -+ uint32_t v[2]; -+}; -+ -+ -+typedef class BytecodeInterpreter* interpreterState; -+ -+struct call_message { -+ class methodOopDesc* _callee; /* method to call during call_method request */ -+ address _callee_entry_point; /* address to jump to for call_method request */ -+ int _bcp_advance; /* size of the invoke bytecode operation */ -+}; -+ -+struct osr_message { -+ address _osr_buf; /* the osr buffer */ -+ address _osr_entry; /* the entry to the osr method */ -+}; -+ -+struct osr_result { -+ nmethod* nm; /* osr nmethod */ -+ address return_addr; /* osr blob return address */ -+}; -+ -+// Result returned to frame manager -+union frame_manager_message { -+ call_message _to_call; /* describes callee */ -+ Bytecodes::Code _return_kind; /* i_return, a_return, ... */ -+ osr_message _osr; /* describes the osr */ -+ osr_result _osr_result; /* result of OSR request */ -+}; -+ -+class BytecodeInterpreter : StackObj { -+friend class SharedRuntime; -+friend class AbstractInterpreterGenerator; -+friend class CppInterpreterGenerator; -+friend class InterpreterGenerator; -+friend class InterpreterMacroAssembler; -+friend class frame; -+friend class SharedRuntime; -+friend class VMStructs; -+ -+public: -+ enum messages { -+ no_request = 0, // unused -+ initialize, // Perform one time interpreter initializations (assumes all switches set) -+ // status message to C++ interpreter -+ method_entry, // initial method entry to interpreter -+ method_resume, // frame manager response to return_from_method request (assuming a frame to resume) -+ deopt_resume, // returning from a native call into a deopted frame -+ deopt_resume2, // deopt resume as a result of a PopFrame -+ got_monitors, // frame manager response to more_monitors request -+ rethrow_exception, // unwinding and throwing exception -+ // requests to frame manager from C++ interpreter -+ call_method, // request for new frame from interpreter, manager responds with method_entry -+ return_from_method, // request from interpreter to unwind, manager responds with method_continue -+ more_monitors, // need a new monitor -+ throwing_exception, // unwind stack and rethrow -+ popping_frame, // unwind call and retry call -+ do_osr // request this invocation be OSR's -+ }; -+ -+private: -+ JavaThread* _thread; // the vm's java thread pointer -+ address _bcp; // instruction pointer -+ intptr_t* _locals; // local variable pointer -+ constantPoolCacheOop _constants; // constant pool cache -+ methodOop _method; // method being executed -+ DataLayout* _mdx; // compiler profiling data for current bytecode -+ intptr_t* _stack; // expression stack -+ messages _msg; // frame manager <-> interpreter message -+ frame_manager_message _result; // result to frame manager -+ interpreterState _prev_link; // previous interpreter state -+ oop _oop_temp; // mirror for interpreted native, null otherwise -+ intptr_t* _stack_base; // base of expression stack -+ intptr_t* _stack_limit; // limit of expression stack -+ BasicObjectLock* _monitor_base; // base of monitors on the native stack -+ -+ -+public: -+ // Constructor is only used by the initialization step. All other instances are created -+ // by the frame manager. -+ BytecodeInterpreter(messages msg); -+ -+// -+// Deoptimization support -+// -+static void layout_interpreterState(interpreterState to_fill, -+ frame* caller, -+ frame* interpreter_frame, -+ methodOop method, -+ intptr_t* locals, -+ intptr_t* stack, -+ intptr_t* stack_base, -+ intptr_t* monitor_base, -+ intptr_t* frame_bottom, -+ bool top_frame); -+ -+/* -+ * Generic 32-bit wide "Java slot" definition. This type occurs -+ * in operand stacks, Java locals, object fields, constant pools. -+ */ -+union VMJavaVal32 { -+ jint i; -+ jfloat f; -+ class oopDesc* r; -+ uint32_t raw; -+}; -+ -+/* -+ * Generic 64-bit Java value definition -+ */ -+union VMJavaVal64 { -+ jlong l; -+ jdouble d; -+ uint32_t v[2]; -+}; -+ -+/* -+ * Generic 32-bit wide "Java slot" definition. This type occurs -+ * in Java locals, object fields, constant pools, and -+ * operand stacks (as a CVMStackVal32). -+ */ -+typedef union VMSlotVal32 { -+ VMJavaVal32 j; /* For "Java" values */ -+ address a; /* a return created by jsr or jsr_w */ -+} VMSlotVal32; -+ -+ -+/* -+ * Generic 32-bit wide stack slot definition. -+ */ -+union VMStackVal32 { -+ VMJavaVal32 j; /* For "Java" values */ -+ VMSlotVal32 s; /* any value from a "slot" or locals[] */ -+}; -+ -+inline JavaThread* thread() { return _thread; } -+ -+inline address bcp() { return _bcp; } -+inline void set_bcp(address new_bcp) { _bcp = new_bcp; } -+ -+inline intptr_t* locals() { return _locals; } -+ -+inline constantPoolCacheOop constants() { return _constants; } -+inline methodOop method() { return _method; } -+inline DataLayout* mdx() { return _mdx; } -+inline void set_mdx(DataLayout *new_mdx) { _mdx = new_mdx; } -+ -+inline messages msg() { return _msg; } -+inline void set_msg(messages new_msg) { _msg = new_msg; } -+ -+inline methodOop callee() { return _result._to_call._callee; } -+inline void set_callee(methodOop new_callee) { _result._to_call._callee = new_callee; } -+inline void set_callee_entry_point(address entry) { _result._to_call._callee_entry_point = entry; } -+inline void set_osr_buf(address buf) { _result._osr._osr_buf = buf; } -+inline void set_osr_entry(address entry) { _result._osr._osr_entry = entry; } -+inline int bcp_advance() { return _result._to_call._bcp_advance; } -+inline void set_bcp_advance(int count) { _result._to_call._bcp_advance = count; } -+ -+inline void set_return_kind(Bytecodes::Code kind) { _result._return_kind = kind; } -+ -+inline interpreterState prev() { return _prev_link; } -+ -+inline intptr_t* stack() { return _stack; } -+inline void set_stack(intptr_t* new_stack) { _stack = new_stack; } -+ -+ -+inline intptr_t* stack_base() { return _stack_base; } -+inline intptr_t* stack_limit() { return _stack_limit; } -+ -+inline BasicObjectLock* monitor_base() { return _monitor_base; } -+ -+/* -+ * 64-bit Arithmetic: -+ * -+ * The functions below follow the semantics of the -+ * ladd, land, ldiv, lmul, lor, lxor, and lrem bytecodes, -+ * respectively. -+ */ -+ -+static jlong VMlongAdd(jlong op1, jlong op2); -+static jlong VMlongAnd(jlong op1, jlong op2); -+static jlong VMlongDiv(jlong op1, jlong op2); -+static jlong VMlongMul(jlong op1, jlong op2); -+static jlong VMlongOr (jlong op1, jlong op2); -+static jlong VMlongSub(jlong op1, jlong op2); -+static jlong VMlongXor(jlong op1, jlong op2); -+static jlong VMlongRem(jlong op1, jlong op2); -+ -+/* -+ * Shift: -+ * -+ * The functions below follow the semantics of the -+ * lushr, lshl, and lshr bytecodes, respectively. -+ */ -+ -+static jlong VMlongUshr(jlong op1, jint op2); -+static jlong VMlongShl (jlong op1, jint op2); -+static jlong VMlongShr (jlong op1, jint op2); -+ -+/* -+ * Unary: -+ * -+ * Return the negation of "op" (-op), according to -+ * the semantics of the lneg bytecode. -+ */ -+ -+static jlong VMlongNeg(jlong op); -+ -+/* -+ * Return the complement of "op" (~op) -+ */ -+ -+static jlong VMlongNot(jlong op); -+ -+ -+/* -+ * Comparisons to 0: -+ */ -+ -+static int32_t VMlongLtz(jlong op); /* op <= 0 */ -+static int32_t VMlongGez(jlong op); /* op >= 0 */ -+static int32_t VMlongEqz(jlong op); /* op == 0 */ -+ -+/* -+ * Between operands: -+ */ -+ -+static int32_t VMlongEq(jlong op1, jlong op2); /* op1 == op2 */ -+static int32_t VMlongNe(jlong op1, jlong op2); /* op1 != op2 */ -+static int32_t VMlongGe(jlong op1, jlong op2); /* op1 >= op2 */ -+static int32_t VMlongLe(jlong op1, jlong op2); /* op1 <= op2 */ -+static int32_t VMlongLt(jlong op1, jlong op2); /* op1 < op2 */ -+static int32_t VMlongGt(jlong op1, jlong op2); /* op1 > op2 */ -+ -+/* -+ * Comparisons (returning an jint value: 0, 1, or -1) -+ * -+ * Between operands: -+ * -+ * Compare "op1" and "op2" according to the semantics of the -+ * "lcmp" bytecode. -+ */ -+ -+static int32_t VMlongCompare(jlong op1, jlong op2); -+ -+/* -+ * Convert int to long, according to "i2l" bytecode semantics -+ */ -+static jlong VMint2Long(jint val); -+ -+/* -+ * Convert long to int, according to "l2i" bytecode semantics -+ */ -+static jint VMlong2Int(jlong val); -+ -+/* -+ * Convert long to float, according to "l2f" bytecode semantics -+ */ -+static jfloat VMlong2Float(jlong val); -+ -+/* -+ * Convert long to double, according to "l2d" bytecode semantics -+ */ -+static jdouble VMlong2Double(jlong val); -+ -+/* -+ * Java floating-point float value manipulation. -+ * -+ * The result argument is, once again, an lvalue. -+ * -+ * Arithmetic: -+ * -+ * The functions below follow the semantics of the -+ * fadd, fsub, fmul, fdiv, and frem bytecodes, -+ * respectively. -+ */ -+ -+static jfloat VMfloatAdd(jfloat op1, jfloat op2); -+static jfloat VMfloatSub(jfloat op1, jfloat op2); -+static jfloat VMfloatMul(jfloat op1, jfloat op2); -+static jfloat VMfloatDiv(jfloat op1, jfloat op2); -+static jfloat VMfloatRem(jfloat op1, jfloat op2); -+ -+/* -+ * Unary: -+ * -+ * Return the negation of "op" (-op), according to -+ * the semantics of the fneg bytecode. -+ */ -+ -+static jfloat VMfloatNeg(jfloat op); -+ -+/* -+ * Comparisons (returning an int value: 0, 1, or -1) -+ * -+ * Between operands: -+ * -+ * Compare "op1" and "op2" according to the semantics of the -+ * "fcmpl" (direction is -1) or "fcmpg" (direction is 1) bytecodes. -+ */ -+ -+static int32_t VMfloatCompare(jfloat op1, jfloat op2, -+ int32_t direction); -+/* -+ * Conversion: -+ */ -+ -+/* -+ * Convert float to double, according to "f2d" bytecode semantics -+ */ -+ -+static jdouble VMfloat2Double(jfloat op); -+ -+/* -+ ****************************************** -+ * Java double floating-point manipulation. -+ ****************************************** -+ * -+ * The result argument is, once again, an lvalue. -+ * -+ * Conversions: -+ */ -+ -+/* -+ * Convert double to int, according to "d2i" bytecode semantics -+ */ -+ -+static jint VMdouble2Int(jdouble val); -+ -+/* -+ * Convert double to float, according to "d2f" bytecode semantics -+ */ -+ -+static jfloat VMdouble2Float(jdouble val); -+ -+/* -+ * Convert int to double, according to "i2d" bytecode semantics -+ */ -+ -+static jdouble VMint2Double(jint val); -+ -+/* -+ * Arithmetic: -+ * -+ * The functions below follow the semantics of the -+ * dadd, dsub, ddiv, dmul, and drem bytecodes, respectively. -+ */ -+ -+static jdouble VMdoubleAdd(jdouble op1, jdouble op2); -+static jdouble VMdoubleSub(jdouble op1, jdouble op2); -+static jdouble VMdoubleDiv(jdouble op1, jdouble op2); -+static jdouble VMdoubleMul(jdouble op1, jdouble op2); -+static jdouble VMdoubleRem(jdouble op1, jdouble op2); -+ -+/* -+ * Unary: -+ * -+ * Return the negation of "op" (-op), according to -+ * the semantics of the dneg bytecode. -+ */ -+ -+static jdouble VMdoubleNeg(jdouble op); -+ -+/* -+ * Comparisons (returning an int32_t value: 0, 1, or -1) -+ * -+ * Between operands: -+ * -+ * Compare "op1" and "op2" according to the semantics of the -+ * "dcmpl" (direction is -1) or "dcmpg" (direction is 1) bytecodes. -+ */ -+ -+static int32_t VMdoubleCompare(jdouble op1, jdouble op2, int32_t direction); -+ -+/* -+ * Copy two typeless 32-bit words from one location to another. -+ * This is semantically equivalent to: -+ * -+ * to[0] = from[0]; -+ * to[1] = from[1]; -+ * -+ * but this interface is provided for those platforms that could -+ * optimize this into a single 64-bit transfer. -+ */ -+ -+static void VMmemCopy64(uint32_t to[2], const uint32_t from[2]); -+ -+ -+// Arithmetic operations -+ -+/* -+ * Java arithmetic methods. -+ * The functions below follow the semantics of the -+ * iadd, isub, imul, idiv, irem, iand, ior, ixor, -+ * and ineg bytecodes, respectively. -+ */ -+ -+static jint VMintAdd(jint op1, jint op2); -+static jint VMintSub(jint op1, jint op2); -+static jint VMintMul(jint op1, jint op2); -+static jint VMintDiv(jint op1, jint op2); -+static jint VMintRem(jint op1, jint op2); -+static jint VMintAnd(jint op1, jint op2); -+static jint VMintOr (jint op1, jint op2); -+static jint VMintXor(jint op1, jint op2); -+ -+/* -+ * Shift Operation: -+ * The functions below follow the semantics of the -+ * iushr, ishl, and ishr bytecodes, respectively. -+ */ -+ -+static jint VMintUshr(jint op, jint num); -+static jint VMintShl (jint op, jint num); -+static jint VMintShr (jint op, jint num); -+ -+/* -+ * Unary Operation: -+ * -+ * Return the negation of "op" (-op), according to -+ * the semantics of the ineg bytecode. -+ */ -+ -+static jint VMintNeg(jint op); -+ -+/* -+ * Int Conversions: -+ */ -+ -+/* -+ * Convert int to float, according to "i2f" bytecode semantics -+ */ -+ -+static jfloat VMint2Float(jint val); -+ -+/* -+ * Convert int to byte, according to "i2b" bytecode semantics -+ */ -+ -+static jbyte VMint2Byte(jint val); -+ -+/* -+ * Convert int to char, according to "i2c" bytecode semantics -+ */ -+ -+static jchar VMint2Char(jint val); -+ -+/* -+ * Convert int to short, according to "i2s" bytecode semantics -+ */ -+ -+static jshort VMint2Short(jint val); -+ -+/*========================================================================= -+ * Bytecode interpreter operations -+ *=======================================================================*/ -+ -+static void dup(intptr_t *tos); -+static void dup2(intptr_t *tos); -+static void dup_x1(intptr_t *tos); /* insert top word two down */ -+static void dup_x2(intptr_t *tos); /* insert top word three down */ -+static void dup2_x1(intptr_t *tos); /* insert top 2 slots three down */ -+static void dup2_x2(intptr_t *tos); /* insert top 2 slots four down */ -+static void swap(intptr_t *tos); /* swap top two elements */ -+ -+// umm don't like this method modifies its object -+ -+// The Interpreter used when -+static void run(interpreterState istate); -+// The interpreter used if JVMTI needs interpreter events -+static void runWithChecks(interpreterState istate); -+static void End_Of_Interpreter(void); -+ -+// Inline static functions for Java Stack and Local manipulation -+ -+static address stack_slot(intptr_t *tos, int offset); -+static jint stack_int(intptr_t *tos, int offset); -+static jfloat stack_float(intptr_t *tos, int offset); -+static oop stack_object(intptr_t *tos, int offset); -+static jdouble stack_double(intptr_t *tos, int offset); -+static jlong stack_long(intptr_t *tos, int offset); -+ -+static void tag_stack(intptr_t *tos, frame::Tag tag, int offset); -+ -+// only used for value types -+static void set_stack_slot(intptr_t *tos, address value, int offset); -+static void set_stack_int(intptr_t *tos, int value, int offset); -+static void set_stack_float(intptr_t *tos, jfloat value, int offset); -+static void set_stack_object(intptr_t *tos, oop value, int offset); -+ -+// needs to be platform dep for the 32 bit platforms. -+static void set_stack_double(intptr_t *tos, jdouble value, int offset); -+static void set_stack_long(intptr_t *tos, jlong value, int offset); -+ -+static void set_stack_double_from_addr(intptr_t *tos, address addr, int offset); -+static void set_stack_long_from_addr(intptr_t *tos, address addr, int offset); -+ -+// Locals -+ -+static address locals_slot(intptr_t* locals, int offset); -+static jint locals_int(intptr_t* locals, int offset); -+static jfloat locals_float(intptr_t* locals, int offset); -+static oop locals_object(intptr_t* locals, int offset); -+static jdouble locals_double(intptr_t* locals, int offset); -+static jlong locals_long(intptr_t* locals, int offset); -+ -+static address locals_long_at(intptr_t* locals, int offset); -+static address locals_double_at(intptr_t* locals, int offset); -+ -+static void tag_locals(intptr_t *locals, frame::Tag tag, int offset); -+ -+static void set_locals_slot(intptr_t *locals, address value, int offset); -+static void set_locals_int(intptr_t *locals, jint value, int offset); -+static void set_locals_float(intptr_t *locals, jfloat value, int offset); -+static void set_locals_object(intptr_t *locals, oop value, int offset); -+static void set_locals_double(intptr_t *locals, jdouble value, int offset); -+static void set_locals_long(intptr_t *locals, jlong value, int offset); -+static void set_locals_double_from_addr(intptr_t *locals, -+ address addr, int offset); -+static void set_locals_long_from_addr(intptr_t *locals, -+ address addr, int offset); -+ -+static void astore(intptr_t* topOfStack, int stack_offset, -+ intptr_t* locals, int locals_offset); -+ -+// Support for dup and swap -+static void copy_stack_slot(intptr_t *tos, int from_offset, int to_offset); -+ -+#ifndef PRODUCT -+static void verify_locals_tag(intptr_t *locals, frame::Tag tag, int offset); -+static void verify_stack_tag(intptr_t *tos, frame::Tag tag, int offset); -+static const char* C_msg(BytecodeInterpreter::messages msg); -+void print(); -+#endif // PRODUCT -+ -+ // Platform fields/methods -+# include "incls/_bytecodeInterpreter_pd.hpp.incl" -+ -+}; // BytecodeInterpreter -+ -+#endif // CC_INTERP -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/bytecodeInterpreter.inline.hpp openjdk/hotspot/src/share/vm/interpreter/bytecodeInterpreter.inline.hpp ---- openjdk6/hotspot/src/share/vm/interpreter/bytecodeInterpreter.inline.hpp 1970-01-01 01:00:00.000000000 +0100 -+++ openjdk/hotspot/src/share/vm/interpreter/bytecodeInterpreter.inline.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -0,0 +1,44 @@ -+/* -+ * Copyright 2002 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, -+ * CA 95054 USA or visit www.sun.com if you need additional information or -+ * have any questions. -+ * -+ */ -+ -+// This file holds platform-independant bodies of inline functions for the C++ based interpreter -+ -+#ifdef CC_INTERP -+ -+#ifdef ASSERT -+extern "C" { typedef void (*verify_oop_fn_t)(oop, const char *);}; -+#define VERIFY_OOP(o) \ -+ /*{ verify_oop_fn_t verify_oop_entry = \ -+ *StubRoutines::verify_oop_subroutine_entry_address(); \ -+ if (verify_oop_entry) { \ -+ (*verify_oop_entry)((o), "Not an oop!"); \ -+ } \ -+ }*/ -+#else -+#define VERIFY_OOP(o) -+#endif -+ -+// Platform dependent data manipulation -+# include "incls/_bytecodeInterpreter_pd.inline.hpp.incl" -+#endif // CC_INTERP -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/bytecodeInterpreterWithChecks.xml openjdk/hotspot/src/share/vm/interpreter/bytecodeInterpreterWithChecks.xml ---- openjdk6/hotspot/src/share/vm/interpreter/bytecodeInterpreterWithChecks.xml 1970-01-01 01:00:00.000000000 +0100 -+++ openjdk/hotspot/src/share/vm/interpreter/bytecodeInterpreterWithChecks.xml 2007-12-14 08:57:02.000000000 +0100 -@@ -0,0 +1,10 @@ -+ -+ -+ -+]> -+ -+ -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/bytecodeInterpreterWithChecks.xsl openjdk/hotspot/src/share/vm/interpreter/bytecodeInterpreterWithChecks.xsl ---- openjdk6/hotspot/src/share/vm/interpreter/bytecodeInterpreterWithChecks.xsl 1970-01-01 01:00:00.000000000 +0100 -+++ openjdk/hotspot/src/share/vm/interpreter/bytecodeInterpreterWithChecks.xsl 2007-12-14 08:57:02.000000000 +0100 -@@ -0,0 +1,21 @@ -+ -+ -+ -+ -+ -+ -+ -+#define VM_JVMTI -+#include "bytecodeInterpreter.cpp" -+ -+ -+ -+ -+ -+ -+ -+ -+ -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/bytecodeStream.cpp openjdk/hotspot/src/share/vm/interpreter/bytecodeStream.cpp ---- openjdk6/hotspot/src/share/vm/interpreter/bytecodeStream.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/interpreter/bytecodeStream.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)bytecodeStream.cpp 1.47 07/06/21 09:48:41 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/bytecodeStream.hpp openjdk/hotspot/src/share/vm/interpreter/bytecodeStream.hpp ---- openjdk6/hotspot/src/share/vm/interpreter/bytecodeStream.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/interpreter/bytecodeStream.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)bytecodeStream.hpp 1.54 07/06/21 09:48:41 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -173,5 +170,3 @@ - - bool is_active_breakpoint() const { return Bytecodes::is_active_breakpoint_at(bcp()); } - }; -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp openjdk/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp ---- openjdk6/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/interpreter/bytecodeTracer.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)bytecodeTracer.cpp 1.52 07/06/08 15:21:46 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -56,9 +53,9 @@ - bool is_wide() { return _is_wide; } - - -- void print_constant(int i); -- void print_attributes(Bytecodes::Code code, int bci); -- void bytecode_epilog(int bci); -+ void print_constant(int i, outputStream* st = tty); -+ void print_attributes(Bytecodes::Code code, int bci, outputStream* st = tty); -+ void bytecode_epilog(int bci, outputStream* st = tty); - - public: - BytecodePrinter() { -@@ -67,7 +64,7 @@ - - // This method is called while executing the raw bytecodes, so none of - // the adjustments that BytecodeStream performs applies. -- void trace(methodHandle method, address bcp, uintptr_t tos, uintptr_t tos2) { -+ void trace(methodHandle method, address bcp, uintptr_t tos, uintptr_t tos2, outputStream* st) { - ResourceMark rm; - if (_current_method != method()) { - // Note 1: This code will not work as expected with true MT/MP. -@@ -76,10 +73,10 @@ - // _current_method pointer happens to have the same bits as - // the incoming method. We could lose a line of trace output. - // This is acceptable in a debug-only feature. -- tty->cr(); -- tty->print("[%d] ", (int) Thread::current()->osthread()->thread_id()); -- method->print_name(tty); -- tty->cr(); -+ st->cr(); -+ st->print("[%d] ", (int) Thread::current()->osthread()->thread_id()); -+ method->print_name(st); -+ st->cr(); - _current_method = method(); - } - Bytecodes::Code code; -@@ -90,12 +87,12 @@ - code = Bytecodes::code_at(bcp); - } - int bci = bcp - method->code_base(); -- tty->print("[%d] ", (int) Thread::current()->osthread()->thread_id()); -+ st->print("[%d] ", (int) Thread::current()->osthread()->thread_id()); - if (Verbose) { -- tty->print("%8d %4d " INTPTR_FORMAT " " INTPTR_FORMAT " %s", -+ st->print("%8d %4d " INTPTR_FORMAT " " INTPTR_FORMAT " %s", - BytecodeCounter::counter_value(), bci, tos, tos2, Bytecodes::name(code)); - } else { -- tty->print("%8d %4d %s", -+ st->print("%8d %4d %s", - BytecodeCounter::counter_value(), bci, Bytecodes::name(code)); - } - _next_pc = is_wide() ? bcp+2 : bcp+1; -@@ -107,7 +104,7 @@ - - // Used for methodOop::print_codes(). The input bcp comes from - // BytecodeStream, which will skip wide bytecodes. -- void trace(methodHandle method, address bcp) { -+ void trace(methodHandle method, address bcp, outputStream* st) { - _current_method = method(); - ResourceMark rm; - Bytecodes::Code code = Bytecodes::code_at(bcp); -@@ -119,13 +116,13 @@ - int bci = bcp - method->code_base(); - // Print bytecode index and name - if (is_wide()) { -- tty->print("%d %s_w", bci, Bytecodes::name(code)); -+ st->print("%d %s_w", bci, Bytecodes::name(code)); - } else { -- tty->print("%d %s", bci, Bytecodes::name(code)); -+ st->print("%d %s", bci, Bytecodes::name(code)); - } - _next_pc = is_wide() ? bcp+2 : bcp+1; -- print_attributes(code, bci); -- bytecode_epilog(bci); -+ print_attributes(code, bci, st); -+ bytecode_epilog(bci, st); - } - }; - -@@ -146,7 +143,7 @@ - } - - --void BytecodeTracer::trace(methodHandle method, address bcp, uintptr_t tos, uintptr_t tos2 ) { -+void BytecodeTracer::trace(methodHandle method, address bcp, uintptr_t tos, uintptr_t tos2, outputStream* st) { - if (TraceBytecodes && BytecodeCounter::counter_value() >= TraceBytecodesAt) { - ttyLocker ttyl; // 5065316: keep the following output coherent - // The ttyLocker also prevents races between two threads -@@ -161,81 +158,81 @@ - // We put the locker on the static trace method, not the - // virtual one, because the clients of this module go through - // the static method. -- _closure->trace(method, bcp, tos, tos2); -+ _closure->trace(method, bcp, tos, tos2, st); - } - } - --void BytecodeTracer::trace(methodHandle method, address bcp) { -+void BytecodeTracer::trace(methodHandle method, address bcp, outputStream* st) { - ttyLocker ttyl; // 5065316: keep the following output coherent -- _closure->trace(method, bcp); -+ _closure->trace(method, bcp, st); - } - --void print_oop(oop value) { -+void print_oop(oop value, outputStream* st) { - if (value == NULL) { -- tty->print_cr(" NULL"); -+ st->print_cr(" NULL"); - } else { - EXCEPTION_MARK; - Handle h_value (THREAD, value); - symbolHandle sym = java_lang_String::as_symbol(h_value, CATCH); - if (sym->utf8_length() > 32) { -- tty->print_cr(" ...."); -+ st->print_cr(" ...."); - } else { -- sym->print(); tty->cr(); -+ sym->print_on(st); st->cr(); - } - } - } - --void BytecodePrinter::print_constant(int i) { -+void BytecodePrinter::print_constant(int i, outputStream* st) { - constantPoolOop constants = method()->constants(); - constantTag tag = constants->tag_at(i); - - if (tag.is_int()) { -- tty->print_cr(" " INT32_FORMAT, constants->int_at(i)); -+ st->print_cr(" " INT32_FORMAT, constants->int_at(i)); - } else if (tag.is_long()) { -- tty->print_cr(" " INT64_FORMAT, constants->long_at(i)); -+ st->print_cr(" " INT64_FORMAT, constants->long_at(i)); - } else if (tag.is_float()) { -- tty->print_cr(" %f", constants->float_at(i)); -+ st->print_cr(" %f", constants->float_at(i)); - } else if (tag.is_double()) { -- tty->print_cr(" %f", constants->double_at(i)); -+ st->print_cr(" %f", constants->double_at(i)); - } else if (tag.is_string()) { - oop string = constants->resolved_string_at(i); -- print_oop(string); -+ print_oop(string, st); - } else if (tag.is_unresolved_string()) { -- tty->print_cr(" ", i); -+ st->print_cr(" ", i); - } else if (tag.is_klass()) { -- tty->print_cr(" %s", constants->resolved_klass_at(i)->klass_part()->external_name()); -+ st->print_cr(" %s", constants->resolved_klass_at(i)->klass_part()->external_name()); - } else if (tag.is_unresolved_klass()) { -- tty->print_cr(" ", i); -+ st->print_cr(" ", i); - } else ShouldNotReachHere(); - } - - --void BytecodePrinter::print_attributes(Bytecodes::Code code, int bci) { -+void BytecodePrinter::print_attributes(Bytecodes::Code code, int bci, outputStream* st) { - // Show attributes of pre-rewritten codes - code = Bytecodes::java_code(code); - // If the code doesn't have any fields there's nothing to print. - // note this is ==1 because the tableswitch and lookupswitch are - // zero size (for some reason) and we want to print stuff out for them. - if (Bytecodes::length_for(code) == 1) { -- tty->cr(); -+ st->cr(); - return; - } - - switch(code) { - // Java specific bytecodes only matter. - case Bytecodes::_bipush: -- tty->print_cr(" " INT32_FORMAT, get_byte()); -+ st->print_cr(" " INT32_FORMAT, get_byte()); - break; - case Bytecodes::_sipush: -- tty->print_cr(" " INT32_FORMAT, get_short()); -+ st->print_cr(" " INT32_FORMAT, get_short()); - break; - case Bytecodes::_ldc: -- print_constant(get_index()); -+ print_constant(get_index(), st); - break; - - case Bytecodes::_ldc_w: - case Bytecodes::_ldc2_w: -- print_constant(get_big_index()); -+ print_constant(get_big_index(), st); - break; - - case Bytecodes::_iload: -@@ -248,13 +245,13 @@ - case Bytecodes::_fstore: - case Bytecodes::_dstore: - case Bytecodes::_astore: -- tty->print_cr(" #%d", get_index_special()); -+ st->print_cr(" #%d", get_index_special()); - break; - - case Bytecodes::_iinc: - { int index = get_index_special(); - jint offset = is_wide() ? get_short(): get_byte(); -- tty->print_cr(" #%d " INT32_FORMAT, index, offset); -+ st->print_cr(" #%d " INT32_FORMAT, index, offset); - } - break; - -@@ -264,14 +261,14 @@ - if (str == NULL || atype == T_OBJECT || atype == T_ARRAY) { - assert(false, "Unidentified basic type"); - } -- tty->print_cr(" %s", str); -+ st->print_cr(" %s", str); - } - break; - case Bytecodes::_anewarray: { - int klass_index = get_big_index(); - constantPoolOop constants = method()->constants(); - symbolOop name = constants->klass_name_at(klass_index); -- tty->print_cr(" %s ", name->as_C_string()); -+ st->print_cr(" %s ", name->as_C_string()); - } - break; - case Bytecodes::_multianewarray: { -@@ -279,7 +276,7 @@ - int nof_dims = get_index(); - constantPoolOop constants = method()->constants(); - symbolOop name = constants->klass_name_at(klass_index); -- tty->print_cr(" %s %d", name->as_C_string(), nof_dims); -+ st->print_cr(" %s %d", name->as_C_string(), nof_dims); - } - break; - -@@ -301,15 +298,15 @@ - case Bytecodes::_if_acmpne: - case Bytecodes::_goto: - case Bytecodes::_jsr: -- tty->print_cr(" %d", bci + get_short()); -+ st->print_cr(" %d", bci + get_short()); - break; - - case Bytecodes::_goto_w: - case Bytecodes::_jsr_w: -- tty->print_cr(" %d", bci + get_int()); -+ st->print_cr(" %d", bci + get_int()); - break; - -- case Bytecodes::_ret: tty->print_cr(" %d", get_index_special()); break; -+ case Bytecodes::_ret: st->print_cr(" %d", get_index_special()); break; - - case Bytecodes::_tableswitch: - { align(); -@@ -321,16 +318,16 @@ - for (int i = 0; i < len; i++) { - dest[i] = bci + get_int(); - } -- tty->print(" %d " INT32_FORMAT " " INT32_FORMAT " ", -+ st->print(" %d " INT32_FORMAT " " INT32_FORMAT " ", - default_dest, lo, hi); - int first = true; - for (int ll = lo; ll <= hi; ll++, first = false) { - int idx = ll - lo; - const char *format = first ? " %d:" INT32_FORMAT " (delta: %d)" : - ", %d:" INT32_FORMAT " (delta: %d)"; -- tty->print(format, ll, dest[idx], dest[idx]-bci); -+ st->print(format, ll, dest[idx], dest[idx]-bci); - } -- tty->cr(); -+ st->cr(); - } - break; - case Bytecodes::_lookupswitch: -@@ -343,14 +340,14 @@ - key [i] = get_int(); - dest[i] = bci + get_int(); - }; -- tty->print(" %d %d ", default_dest, len); -+ st->print(" %d %d ", default_dest, len); - bool first = true; - for (int ll = 0; ll < len; ll++, first = false) { - const char *format = first ? " " INT32_FORMAT ":" INT32_FORMAT : - ", " INT32_FORMAT ":" INT32_FORMAT ; -- tty->print(format, key[ll], dest[ll]); -+ st->print(format, key[ll], dest[ll]); - } -- tty->cr(); -+ st->cr(); - } - break; - -@@ -361,7 +358,7 @@ - int i = get_big_index(); - constantPoolOop constants = method()->constants(); - symbolOop field = constants->name_ref_at(i); -- tty->print_cr(" %d <%s>", i, field->as_C_string()); -+ st->print_cr(" %d <%s>", i, field->as_C_string()); - } - break; - -@@ -372,7 +369,7 @@ - constantPoolOop constants = method()->constants(); - symbolOop name = constants->name_ref_at(i); - symbolOop signature = constants->signature_ref_at(i); -- tty->print_cr(" %d <%s> <%s> ", i, name->as_C_string(), signature->as_C_string()); -+ st->print_cr(" %d <%s> <%s> ", i, name->as_C_string(), signature->as_C_string()); - } - break; - -@@ -383,7 +380,7 @@ - constantPoolOop constants = method()->constants(); - symbolOop name = constants->name_ref_at(i); - symbolOop signature = constants->signature_ref_at(i); -- tty->print_cr(" %d <%s> <%s> %d", i, name->as_C_string(), signature->as_C_string(), n); -+ st->print_cr(" %d <%s> <%s> %d", i, name->as_C_string(), signature->as_C_string(), n); - } - break; - -@@ -393,7 +390,7 @@ - { int i = get_big_index(); - constantPoolOop constants = method()->constants(); - symbolOop name = constants->klass_name_at(i); -- tty->print_cr(" %d <%s>", i, name->as_C_string()); -+ st->print_cr(" %d <%s>", i, name->as_C_string()); - } - break; - -@@ -408,14 +405,14 @@ - } - - --void BytecodePrinter::bytecode_epilog(int bci) { -+void BytecodePrinter::bytecode_epilog(int bci, outputStream* st) { - methodDataOop mdo = method()->method_data(); - if (mdo != NULL) { - ProfileData* data = mdo->bci_to_data(bci); - if (data != NULL) { -- tty->print(" %d", mdo->dp_to_di(data->dp())); -- tty->fill_to(6); -- data->print_data_on(tty); -+ st->print(" %d", mdo->dp_to_di(data->dp())); -+ st->fill_to(6); -+ data->print_data_on(st); - } - } - } -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/bytecodeTracer.hpp openjdk/hotspot/src/share/vm/interpreter/bytecodeTracer.hpp ---- openjdk6/hotspot/src/share/vm/interpreter/bytecodeTracer.hpp 2008-07-10 22:04:31.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/interpreter/bytecodeTracer.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)bytecodeTracer.hpp 1.24 07/05/05 17:05:37 JVM" --#endif - /* - * Copyright 1997-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -45,8 +42,8 @@ - static BytecodeClosure* closure() { return _closure; } - static void set_closure(BytecodeClosure* closure) { _closure = closure; } - -- static void trace(methodHandle method, address bcp, uintptr_t tos, uintptr_t tos2); -- static void trace(methodHandle method, address bcp); -+ static void trace(methodHandle method, address bcp, uintptr_t tos, uintptr_t tos2, outputStream* st = tty); -+ static void trace(methodHandle method, address bcp, outputStream* st = tty); - }; - - -@@ -54,8 +51,8 @@ - - class BytecodeClosure { - public: -- virtual void trace(methodHandle method, address bcp, uintptr_t tos, uintptr_t tos2) = 0; -- virtual void trace(methodHandle method, address bcp) = 0; -+ virtual void trace(methodHandle method, address bcp, uintptr_t tos, uintptr_t tos2, outputStream* st) = 0; -+ virtual void trace(methodHandle method, address bcp, outputStream* st) = 0; - }; - - #endif // !PRODUCT -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/bytecodes.cpp openjdk/hotspot/src/share/vm/interpreter/bytecodes.cpp ---- openjdk6/hotspot/src/share/vm/interpreter/bytecodes.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/interpreter/bytecodes.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)bytecodes.cpp 1.97 07/06/21 09:48:42 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/bytecodes.hpp openjdk/hotspot/src/share/vm/interpreter/bytecodes.hpp ---- openjdk6/hotspot/src/share/vm/interpreter/bytecodes.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/interpreter/bytecodes.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)bytecodes.hpp 1.79 07/06/21 09:48:42 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -359,4 +356,3 @@ - // Initialization - static void initialize (); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/cInterpretMethod.hpp openjdk/hotspot/src/share/vm/interpreter/cInterpretMethod.hpp ---- openjdk6/hotspot/src/share/vm/interpreter/cInterpretMethod.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/interpreter/cInterpretMethod.hpp 1970-01-01 01:00:00.000000000 +0100 -@@ -1,2617 +0,0 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)cInterpretMethod.hpp 1.68 07/05/17 15:54:02 JVM" --#endif --/* -- * Copyright 2002-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, -- * CA 95054 USA or visit www.sun.com if you need additional information or -- * have any questions. -- * -- */ -- --#ifndef CINTERPRETERBODY_ONCE --#define CINTERPERTERBODY_ONCE --#endif -- --/* -- * This code was converted from CVM sources to C++ and the Hotspot VM -- */ -- --#ifdef CC_INTERP -- --/* -- * USELABELS - If using GCC, then use labels for the opcode dispatching -- * rather -then a switch statement. This improves performance because it -- * gives us the oportunity to have the instructions that calculate the -- * next opcode to jump to be intermixed with the rest of the instructions -- * that implement the opcode (see UPDATE_PC_AND_TOS_AND_CONTINUE macro). -- */ --#undef USELABELS --#ifdef __GNUC__ --/* -- ASSERT signifies debugging. It is much easier to step thru bytecodes if we -- don't use the computed goto approach. --*/ --#ifndef ASSERT --#define USELABELS --#endif --#endif -- --#undef CASE --#ifdef USELABELS --#define CASE(opcode) opc ## opcode --#define DEFAULT opc_default --#else --#define CASE(opcode) case Bytecodes:: opcode --#define DEFAULT default --#endif -- --/* -- * PREFETCH_OPCCODE - Some compilers do better if you prefetch the next -- * opcode before going back to the top of the while loop, rather then having -- * the top of the while loop handle it. This provides a better opportunity -- * for instruction scheduling. Some compilers just do this prefetch -- * automatically. Some actually end up with worse performance if you -- * force the prefetch. Solaris gcc seems to do better, but cc does worse. -- */ --#undef PREFETCH_OPCCODE --#define PREFETCH_OPCCODE -- --/* -- Interpreter safepoint: it is expected that the interpreter will have no live -- handles of its own creation live at an interpreter safepoint. Therefore we -- run a HandleMarkCleaner and trash all handles allocated in the call chain -- since the JavaCalls::call_helper invocation that initiated the chain. -- There really shouldn't be any handles remaining to trash but this is cheap -- in relation to a safepoint. --*/ --#define SAFEPOINT \ -- if ( SafepointSynchronize::is_synchronizing()) { \ -- { \ -- /* zap freed handles rather than GC'ing them */ \ -- HandleMarkCleaner __hmc(THREAD); \ -- } \ -- CALL_VM(SafepointSynchronize::block(THREAD), handle_exception); \ -- } -- --/* -- * VM_JAVA_ERROR - Macro for throwing a java exception from -- * the interpreter loop. Should really be a CALL_VM but there -- * is no entry point to do the transition to vm so we just -- * do it by hand here. -- */ --#define VM_JAVA_ERROR_NO_JUMP(name, msg) \ -- DECACHE_STATE(); \ -- SET_LAST_JAVA_FRAME(); \ -- { \ -- ThreadInVMfromJava trans(THREAD); \ -- Exceptions::_throw_msg(THREAD, __FILE__, __LINE__, name, msg, NULL, NULL); \ -- } \ -- RESET_LAST_JAVA_FRAME(); \ -- CACHE_STATE(); -- --// Normal throw of a java error --#define VM_JAVA_ERROR(name, msg) \ -- VM_JAVA_ERROR_NO_JUMP(name, msg) \ -- goto handle_exception; -- --#ifdef PRODUCT --#define DO_UPDATE_INSTRUCTION_COUNT(opcode) --#else --#define DO_UPDATE_INSTRUCTION_COUNT(opcode) \ --{ \ -- BytecodeCounter::_counter_value++; \ -- BytecodeHistogram::_counters[(Bytecodes::Code)opcode]++; \ -- if (StopInterpreterAt && StopInterpreterAt == BytecodeCounter::_counter_value) os::breakpoint(); \ -- if (TraceBytecodes) { \ -- CALL_VM((void)SharedRuntime::trace_bytecode(THREAD, 0, \ -- topOfStack[Interpreter::expr_index_at(1)], \ -- topOfStack[Interpreter::expr_index_at(2)]), \ -- handle_exception); \ -- } \ --} --#endif -- --#undef DEBUGGER_SINGLE_STEP_NOTIFY --#ifdef VM_JVMTI --/* NOTE: (kbr) This macro must be called AFTER the PC has been -- incremented. JvmtiExport::at_single_stepping_point() may cause a -- breakpoint opcode to get inserted at the current PC to allow the -- debugger to coalesce single-step events. -- -- As a result if we call at_single_stepping_point() we refetch opcode -- to get the current opcode. This will override any other prefetching -- that might have occurred. --*/ --#define DEBUGGER_SINGLE_STEP_NOTIFY() \ --{ \ -- if (_jvmti_interp_events) { \ -- if (JvmtiExport::should_post_single_step()) { \ -- DECACHE_STATE(); \ -- SET_LAST_JAVA_FRAME(); \ -- ThreadInVMfromJava trans(THREAD); \ -- JvmtiExport::at_single_stepping_point(THREAD, \ -- istate->method(), \ -- pc); \ -- RESET_LAST_JAVA_FRAME(); \ -- CACHE_STATE(); \ -- if (THREAD->pop_frame_pending() && \ -- !THREAD->pop_frame_in_process()) { \ -- goto handle_Pop_Frame; \ -- } \ -- opcode = *pc; \ -- } \ -- } \ --} --#else --#define DEBUGGER_SINGLE_STEP_NOTIFY() --#endif -- --/* -- * CONTINUE - Macro for executing the next opcode. -- */ --#undef CONTINUE --#ifdef USELABELS --// Have to do this dispatch this way in C++ because otherwise gcc complains about crossing an --// initialization (which is is the initialization of the table pointer...) --#define DISPATCH(opcode) goto *dispatch_table[opcode] --#define CONTINUE { \ -- opcode = *pc; \ -- DO_UPDATE_INSTRUCTION_COUNT(opcode); \ -- DEBUGGER_SINGLE_STEP_NOTIFY(); \ -- DISPATCH(opcode); \ -- } --#else --#ifdef PREFETCH_OPCCODE --#define CONTINUE { \ -- opcode = *pc; \ -- DO_UPDATE_INSTRUCTION_COUNT(opcode); \ -- DEBUGGER_SINGLE_STEP_NOTIFY(); \ -- continue; \ -- } --#else --#define CONTINUE { \ -- DO_UPDATE_INSTRUCTION_COUNT(opcode); \ -- DEBUGGER_SINGLE_STEP_NOTIFY(); \ -- continue; \ -- } --#endif --#endif -- --// JavaStack Implementation --#define MORE_STACK(count) \ -- (topOfStack -= ((count) * Interpreter::stackElementWords())) -- -- --#define UPDATE_PC(opsize) {pc += opsize; } --/* -- * UPDATE_PC_AND_TOS - Macro for updating the pc and topOfStack. -- */ --#undef UPDATE_PC_AND_TOS --#define UPDATE_PC_AND_TOS(opsize, stack) \ -- {pc += opsize; MORE_STACK(stack); } -- --/* -- * UPDATE_PC_AND_TOS_AND_CONTINUE - Macro for updating the pc and topOfStack, -- * and executing the next opcode. It's somewhat similar to the combination -- * of UPDATE_PC_AND_TOS and CONTINUE, but with some minor optimizations. -- */ --#undef UPDATE_PC_AND_TOS_AND_CONTINUE --#ifdef USELABELS --#define UPDATE_PC_AND_TOS_AND_CONTINUE(opsize, stack) { \ -- pc += opsize; opcode = *pc; MORE_STACK(stack); \ -- DO_UPDATE_INSTRUCTION_COUNT(opcode); \ -- DEBUGGER_SINGLE_STEP_NOTIFY(); \ -- DISPATCH(opcode); \ -- } -- --#define UPDATE_PC_AND_CONTINUE(opsize) { \ -- pc += opsize; opcode = *pc; \ -- DO_UPDATE_INSTRUCTION_COUNT(opcode); \ -- DEBUGGER_SINGLE_STEP_NOTIFY(); \ -- DISPATCH(opcode); \ -- } --#else --#ifdef PREFETCH_OPCCODE --#define UPDATE_PC_AND_TOS_AND_CONTINUE(opsize, stack) { \ -- pc += opsize; opcode = *pc; MORE_STACK(stack); \ -- DO_UPDATE_INSTRUCTION_COUNT(opcode); \ -- DEBUGGER_SINGLE_STEP_NOTIFY(); \ -- goto do_continue; \ -- } -- --#define UPDATE_PC_AND_CONTINUE(opsize) { \ -- pc += opsize; opcode = *pc; \ -- DO_UPDATE_INSTRUCTION_COUNT(opcode); \ -- DEBUGGER_SINGLE_STEP_NOTIFY(); \ -- goto do_continue; \ -- } --#else --#define UPDATE_PC_AND_TOS_AND_CONTINUE(opsize, stack) { \ -- pc += opsize; MORE_STACK(stack); \ -- DO_UPDATE_INSTRUCTION_COUNT(opcode); \ -- DEBUGGER_SINGLE_STEP_NOTIFY(); \ -- goto do_continue; \ -- } -- --#define UPDATE_PC_AND_CONTINUE(opsize) { \ -- pc += opsize; \ -- DO_UPDATE_INSTRUCTION_COUNT(opcode); \ -- DEBUGGER_SINGLE_STEP_NOTIFY(); \ -- goto do_continue; \ -- } --#endif /* PREFETCH_OPCCODE */ --#endif /* USELABELS */ -- --// About to call a new method, update the save the adjusted pc and return to frame manager --#define UPDATE_PC_AND_RETURN(opsize) \ -- DECACHE_TOS(); \ -- istate->set_bcp(pc+opsize); \ -- return; -- -- --#define METHOD istate->method() --#define INVOCATION_COUNT METHOD->invocation_counter() --#define BACKEDGE_COUNT METHOD->backedge_counter() -- -- --#define INCR_INVOCATION_COUNT INVOCATION_COUNT->increment() --#define OSR_REQUEST(res, branch_pc) \ -- CALL_VM(res=InterpreterRuntime::frequency_counter_overflow(THREAD, branch_pc), handle_exception); --/* -- * For those opcodes that need to have a GC point on a backwards branch -- */ -- --// Backedge counting is kind of strange. The asm interpreter will increment --// the backedge counter as a separate counter but it does it's comparisons --// to the sum (scaled) of invocation counter and backedge count to make --// a decision. Seems kind of odd to sum them together like that -- --// skip is delta from current bcp/bci for target, branch_pc is pre-branch bcp -- -- --#define DO_BACKEDGE_CHECKS(skip, branch_pc) \ -- if ((skip) <= 0) { \ -- if (UseCompiler && UseLoopCounter) { \ -- bool do_OSR = UseOnStackReplacement; \ -- BACKEDGE_COUNT->increment(); \ -- if (do_OSR) do_OSR = BACKEDGE_COUNT->reached_InvocationLimit(); \ -- if (do_OSR) { \ -- nmethod* osr_nmethod; \ -- OSR_REQUEST(osr_nmethod, branch_pc); \ -- if (osr_nmethod->osr_entry_bci() != InvalidOSREntryBci) { \ -- intptr_t* buf; \ -- CALL_VM(buf=SharedRuntime::OSR_migration_begin(THREAD), handle_exception); \ -- istate->set_msg(do_osr); \ -- istate->set_osr_buf((address)buf); \ -- istate->set_osr_entry(osr_nmethod->osr_entry()); \ -- return; \ -- } \ -- } else { \ -- INCR_INVOCATION_COUNT; \ -- SAFEPOINT; \ -- } \ -- } /* UseCompiler ... */ \ -- INCR_INVOCATION_COUNT; \ -- SAFEPOINT; \ -- } -- --/* -- * Macros for accessing the stack. -- */ --#undef STACK_INT --#undef STACK_FLOAT --#undef STACK_OBJECT --#undef STACK_DOUBLE --#undef STACK_LONG --// JavaStack Implementation -- --#define STACK_SLOT(offset) stack_slot(topOfStack, (offset)) --#define STACK_INT(offset) stack_int(topOfStack, (offset)) --#define STACK_FLOAT(offset) stack_float(topOfStack, (offset)) --#define STACK_OBJECT(offset) stack_object(topOfStack, (offset)) --#define STACK_DOUBLE(offset) stack_double(topOfStack, (offset)) --#define STACK_LONG(offset) stack_long(topOfStack, (offset)) -- -- --#define SET_STACK_SLOT(value, offset) \ -- set_stack_slot(topOfStack, (value), (offset)) --#define SET_STACK_INT(value, offset) \ -- set_stack_int(topOfStack, (value), (offset)) --#define SET_STACK_FLOAT(value, offset) \ -- set_stack_float(topOfStack, (value), (offset)) --#define SET_STACK_OBJECT(value, offset) \ -- set_stack_object(topOfStack, (value), (offset)) --#define SET_STACK_DOUBLE(value, offset) \ -- set_stack_double(topOfStack, (value), (offset)) --#define SET_STACK_DOUBLE_FROM_ADDR(addr, offset) \ -- set_stack_double_from_addr(topOfStack, (addr), (offset)) --#define SET_STACK_LONG(value, offset) \ -- set_stack_long(topOfStack, (value), (offset)) --#define SET_STACK_LONG_FROM_ADDR(addr, offset) \ -- set_stack_long_from_addr(topOfStack, (addr), (offset)) -- --#define LOCALS_SLOT(offset) locals_slot(locals, (offset)) --#define LOCALS_INT(offset) locals_int(locals, (offset)) --#define LOCALS_FLOAT(offset) locals_float(locals, (offset)) --#define LOCALS_OBJECT(offset) locals_object(locals, (offset)) --#define LOCALS_DOUBLE(offset) locals_double(locals, (offset)) --#define LOCALS_LONG(offset) locals_long(locals, (offset)) --#define LOCALS_LONG_AT(offset) locals_long_at(locals, (offset)) --#define LOCALS_DOUBLE_AT(offset) locals_double_at(locals, (offset)) -- -- --#define SET_LOCALS_SLOT(value, offset) \ -- set_locals_slot(locals, (value), (offset)) --#define SET_LOCALS_INT(value, offset) \ -- set_locals_int(locals, (value), (offset)) --#define SET_LOCALS_FLOAT(value, offset) \ -- set_locals_float(locals, (value), (offset)) --#define SET_LOCALS_OBJECT(value, offset) \ -- set_locals_object(locals, (value), (offset)) --#define SET_LOCALS_DOUBLE(value, offset) \ -- set_locals_double(locals, (value), (offset)) --#define SET_LOCALS_LONG(value, offset) \ -- set_locals_long(locals, (value), (offset)) --#define SET_LOCALS_DOUBLE_FROM_ADDR(addr, offset) \ -- set_locals_double_from_addr(locals, (addr), (offset)) --#define SET_LOCALS_LONG_FROM_ADDR(addr, offset) \ -- set_locals_long_from_addr(locals, (addr), (offset)) -- -- --/* -- * Macros for caching and flushing the interpreter state. Some local -- * variables need to be flushed out to the frame before we do certain -- * things (like pushing frames or becomming gc safe) and some need to -- * be recached later (like after popping a frame). We could use one -- * macro to cache or decache everything, but this would be less then -- * optimal because we don't always need to cache or decache everything -- * because some things we know are already cached or decached. -- */ --#undef DECACHE_TOS --#undef CACHE_TOS --#undef CACHE_PREV_TOS --#define DECACHE_TOS() istate->set_stack(topOfStack); -- --#define CACHE_TOS() topOfStack = (intptr_t *)istate->stack(); -- --#undef DECACHE_PC --#undef CACHE_PC --#define DECACHE_PC() istate->set_bcp(pc); --#define CACHE_PC() pc = istate->bcp(); --#define CACHE_CP() cp = istate->constants(); --#define CACHE_LOCALS() locals = istate->locals(); --#undef CACHE_FRAME --#define CACHE_FRAME() -- --/* -- * CHECK_NULL - Macro for throwing a NullPointerException if the object -- * passed is a null ref. -- * On some architectures/platforms it should be possible to do this implicitly -- */ --#undef CHECK_NULL --#define CHECK_NULL(obj_) \ -- if ((obj_) == 0) { \ -- VM_JAVA_ERROR(vmSymbols::java_lang_NullPointerException(), ""); \ -- } -- --#define VMdoubleConstZero() 0.0 --#define VMdoubleConstOne() 1.0 --#define VMlongConstZero() (max_jlong-max_jlong) --#define VMlongConstOne() ((max_jlong-max_jlong)+1) -- --/* -- * Alignment -- */ --/* #define VMalignWordUp(val) (((juint)(val) + 3) & ~3) */ --#define VMalignWordUp(val) (((uintptr_t)(val) + 3) & ~3) -- --// Decache the interpreter state that interpreter modifies directly (i.e. GC is indirect mod) --#define DECACHE_STATE() DECACHE_PC(); DECACHE_TOS(); -- --// Reload interpreter state after calling the VM or a possible GC --#define CACHE_STATE() \ -- CACHE_TOS(); \ -- CACHE_PC(); \ -- CACHE_CP(); \ -- CACHE_LOCALS(); -- --// Call the VM don't check for pending exceptions --#define CALL_VM_NOCHECK(func) \ -- DECACHE_STATE(); \ -- SET_LAST_JAVA_FRAME(); \ -- func; \ -- RESET_LAST_JAVA_FRAME(); \ -- CACHE_STATE(); \ -- if (THREAD->pop_frame_pending() && \ -- !THREAD->pop_frame_in_process()) { \ -- goto handle_Pop_Frame; \ -- } -- --// Call the VM and check for pending exceptions --#define CALL_VM(func, label) { \ -- CALL_VM_NOCHECK(func); \ -- if (THREAD->pending_exception()) goto label; \ -- } -- --/* -- * cInterpreter::InterpretMethod(interpreterState istate) -- * cInterpreter::InterpretMethodWithChecks(interpreterState istate) -- * -- * The real deal. This is where byte codes actually get interpreted. -- * Basically it's a big while loop that iterates until we return from -- * the method passed in. -- * -- * The InterpretMethodWithChecks is used if JVMTI is enabled. -- * -- */ --#if defined(VM_JVMTI) --void --cInterpreter::InterpretMethodWithChecks(interpreterState istate) { --#else --void --cInterpreter::InterpretMethod(interpreterState istate) { --#endif -- -- // In order to simplify some tests based on switches set at runtime -- // we invoke the interpreter a single time after switches are enabled -- // and set simpler to to test variables rather than method calls or complex -- // boolean expressions. -- -- static int initialized = 0; --#ifdef VM_JVMTI -- static bool _jvmti_interp_events = 0; --#endif -- -- static int _compiling; // (UseCompiler || CountCompiledCalls) -- --#ifdef ASSERT -- // Verify linkages. -- interpreterState l = istate; -- do { -- assert(l == l->_self_link, "bad link"); -- l = l->_prev_link; -- } while (l != NULL); -- // Screwups with stack management usually cause us to overwrite istate -- // save a copy so we can verify it. -- interpreterState orig = istate; --#endif -- -- static volatile jbyte* _byte_map_base; // adjusted card table base for oop store barrier -- -- register intptr_t* topOfStack = (intptr_t *)istate->stack(); /* access with STACK macros */ -- register address pc = istate->bcp(); -- register jubyte opcode; -- register intptr_t* locals = istate->locals(); -- register constantPoolCacheOop cp = istate->constants(); // method()->constants()->cache() --#ifdef LOTS_OF_REGS -- register JavaThread* THREAD = istate->thread(); -- register volatile jbyte* BYTE_MAP_BASE = _byte_map_base; --#else --#undef THREAD --#define THREAD istate->thread() --#undef BYTE_MAP_BASE --#define BYTE_MAP_BASE _byte_map_base --#endif -- --#ifdef USELABELS -- const static void* const opclabels_data[256] = { --/* 0x00 */ &&opc_nop, &&opc_aconst_null,&&opc_iconst_m1,&&opc_iconst_0, --/* 0x04 */ &&opc_iconst_1,&&opc_iconst_2, &&opc_iconst_3, &&opc_iconst_4, --/* 0x08 */ &&opc_iconst_5,&&opc_lconst_0, &&opc_lconst_1, &&opc_fconst_0, --/* 0x0C */ &&opc_fconst_1,&&opc_fconst_2, &&opc_dconst_0, &&opc_dconst_1, -- --/* 0x10 */ &&opc_bipush, &&opc_sipush, &&opc_ldc, &&opc_ldc_w, --/* 0x14 */ &&opc_ldc2_w, &&opc_iload, &&opc_lload, &&opc_fload, --/* 0x18 */ &&opc_dload, &&opc_aload, &&opc_iload_0,&&opc_iload_1, --/* 0x1C */ &&opc_iload_2,&&opc_iload_3,&&opc_lload_0,&&opc_lload_1, -- --/* 0x20 */ &&opc_lload_2,&&opc_lload_3,&&opc_fload_0,&&opc_fload_1, --/* 0x24 */ &&opc_fload_2,&&opc_fload_3,&&opc_dload_0,&&opc_dload_1, --/* 0x28 */ &&opc_dload_2,&&opc_dload_3,&&opc_aload_0,&&opc_aload_1, --/* 0x2C */ &&opc_aload_2,&&opc_aload_3,&&opc_iaload, &&opc_laload, -- --/* 0x30 */ &&opc_faload, &&opc_daload, &&opc_aaload, &&opc_baload, --/* 0x34 */ &&opc_caload, &&opc_saload, &&opc_istore, &&opc_lstore, --/* 0x38 */ &&opc_fstore, &&opc_dstore, &&opc_astore, &&opc_istore_0, --/* 0x3C */ &&opc_istore_1,&&opc_istore_2,&&opc_istore_3,&&opc_lstore_0, -- --/* 0x40 */ &&opc_lstore_1,&&opc_lstore_2,&&opc_lstore_3,&&opc_fstore_0, --/* 0x44 */ &&opc_fstore_1,&&opc_fstore_2,&&opc_fstore_3,&&opc_dstore_0, --/* 0x48 */ &&opc_dstore_1,&&opc_dstore_2,&&opc_dstore_3,&&opc_astore_0, --/* 0x4C */ &&opc_astore_1,&&opc_astore_2,&&opc_astore_3,&&opc_iastore, -- --/* 0x50 */ &&opc_lastore,&&opc_fastore,&&opc_dastore,&&opc_aastore, --/* 0x54 */ &&opc_bastore,&&opc_castore,&&opc_sastore,&&opc_pop, --/* 0x58 */ &&opc_pop2, &&opc_dup, &&opc_dup_x1, &&opc_dup_x2, --/* 0x5C */ &&opc_dup2, &&opc_dup2_x1,&&opc_dup2_x2,&&opc_swap, -- --/* 0x60 */ &&opc_iadd,&&opc_ladd,&&opc_fadd,&&opc_dadd, --/* 0x64 */ &&opc_isub,&&opc_lsub,&&opc_fsub,&&opc_dsub, --/* 0x68 */ &&opc_imul,&&opc_lmul,&&opc_fmul,&&opc_dmul, --/* 0x6C */ &&opc_idiv,&&opc_ldiv,&&opc_fdiv,&&opc_ddiv, -- --/* 0x70 */ &&opc_irem, &&opc_lrem, &&opc_frem,&&opc_drem, --/* 0x74 */ &&opc_ineg, &&opc_lneg, &&opc_fneg,&&opc_dneg, --/* 0x78 */ &&opc_ishl, &&opc_lshl, &&opc_ishr,&&opc_lshr, --/* 0x7C */ &&opc_iushr,&&opc_lushr,&&opc_iand,&&opc_land, -- --/* 0x80 */ &&opc_ior, &&opc_lor,&&opc_ixor,&&opc_lxor, --/* 0x84 */ &&opc_iinc,&&opc_i2l,&&opc_i2f, &&opc_i2d, --/* 0x88 */ &&opc_l2i, &&opc_l2f,&&opc_l2d, &&opc_f2i, --/* 0x8C */ &&opc_f2l, &&opc_f2d,&&opc_d2i, &&opc_d2l, -- --/* 0x90 */ &&opc_d2f, &&opc_i2b, &&opc_i2c, &&opc_i2s, --/* 0x94 */ &&opc_lcmp, &&opc_fcmpl,&&opc_fcmpg,&&opc_dcmpl, --/* 0x98 */ &&opc_dcmpg,&&opc_ifeq, &&opc_ifne, &&opc_iflt, --/* 0x9C */ &&opc_ifge, &&opc_ifgt, &&opc_ifle, &&opc_if_icmpeq, -- --/* 0xA0 */ &&opc_if_icmpne,&&opc_if_icmplt,&&opc_if_icmpge, &&opc_if_icmpgt, --/* 0xA4 */ &&opc_if_icmple,&&opc_if_acmpeq,&&opc_if_acmpne, &&opc_goto, --/* 0xA8 */ &&opc_jsr, &&opc_ret, &&opc_tableswitch,&&opc_lookupswitch, --/* 0xAC */ &&opc_ireturn, &&opc_lreturn, &&opc_freturn, &&opc_dreturn, -- --/* 0xB0 */ &&opc_areturn, &&opc_return, &&opc_getstatic, &&opc_putstatic, --/* 0xB4 */ &&opc_getfield, &&opc_putfield, &&opc_invokevirtual,&&opc_invokespecial, --/* 0xB8 */ &&opc_invokestatic,&&opc_invokeinterface,NULL, &&opc_new, --/* 0xBC */ &&opc_newarray, &&opc_anewarray, &&opc_arraylength, &&opc_athrow, -- --/* 0xC0 */ &&opc_checkcast, &&opc_instanceof, &&opc_monitorenter, &&opc_monitorexit, --/* 0xC4 */ &&opc_wide, &&opc_multianewarray, &&opc_ifnull, &&opc_ifnonnull, --/* 0xC8 */ &&opc_goto_w, &&opc_jsr_w, &&opc_breakpoint, &&opc_fast_igetfield, --/* 0xCC */ &&opc_fastagetfield,&&opc_fast_aload_0, &&opc_fast_iaccess_0, &&opc__fast_aaccess_0, -- --/* 0xD0 */ &&opc_fast_linearswitch, &&opc_fast_binaryswitch, &&opc_return_register_finalizer, &&opc_default, --/* 0xD4 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, --/* 0xD8 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, --/* 0xDC */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, -- --/* 0xE0 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, --/* 0xE4 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, --/* 0xE8 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, --/* 0xEC */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, -- --/* 0xF0 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, --/* 0xF4 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, --/* 0xF8 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, --/* 0xFC */ &&opc_default, &&opc_default, &&opc_default, &&opc_default -- }; -- register uintptr_t *dispatch_table = (uintptr_t*)&opclabels_data[0]; --#endif /* USELABELS */ -- --#ifdef ASSERT -- // this will trigger a VERIFY_OOP on entry -- if (istate->msg() != initialize && ! istate->method()->is_static()) { -- oop rcvr = LOCALS_OBJECT(0); -- } --#endif -- -- /* QQQ this should be a stack method so we don't know actual direction */ -- assert(istate->msg() == initialize || -- topOfStack >= istate->stack_limit() && -- topOfStack < istate->stack_base(), -- "Stack top out of range"); -- -- switch (istate->msg()) { -- case initialize: { -- if (initialized++) ShouldNotReachHere(); // Only one initialize call -- _compiling = (UseCompiler || CountCompiledCalls); --#ifdef VM_JVMTI -- _jvmti_interp_events = JvmtiExport::can_post_interpreter_events(); --#endif -- BarrierSet* bs = Universe::heap()->barrier_set(); -- assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind"); -- _byte_map_base = (volatile jbyte*)(((CardTableModRefBS*)bs)->byte_map_base); -- return; -- } -- break; -- case method_entry: { -- THREAD->set_do_not_unlock(); -- // count invocations -- assert(initialized, "Interpreter not initialized"); -- if (_compiling) { -- if (ProfileInterpreter) { -- istate->method()->increment_interpreter_invocation_count(); -- } -- INCR_INVOCATION_COUNT; -- if (istate->method()->invocation_counter()->has_overflowed()) { -- CALL_VM((void)InterpreterRuntime::frequency_counter_overflow(THREAD, NULL), handle_exception); -- -- // We no longer retry on a counter overflow -- -- // istate->set_msg(retry_method); -- // THREAD->clr_do_not_unlock(); -- // return; -- } -- SAFEPOINT; -- } -- --#ifdef HACK -- { -- ResourceMark rm; -- char *method_name = istate->method()->name_and_sig_as_C_string(); -- if (strstr(method_name, "SecurityManager$1") != NULL) os::breakpoint(); -- } --#endif // HACK -- -- -- // lock method if synchronized -- if (istate->method()->is_synchronized()) { -- // oop rcvr = locals[0].j.r; -- oop rcvr; -- if (istate->method()->is_static()) { -- rcvr = istate->method()->constants()->pool_holder()->klass_part()->java_mirror(); -- } else { -- rcvr = LOCALS_OBJECT(0); -- } -- // The initial monitor is ours for the taking -- BasicObjectLock* mon = &istate->monitor_base()[-1]; -- oop monobj = mon->obj(); -- assert(mon->obj() == rcvr, "method monitor mis-initialized"); -- -- markOop displaced = rcvr->mark()->set_unlocked(); -- mon->lock()->set_displaced_header(displaced); -- if (Atomic::cmpxchg_ptr(mon, rcvr->mark_addr(), displaced) != displaced) { -- // Is it simple recursive case? -- if (THREAD->is_lock_owned((address) displaced->clear_lock_bits())) { -- mon->lock()->set_displaced_header(NULL); -- } else { -- CALL_VM(InterpreterRuntime::monitorenter(THREAD, mon), handle_exception); -- } -- } -- } -- THREAD->clr_do_not_unlock(); -- -- // Notify jvmti --#ifdef VM_JVMTI -- if (_jvmti_interp_events) { -- // Whenever JVMTI puts a thread in interp_only_mode, method -- // entry/exit events are sent for that thread to track stack depth. -- if (THREAD->is_interp_only_mode()) { -- CALL_VM(InterpreterRuntime::post_method_entry(THREAD), -- handle_exception); -- } -- } --#endif /* VM_JVMTI */ -- -- goto run; -- } -- -- case popping_frame: { -- // returned from a java call to pop the frame, restart the call -- // clear the message so we don't confuse ourselves later -- assert(THREAD->pop_frame_in_process(), "wrong frame pop state"); -- istate->set_msg(no_request); -- THREAD->clr_pop_frame_in_process(); -- goto run; -- } -- -- case method_resume: { --#ifdef HACK -- { -- ResourceMark rm; -- char *method_name = istate->method()->name_and_sig_as_C_string(); -- if (strstr(method_name, "SecurityManager$1") != NULL) os::breakpoint(); -- } --#endif // HACK -- // returned from a java call, continue executing. -- if (THREAD->pop_frame_pending() && !THREAD->pop_frame_in_process()) { -- goto handle_Pop_Frame; -- } -- -- if (THREAD->has_pending_exception()) goto handle_exception; -- // Update the pc by the saved amount of the invoke bytecode size -- UPDATE_PC(istate->bcp_advance()); -- goto run; -- } -- -- case deopt_resume2: { -- // Returned from an opcode that will reexecute. Deopt was -- // a result of a PopFrame request. -- // -- goto run; -- } -- -- case deopt_resume: { -- // Returned from an opcode that has completed. The stack has -- // the result all we need to do is skip across the bytecode -- // and continue (assuming there is no exception pending) -- // -- // compute continuation length -- // -- UPDATE_PC(Bytecodes::length_at(pc)); -- if (THREAD->has_pending_exception()) goto handle_exception; -- goto run; -- } -- case got_monitors: { -- // continue locking now that we have a monitor to use -- // we expect to find newly allocated monitor at the "top" of the monitor stack. -- oop lockee = STACK_OBJECT(-1); -- // derefing's lockee ought to provoke implicit null check -- // find a free monitor -- BasicObjectLock* entry = (BasicObjectLock*) istate->stack_base(); -- assert(entry->obj() == NULL, "Frame manager didn't allocate the monitor"); -- entry->set_obj(lockee); -- -- markOop displaced = lockee->mark()->set_unlocked(); -- entry->lock()->set_displaced_header(displaced); -- if (Atomic::cmpxchg_ptr(entry, lockee->mark_addr(), displaced) != displaced) { -- // Is it simple recursive case? -- if (THREAD->is_lock_owned((address) displaced->clear_lock_bits())) { -- entry->lock()->set_displaced_header(NULL); -- } else { -- CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception); -- } -- } -- UPDATE_PC_AND_TOS(1, -1); -- goto run; -- } -- default: { -- fatal("Unexpected message from frame manager"); -- } -- } -- --run: -- -- DO_UPDATE_INSTRUCTION_COUNT(*pc) -- DEBUGGER_SINGLE_STEP_NOTIFY(); --#ifdef PREFETCH_OPCCODE -- opcode = *pc; /* prefetch first opcode */ --#endif -- --#ifndef USELABELS -- while (1) --#endif -- { --#ifndef PREFETCH_OPCCODE -- opcode = *pc; --#endif -- // Seems like this happens twice per opcode. At worst this is only -- // need at entry to the loop. -- // DEBUGGER_SINGLE_STEP_NOTIFY(); -- /* Using this labels avoids double breakpoints when quickening and -- * when returing from transition frames. -- */ -- opcode_switch: -- assert(istate == orig, "Corrupted istate"); -- /* QQQ Hmm this has knowledge of direction, ought to be a stack method */ -- assert(topOfStack >= istate->stack_limit(), "Stack overrun"); -- assert(topOfStack < istate->stack_base(), "Stack underrun"); -- --#ifdef USELABELS -- DISPATCH(opcode); --#else -- switch (opcode) --#endif -- { -- CASE(_nop): -- UPDATE_PC_AND_CONTINUE(1); -- -- /* Push miscellaneous constants onto the stack. */ -- -- CASE(_aconst_null): -- SET_STACK_OBJECT(NULL, 0); -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); -- --#undef OPC_CONST_n --#define OPC_CONST_n(opcode, const_type, value) \ -- CASE(opcode): \ -- SET_STACK_ ## const_type(value, 0); \ -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); -- -- OPC_CONST_n(_iconst_m1, INT, -1); -- OPC_CONST_n(_iconst_0, INT, 0); -- OPC_CONST_n(_iconst_1, INT, 1); -- OPC_CONST_n(_iconst_2, INT, 2); -- OPC_CONST_n(_iconst_3, INT, 3); -- OPC_CONST_n(_iconst_4, INT, 4); -- OPC_CONST_n(_iconst_5, INT, 5); -- OPC_CONST_n(_fconst_0, FLOAT, 0.0); -- OPC_CONST_n(_fconst_1, FLOAT, 1.0); -- OPC_CONST_n(_fconst_2, FLOAT, 2.0); -- --#if 0 --#undef OPC_CONST2_n --#define OPC_CONST2_n(opcname, value, key) \ -- CASE(_##opcname): \ -- { \ -- VM##key##2Jvm(&STACK_INFO(DTOS(0)).raw, \ -- VM##key##Const##value()); \ -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); \ -- } --#endif -- --#undef OPC_CONST2_n --#define OPC_CONST2_n(opcname, value, key, kind) \ -- CASE(_##opcname): \ -- { \ -- SET_STACK_ ## kind(VM##key##Const##value(), 1); \ -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); \ -- } -- OPC_CONST2_n(dconst_0, Zero, double, DOUBLE); -- OPC_CONST2_n(dconst_1, One, double, DOUBLE); -- OPC_CONST2_n(lconst_0, Zero, long, LONG); -- OPC_CONST2_n(lconst_1, One, long, LONG); -- -- /* Load constant from constant pool: */ -- -- /* Push a 1-byte signed integer value onto the stack. */ -- CASE(_bipush): -- SET_STACK_INT((jbyte)(pc[1]), 0); -- UPDATE_PC_AND_TOS_AND_CONTINUE(2, 1); -- -- /* Push a 2-byte signed integer constant onto the stack. */ -- CASE(_sipush): -- SET_STACK_INT((int16_t)Bytes::get_Java_u2(pc + 1), 0); -- UPDATE_PC_AND_TOS_AND_CONTINUE(3, 1); -- -- /* load from local variable */ -- -- CASE(_aload): -- SET_STACK_OBJECT(LOCALS_OBJECT(pc[1]), 0); -- UPDATE_PC_AND_TOS_AND_CONTINUE(2, 1); -- -- CASE(_iload): -- CASE(_fload): -- SET_STACK_SLOT(LOCALS_SLOT(pc[1]), 0); -- UPDATE_PC_AND_TOS_AND_CONTINUE(2, 1); -- -- CASE(_lload): -- SET_STACK_LONG_FROM_ADDR(LOCALS_LONG_AT(pc[1]), 1); -- UPDATE_PC_AND_TOS_AND_CONTINUE(2, 2); -- -- CASE(_dload): -- SET_STACK_DOUBLE_FROM_ADDR(LOCALS_DOUBLE_AT(pc[1]), 1); -- UPDATE_PC_AND_TOS_AND_CONTINUE(2, 2); -- --#undef OPC_LOAD_n --#define OPC_LOAD_n(num) \ -- CASE(_aload_##num): \ -- SET_STACK_OBJECT(LOCALS_OBJECT(num), 0); \ -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); \ -- \ -- CASE(_iload_##num): \ -- CASE(_fload_##num): \ -- SET_STACK_SLOT(LOCALS_SLOT(num), 0); \ -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); \ -- \ -- CASE(_lload_##num): \ -- SET_STACK_LONG_FROM_ADDR(LOCALS_LONG_AT(num), 1); \ -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); \ -- CASE(_dload_##num): \ -- SET_STACK_DOUBLE_FROM_ADDR(LOCALS_DOUBLE_AT(num), 1); \ -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); -- -- OPC_LOAD_n(0); -- OPC_LOAD_n(1); -- OPC_LOAD_n(2); -- OPC_LOAD_n(3); -- -- /* store to a local variable */ -- -- CASE(_astore): -- astore(topOfStack, -1, locals, pc[1]); -- UPDATE_PC_AND_TOS_AND_CONTINUE(2, -1); -- -- CASE(_istore): -- CASE(_fstore): -- SET_LOCALS_SLOT(STACK_SLOT(-1), pc[1]); -- UPDATE_PC_AND_TOS_AND_CONTINUE(2, -1); -- -- CASE(_lstore): -- SET_LOCALS_LONG(STACK_LONG(-1), pc[1]); -- UPDATE_PC_AND_TOS_AND_CONTINUE(2, -2); -- -- CASE(_dstore): -- SET_LOCALS_DOUBLE(STACK_DOUBLE(-1), pc[1]); -- UPDATE_PC_AND_TOS_AND_CONTINUE(2, -2); -- -- CASE(_wide): { -- uint16_t reg = Bytes::get_Java_u2(pc + 2); -- -- opcode = pc[1]; -- switch(opcode) { -- case Bytecodes::_aload: -- SET_STACK_OBJECT(LOCALS_OBJECT(reg), 0); -- UPDATE_PC_AND_TOS_AND_CONTINUE(4, 1); -- -- case Bytecodes::_iload: -- case Bytecodes::_fload: -- SET_STACK_SLOT(LOCALS_SLOT(reg), 0); -- UPDATE_PC_AND_TOS_AND_CONTINUE(4, 1); -- -- case Bytecodes::_lload: -- SET_STACK_LONG_FROM_ADDR(LOCALS_LONG_AT(reg), 1); -- UPDATE_PC_AND_TOS_AND_CONTINUE(4, 2); -- -- case Bytecodes::_dload: -- SET_STACK_DOUBLE_FROM_ADDR(LOCALS_LONG_AT(reg), 1); -- UPDATE_PC_AND_TOS_AND_CONTINUE(4, 2); -- -- case Bytecodes::_astore: -- astore(topOfStack, -1, locals, reg); -- UPDATE_PC_AND_TOS_AND_CONTINUE(4, -1); -- -- case Bytecodes::_istore: -- case Bytecodes::_fstore: -- SET_LOCALS_SLOT(STACK_SLOT(-1), reg); -- UPDATE_PC_AND_TOS_AND_CONTINUE(4, -1); -- -- case Bytecodes::_lstore: -- SET_LOCALS_LONG(STACK_LONG(-1), reg); -- UPDATE_PC_AND_TOS_AND_CONTINUE(4, -2); -- -- case Bytecodes::_dstore: -- SET_LOCALS_DOUBLE(STACK_DOUBLE(-1), reg); -- UPDATE_PC_AND_TOS_AND_CONTINUE(4, -2); -- -- case Bytecodes::_iinc: { -- int16_t offset = (int16_t)Bytes::get_Java_u2(pc+4); -- // Be nice to see what this generates.... QQQ -- SET_LOCALS_INT(LOCALS_INT(reg) + offset, reg); -- UPDATE_PC_AND_CONTINUE(6); -- } -- case Bytecodes::_ret: -- pc = istate->method()->code_base() + (intptr_t)(LOCALS_SLOT(reg)); -- UPDATE_PC_AND_CONTINUE(0); -- default: -- VM_JAVA_ERROR(vmSymbols::java_lang_InternalError(), "undefined opcode"); -- } -- } -- -- --#undef OPC_STORE_n --#define OPC_STORE_n(num) \ -- CASE(_astore_##num): \ -- astore(topOfStack, -1, locals, num); \ -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); \ -- CASE(_istore_##num): \ -- CASE(_fstore_##num): \ -- SET_LOCALS_SLOT(STACK_SLOT(-1), num); \ -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); -- -- OPC_STORE_n(0); -- OPC_STORE_n(1); -- OPC_STORE_n(2); -- OPC_STORE_n(3); -- --#undef OPC_DSTORE_n --#define OPC_DSTORE_n(num) \ -- CASE(_dstore_##num): \ -- SET_LOCALS_DOUBLE(STACK_DOUBLE(-1), num); \ -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, -2); \ -- CASE(_lstore_##num): \ -- SET_LOCALS_LONG(STACK_LONG(-1), num); \ -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, -2); -- -- OPC_DSTORE_n(0); -- OPC_DSTORE_n(1); -- OPC_DSTORE_n(2); -- OPC_DSTORE_n(3); -- -- /* stack pop, dup, and insert opcodes */ -- -- -- CASE(_pop): /* Discard the top item on the stack */ -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); -- -- -- CASE(_pop2): /* Discard the top 2 items on the stack */ -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, -2); -- -- -- CASE(_dup): /* Duplicate the top item on the stack */ -- dup(topOfStack); -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); -- -- CASE(_dup2): /* Duplicate the top 2 items on the stack */ -- dup2(topOfStack); -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); -- -- CASE(_dup_x1): /* insert top word two down */ -- dup_x1(topOfStack); -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); -- -- CASE(_dup_x2): /* insert top word three down */ -- dup_x2(topOfStack); -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); -- -- CASE(_dup2_x1): /* insert top 2 slots three down */ -- dup2_x1(topOfStack); -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); -- -- CASE(_dup2_x2): /* insert top 2 slots four down */ -- dup2_x2(topOfStack); -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); -- -- CASE(_swap): { /* swap top two elements on the stack */ -- swap(topOfStack); -- UPDATE_PC_AND_CONTINUE(1); -- } -- -- /* Perform various binary integer operations */ -- --#undef OPC_INT_BINARY --#define OPC_INT_BINARY(opcname, opname, test) \ -- CASE(_i##opcname): \ -- if (test && (STACK_INT(-1) == 0)) { \ -- VM_JAVA_ERROR(vmSymbols::java_lang_ArithmeticException(), \ -- "/ by int zero"); \ -- } \ -- SET_STACK_INT(VMint##opname(STACK_INT(-2), \ -- STACK_INT(-1)), \ -- -2); \ -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); \ -- CASE(_l##opcname): \ -- { \ -- if (test) { \ -- jlong l1 = STACK_LONG(-1); \ -- if (VMlongEqz(l1)) { \ -- VM_JAVA_ERROR(vmSymbols::java_lang_ArithmeticException(), \ -- "/ by long zero"); \ -- } \ -- } \ -- /* First long at (-1,-2) next long at (-3,-4) */ \ -- SET_STACK_LONG(VMlong##opname(STACK_LONG(-3), \ -- STACK_LONG(-1)), \ -- -3); \ -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, -2); \ -- } -- -- OPC_INT_BINARY(add, Add, 0); -- OPC_INT_BINARY(sub, Sub, 0); -- OPC_INT_BINARY(mul, Mul, 0); -- OPC_INT_BINARY(and, And, 0); -- OPC_INT_BINARY(or, Or, 0); -- OPC_INT_BINARY(xor, Xor, 0); -- OPC_INT_BINARY(div, Div, 1); -- OPC_INT_BINARY(rem, Rem, 1); -- -- -- /* Perform various binary floating number operations */ -- /* On some machine/platforms/compilers div zero check can be implicit */ -- --#undef OPC_FLOAT_BINARY --#define OPC_FLOAT_BINARY(opcname, opname) \ -- CASE(_d##opcname): { \ -- SET_STACK_DOUBLE(VMdouble##opname(STACK_DOUBLE(-3), \ -- STACK_DOUBLE(-1)), \ -- -3); \ -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, -2); \ -- } \ -- CASE(_f##opcname): \ -- SET_STACK_FLOAT(VMfloat##opname(STACK_FLOAT(-2), \ -- STACK_FLOAT(-1)), \ -- -2); \ -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); -- -- -- OPC_FLOAT_BINARY(add, Add); -- OPC_FLOAT_BINARY(sub, Sub); -- OPC_FLOAT_BINARY(mul, Mul); -- OPC_FLOAT_BINARY(div, Div); -- OPC_FLOAT_BINARY(rem, Rem); -- -- /* Shift operations -- * Shift left int and long: ishl, lshl -- * Logical shift right int and long w/zero extension: iushr, lushr -- * Arithmetic shift right int and long w/sign extension: ishr, lshr -- */ -- --#undef OPC_SHIFT_BINARY --#define OPC_SHIFT_BINARY(opcname, opname) \ -- CASE(_i##opcname): \ -- SET_STACK_INT(VMint##opname(STACK_INT(-2), \ -- STACK_INT(-1)), \ -- -2); \ -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); \ -- CASE(_l##opcname): \ -- { \ -- SET_STACK_LONG(VMlong##opname(STACK_LONG(-2), \ -- STACK_INT(-1)), \ -- -2); \ -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); \ -- } -- -- OPC_SHIFT_BINARY(shl, Shl); -- OPC_SHIFT_BINARY(shr, Shr); -- OPC_SHIFT_BINARY(ushr, Ushr); -- -- /* Increment local variable by constant */ -- CASE(_iinc): -- { -- // locals[pc[1]].j.i += (jbyte)(pc[2]); -- SET_LOCALS_INT(LOCALS_INT(pc[1]) + (jbyte)(pc[2]), pc[1]); -- UPDATE_PC_AND_CONTINUE(3); -- } -- -- /* negate the value on the top of the stack */ -- -- CASE(_ineg): -- SET_STACK_INT(VMintNeg(STACK_INT(-1)), -1); -- UPDATE_PC_AND_CONTINUE(1); -- -- CASE(_fneg): -- SET_STACK_FLOAT(VMfloatNeg(STACK_FLOAT(-1)), -1); -- UPDATE_PC_AND_CONTINUE(1); -- -- CASE(_lneg): -- { -- SET_STACK_LONG(VMlongNeg(STACK_LONG(-1)), -1); -- UPDATE_PC_AND_CONTINUE(1); -- } -- -- CASE(_dneg): -- { -- SET_STACK_DOUBLE(VMdoubleNeg(STACK_DOUBLE(-1)), -1); -- UPDATE_PC_AND_CONTINUE(1); -- } -- -- /* Conversion operations */ -- -- CASE(_i2f): /* convert top of stack int to float */ -- SET_STACK_FLOAT(VMint2Float(STACK_INT(-1)), -1); -- UPDATE_PC_AND_CONTINUE(1); -- -- CASE(_i2l): /* convert top of stack int to long */ -- { -- // this is ugly QQQ -- jlong r = VMint2Long(STACK_INT(-1)); -- MORE_STACK(-1); // Pop -- SET_STACK_LONG(r, 1); -- -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); -- } -- -- CASE(_i2d): /* convert top of stack int to double */ -- { -- // this is ugly QQQ (why cast to jlong?? ) -- jdouble r = (jlong)STACK_INT(-1); -- MORE_STACK(-1); // Pop -- SET_STACK_DOUBLE(r, 1); -- -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); -- } -- -- CASE(_l2i): /* convert top of stack long to int */ -- { -- jint r = VMlong2Int(STACK_LONG(-1)); -- MORE_STACK(-2); // Pop -- SET_STACK_INT(r, 0); -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); -- } -- -- CASE(_l2f): /* convert top of stack long to float */ -- { -- jlong r = STACK_LONG(-1); -- MORE_STACK(-2); // Pop -- SET_STACK_FLOAT(VMlong2Float(r), 0); -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); -- } -- -- CASE(_l2d): /* convert top of stack long to double */ -- { -- jlong r = STACK_LONG(-1); -- MORE_STACK(-2); // Pop -- SET_STACK_DOUBLE(VMlong2Double(r), 1); -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); -- } -- -- CASE(_f2i): /* Convert top of stack float to int */ -- SET_STACK_INT(SharedRuntime::f2i(STACK_FLOAT(-1)), -1); -- UPDATE_PC_AND_CONTINUE(1); -- -- CASE(_f2l): /* convert top of stack float to long */ -- { -- jlong r = SharedRuntime::f2l(STACK_FLOAT(-1)); -- MORE_STACK(-1); // POP -- SET_STACK_LONG(r, 1); -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); -- } -- -- CASE(_f2d): /* convert top of stack float to double */ -- { -- jfloat f; -- jdouble r; -- f = STACK_FLOAT(-1); --#ifdef IA64 -- // IA64 gcc bug -- r = ( f == 0.0f ) ? (jdouble) f : (jdouble) f + ia64_double_zero; --#else -- r = (jdouble) f; --#endif -- MORE_STACK(-1); // POP -- SET_STACK_DOUBLE(r, 1); -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); -- } -- -- CASE(_d2i): /* convert top of stack double to int */ -- { -- jint r1 = SharedRuntime::d2i(STACK_DOUBLE(-1)); -- MORE_STACK(-2); -- SET_STACK_INT(r1, 0); -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); -- } -- -- CASE(_d2f): /* convert top of stack double to float */ -- { -- jfloat r1 = VMdouble2Float(STACK_DOUBLE(-1)); -- MORE_STACK(-2); -- SET_STACK_FLOAT(r1, 0); -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); -- } -- -- CASE(_d2l): /* convert top of stack double to long */ -- { -- jlong r1 = SharedRuntime::d2l(STACK_DOUBLE(-1)); -- MORE_STACK(-2); -- SET_STACK_LONG(r1, 1); -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); -- } -- -- CASE(_i2b): -- SET_STACK_INT(VMint2Byte(STACK_INT(-1)), -1); -- UPDATE_PC_AND_CONTINUE(1); -- -- CASE(_i2c): -- SET_STACK_INT(VMint2Char(STACK_INT(-1)), -1); -- UPDATE_PC_AND_CONTINUE(1); -- -- CASE(_i2s): -- SET_STACK_INT(VMint2Short(STACK_INT(-1)), -1); -- UPDATE_PC_AND_CONTINUE(1); -- -- /* comparison operators */ -- -- --#define COMPARISON_OP(name, comparison) \ -- CASE(_if_icmp##name): { \ -- int skip = (STACK_INT(-2) comparison STACK_INT(-1)) \ -- ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3; \ -- address branch_pc = pc; \ -- UPDATE_PC_AND_TOS(skip, -2); \ -- DO_BACKEDGE_CHECKS(skip, branch_pc); \ -- CONTINUE; \ -- } \ -- CASE(_if##name): { \ -- int skip = (STACK_INT(-1) comparison 0) \ -- ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3; \ -- address branch_pc = pc; \ -- UPDATE_PC_AND_TOS(skip, -1); \ -- DO_BACKEDGE_CHECKS(skip, branch_pc); \ -- CONTINUE; \ -- } -- --#define COMPARISON_OP2(name, comparison) \ -- COMPARISON_OP(name, comparison) \ -- CASE(_if_acmp##name): { \ -- int skip = (STACK_OBJECT(-2) comparison STACK_OBJECT(-1)) \ -- ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3; \ -- address branch_pc = pc; \ -- UPDATE_PC_AND_TOS(skip, -2); \ -- DO_BACKEDGE_CHECKS(skip, branch_pc); \ -- CONTINUE; \ -- } -- --#define NULL_COMPARISON_NOT_OP(name) \ -- CASE(_if##name): { \ -- int skip = (!(STACK_OBJECT(-1) == 0)) \ -- ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3; \ -- address branch_pc = pc; \ -- UPDATE_PC_AND_TOS(skip, -1); \ -- DO_BACKEDGE_CHECKS(skip, branch_pc); \ -- CONTINUE; \ -- } -- --#define NULL_COMPARISON_OP(name) \ -- CASE(_if##name): { \ -- int skip = ((STACK_OBJECT(-1) == 0)) \ -- ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3; \ -- address branch_pc = pc; \ -- UPDATE_PC_AND_TOS(skip, -1); \ -- DO_BACKEDGE_CHECKS(skip, branch_pc); \ -- CONTINUE; \ -- } -- COMPARISON_OP(lt, <); -- COMPARISON_OP(gt, >); -- COMPARISON_OP(le, <=); -- COMPARISON_OP(ge, >=); -- COMPARISON_OP2(eq, ==); /* include ref comparison */ -- COMPARISON_OP2(ne, !=); /* include ref comparison */ -- NULL_COMPARISON_OP(null); -- NULL_COMPARISON_NOT_OP(nonnull); -- -- /* Goto pc at specified offset in switch table. */ -- -- CASE(_tableswitch): { -- jint* lpc = (jint*)VMalignWordUp(pc+1); -- int32_t key = STACK_INT(-1); -- int32_t low = Bytes::get_Java_u4((address)&lpc[1]); -- int32_t high = Bytes::get_Java_u4((address)&lpc[2]); -- int32_t skip; -- key -= low; -- skip = ((uint32_t) key > (uint32_t)(high - low)) -- ? Bytes::get_Java_u4((address)&lpc[0]) -- : Bytes::get_Java_u4((address)&lpc[key + 3]); -- // Does this really need a full backedge check (osr?) -- address branch_pc = pc; -- UPDATE_PC_AND_TOS(skip, -1); -- DO_BACKEDGE_CHECKS(skip, branch_pc); -- CONTINUE; -- } -- -- /* Goto pc whose table entry matches specified key */ -- -- CASE(_lookupswitch): { -- jint* lpc = (jint*)VMalignWordUp(pc+1); -- int32_t key = STACK_INT(-1); -- int32_t skip = Bytes::get_Java_u4((address) lpc); /* default amount */ -- int32_t npairs = Bytes::get_Java_u4((address) &lpc[1]); -- while (--npairs >= 0) { -- lpc += 2; -- if (key == (int32_t)Bytes::get_Java_u4((address)lpc)) { -- skip = Bytes::get_Java_u4((address)&lpc[1]); -- break; -- } -- } -- address branch_pc = pc; -- UPDATE_PC_AND_TOS(skip, -1); -- DO_BACKEDGE_CHECKS(skip, branch_pc); -- CONTINUE; -- } -- -- CASE(_fcmpl): -- CASE(_fcmpg): -- { -- SET_STACK_INT(VMfloatCompare(STACK_FLOAT(-2), -- STACK_FLOAT(-1), -- (opcode == Bytecodes::_fcmpl ? -1 : 1)), -- -2); -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); -- } -- -- CASE(_dcmpl): -- CASE(_dcmpg): -- { -- int r = VMdoubleCompare(STACK_DOUBLE(-3), -- STACK_DOUBLE(-1), -- (opcode == Bytecodes::_dcmpl ? -1 : 1)); -- MORE_STACK(-4); // Pop -- SET_STACK_INT(r, 0); -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); -- } -- -- CASE(_lcmp): -- { -- int r = VMlongCompare(STACK_LONG(-3), STACK_LONG(-1)); -- MORE_STACK(-4); -- SET_STACK_INT(r, 0); -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); -- } -- -- -- /* Return from a method */ -- -- CASE(_areturn): -- CASE(_ireturn): -- CASE(_freturn): -- { -- // Allow a safepoint before returning to frame manager. -- SAFEPOINT; -- -- goto handle_return; -- } -- -- CASE(_lreturn): -- CASE(_dreturn): -- { -- // Allow a safepoint before returning to frame manager. -- SAFEPOINT; -- goto handle_return; -- } -- -- CASE(_return_register_finalizer): { -- -- oop rcvr = LOCALS_OBJECT(0); -- if (rcvr->klass()->klass_part()->has_finalizer()) { -- CALL_VM(InterpreterRuntime::register_finalizer(THREAD, rcvr), handle_exception); -- } -- goto handle_return; -- } -- CASE(_return): { -- -- // Allow a safepoint before returning to frame manager. -- SAFEPOINT; -- goto handle_return; -- } -- -- /* Array access byte-codes */ -- -- /* Every array access byte-code starts out like this */ --#define ARRAY_INTRO(arrayOff) \ -- arrayOopDesc* arrObj = (arrayOopDesc*)STACK_OBJECT(arrayOff); \ -- jint index = STACK_INT(arrayOff + 1); \ -- char message[jintAsStringSize]; \ -- CHECK_NULL(arrObj); \ -- if ((uint32_t)index >= (uint32_t)arrObj->length()) { \ -- sprintf(message, "%d", index); \ -- VM_JAVA_ERROR(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), \ -- message); \ -- } -- -- /* 32-bit loads. These handle conversion from < 32-bit types */ --#define ARRAY_LOADTO32(T, T2, format, stackRes, extra) \ -- { \ -- ARRAY_INTRO(-2); \ -- extra; \ -- SET_ ## stackRes(*(T2 *)(((address) arrObj->base(T)) + index * sizeof(T2)), \ -- -2); \ -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); \ -- } -- -- /* 64-bit loads */ --#define ARRAY_LOADTO64(T,T2, stackRes, extra) \ -- { \ -- ARRAY_INTRO(-2); \ -- SET_ ## stackRes(*(T2 *)(((address) arrObj->base(T)) + index * sizeof(T2)), -1); \ -- extra; \ -- UPDATE_PC_AND_CONTINUE(1); \ -- } -- -- CASE(_iaload): -- ARRAY_LOADTO32(T_INT, jint, "%d", STACK_INT, 0); -- CASE(_faload): -- ARRAY_LOADTO32(T_FLOAT, jfloat, "%f", STACK_FLOAT, 0); -- CASE(_aaload): -- ARRAY_LOADTO32(T_OBJECT, oop, INTPTR_FORMAT, STACK_OBJECT, 0); -- CASE(_baload): -- ARRAY_LOADTO32(T_BYTE, jbyte, "%d", STACK_INT, 0); -- CASE(_caload): -- ARRAY_LOADTO32(T_CHAR, jchar, "%d", STACK_INT, 0); -- CASE(_saload): -- ARRAY_LOADTO32(T_SHORT, jshort, "%d", STACK_INT, 0); -- CASE(_laload): -- ARRAY_LOADTO64(T_LONG, jlong, STACK_LONG, 0); -- CASE(_daload): -- ARRAY_LOADTO64(T_DOUBLE, jdouble, STACK_DOUBLE, 0); -- -- /* 32-bit stores. These handle conversion to < 32-bit types */ --#define ARRAY_STOREFROM32(T, T2, format, stackSrc, extra) \ -- { \ -- ARRAY_INTRO(-3); \ -- extra; \ -- *(T2 *)(((address) arrObj->base(T)) + index * sizeof(T2)) = stackSrc( -1); \ -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, -3); \ -- } -- -- /* 64-bit stores */ --#define ARRAY_STOREFROM64(T, T2, stackSrc, extra) \ -- { \ -- ARRAY_INTRO(-4); \ -- extra; \ -- *(T2 *)(((address) arrObj->base(T)) + index * sizeof(T2)) = stackSrc( -1); \ -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, -4); \ -- } -- -- CASE(_iastore): -- ARRAY_STOREFROM32(T_INT, jint, "%d", STACK_INT, 0); -- CASE(_fastore): -- ARRAY_STOREFROM32(T_FLOAT, jfloat, "%f", STACK_FLOAT, 0); -- /* -- * This one looks different because of the assignability check -- */ -- CASE(_aastore): { -- oop rhsObject = STACK_OBJECT(-1); -- ARRAY_INTRO( -3); -- // arrObj, index are set -- if (rhsObject != NULL) { -- /* Check assignability of rhsObject into arrObj */ -- klassOop rhsKlassOop = rhsObject->klass(); // EBX (subclass) -- assert(arrObj->klass()->klass()->klass_part()->oop_is_objArrayKlass(), "Ack not an objArrayKlass"); -- klassOop elemKlassOop = ((objArrayKlass*) arrObj->klass()->klass_part())->element_klass(); // superklass EAX -- // -- // Check for compatibilty. This check must not GC!! -- // Seems way more expensive now that we must dispatch -- // -- if (rhsKlassOop != elemKlassOop && !rhsKlassOop->klass_part()->is_subtype_of(elemKlassOop)) { // ebx->is... -- VM_JAVA_ERROR(vmSymbols::java_lang_ArrayStoreException(), ""); -- } -- } -- oop* elem_loc = (oop*)(((address) arrObj->base(T_OBJECT)) + index * sizeof(oop)); -- // *(oop*)(((address) arrObj->base(T_OBJECT)) + index * sizeof(oop)) = rhsObject; -- *elem_loc = rhsObject; -- // Mark the card -- OrderAccess::release_store(&BYTE_MAP_BASE[(uintptr_t)elem_loc >> CardTableModRefBS::card_shift], 0); -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, -3); -- } -- CASE(_bastore): -- ARRAY_STOREFROM32(T_BYTE, jbyte, "%d", STACK_INT, 0); -- CASE(_castore): -- ARRAY_STOREFROM32(T_CHAR, jchar, "%d", STACK_INT, 0); -- CASE(_sastore): -- ARRAY_STOREFROM32(T_SHORT, jshort, "%d", STACK_INT, 0); -- CASE(_lastore): -- ARRAY_STOREFROM64(T_LONG, jlong, STACK_LONG, 0); -- CASE(_dastore): -- ARRAY_STOREFROM64(T_DOUBLE, jdouble, STACK_DOUBLE, 0); -- -- CASE(_arraylength): -- { -- arrayOopDesc *ary = (arrayOopDesc *) STACK_OBJECT(-1); -- CHECK_NULL(ary); -- SET_STACK_INT(ary->length(), -1); -- UPDATE_PC_AND_CONTINUE(1); -- } -- -- /* monitorenter and monitorexit for locking/unlocking an object */ -- -- CASE(_monitorenter): { -- oop lockee = STACK_OBJECT(-1); -- // derefing's lockee ought to provoke implicit null check -- CHECK_NULL(lockee); -- // find a free monitor or one already allocated for this object -- // if we find a matching object then we need a new monitor -- // since this is recursive enter -- BasicObjectLock* limit = istate->monitor_base(); -- BasicObjectLock* most_recent = (BasicObjectLock*) istate->stack_base(); -- BasicObjectLock* entry = NULL; -- while (most_recent != limit ) { -- if (most_recent->obj() == NULL) entry = most_recent; -- else if (most_recent->obj() == lockee) break; -- most_recent++; -- } -- if (entry != NULL) { -- entry->set_obj(lockee); -- markOop displaced = lockee->mark()->set_unlocked(); -- entry->lock()->set_displaced_header(displaced); -- if (Atomic::cmpxchg_ptr(entry, lockee->mark_addr(), displaced) != displaced) { -- // Is it simple recursive case? -- if (THREAD->is_lock_owned((address) displaced->clear_lock_bits())) { -- entry->lock()->set_displaced_header(NULL); -- } else { -- CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception); -- } -- } -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); -- } else { -- istate->set_msg(more_monitors); -- // HACK FIX LATER -- // Why was this needed? Seems to be useless now -- // istate->set_callee((methodOop) lockee); -- UPDATE_PC_AND_RETURN(0); // Re-execute -- } -- } -- -- CASE(_monitorexit): { -- oop lockee = STACK_OBJECT(-1); -- CHECK_NULL(lockee); -- // derefing's lockee ought to provoke implicit null check -- // find our monitor slot -- BasicObjectLock* limit = istate->monitor_base(); -- BasicObjectLock* most_recent = (BasicObjectLock*) istate->stack_base(); -- while (most_recent != limit ) { -- if ((most_recent)->obj() == lockee) { -- BasicLock* lock = most_recent->lock(); -- markOop header = lock->displaced_header(); -- most_recent->set_obj(NULL); -- // If it isn't recursive we either must swap old header or call the runtime -- if (header != NULL) { -- if (Atomic::cmpxchg_ptr(header, lockee->mark_addr(), lock) != lock) { -- // restore object for the slow case -- most_recent->set_obj(lockee); -- CALL_VM(InterpreterRuntime::monitorexit(THREAD, most_recent), handle_exception); -- } -- } -- UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); -- } -- most_recent++; -- } -- // Need to throw illegal monitor state exception -- CALL_VM(InterpreterRuntime::throw_illegal_monitor_state_exception(THREAD), handle_exception); -- // Should never reach here... -- assert(false, "Should have thrown illegal monitor exception"); -- } -- -- /* All of the non-quick opcodes. */ -- -- /* -Set clobbersCpIndex true if the quickened opcode clobbers the -- * constant pool index in the instruction. -- */ -- CASE(_getfield): -- CASE(_getstatic): -- { -- u2 index; -- ConstantPoolCacheEntry* cache; -- index = Bytes::get_native_u2(pc+1); -- -- // QQQ Need to make this as inlined as possible. Probably need to -- // split all the bytecode cases out so c++ compiler has a chance -- // for constant prop to fold everything possible away. -- -- cache = cp->entry_at(index); -- if (!cache->is_resolved((Bytecodes::Code)opcode)) { -- CALL_VM(InterpreterRuntime::resolve_get_put(THREAD, (Bytecodes::Code)opcode), -- handle_exception); -- cache = cp->entry_at(index); -- } -- --#ifdef VM_JVMTI -- if (_jvmti_interp_events) { -- int *count_addr; -- oop obj; -- // Check to see if a field modification watch has been set -- // before we take the time to call into the VM. -- count_addr = (int *)JvmtiExport::get_field_access_count_addr(); -- if ( *count_addr > 0 ) { -- if ((Bytecodes::Code)opcode == Bytecodes::_getstatic) { -- obj = (oop)NULL; -- } else { -- obj = (oop) STACK_OBJECT(-1); -- } -- CALL_VM(InterpreterRuntime::post_field_access(THREAD, -- obj, -- cache), -- handle_exception); -- } -- } --#endif /* VM_JVMTI */ -- -- oop obj; -- if ((Bytecodes::Code)opcode == Bytecodes::_getstatic) { -- obj = (oop) cache->f1(); -- MORE_STACK(1); // Assume single slot push -- } else { -- obj = (oop) STACK_OBJECT(-1); -- CHECK_NULL(obj); -- } -- -- // -- // Now store the result on the stack -- // -- TosState tos_type = cache->flag_state(); -- int field_offset = cache->f2(); -- if (cache->is_volatile()) { -- if (tos_type == atos) { -- SET_STACK_OBJECT(obj->obj_field_acquire(field_offset), -1); -- } else if (tos_type == itos) { -- SET_STACK_INT(obj->int_field_acquire(field_offset), -1); -- } else if (tos_type == ltos) { -- SET_STACK_LONG(obj->long_field_acquire(field_offset), 0); -- MORE_STACK(1); -- } else if (tos_type == btos) { -- SET_STACK_INT(obj->byte_field_acquire(field_offset), -1); -- } else if (tos_type == ctos) { -- SET_STACK_INT(obj->char_field_acquire(field_offset), -1); -- } else if (tos_type == stos) { -- SET_STACK_INT(obj->short_field_acquire(field_offset), -1); -- } else if (tos_type == ftos) { -- SET_STACK_FLOAT(obj->float_field_acquire(field_offset), -1); -- } else { -- SET_STACK_DOUBLE(obj->double_field_acquire(field_offset), 0); -- MORE_STACK(1); -- } -- } else { -- if (tos_type == atos) { -- SET_STACK_OBJECT(obj->obj_field(field_offset), -1); -- } else if (tos_type == itos) { -- SET_STACK_INT(obj->int_field(field_offset), -1); -- } else if (tos_type == ltos) { -- SET_STACK_LONG(obj->long_field(field_offset), 0); -- MORE_STACK(1); -- } else if (tos_type == btos) { -- SET_STACK_INT(obj->byte_field(field_offset), -1); -- } else if (tos_type == ctos) { -- SET_STACK_INT(obj->char_field(field_offset), -1); -- } else if (tos_type == stos) { -- SET_STACK_INT(obj->short_field(field_offset), -1); -- } else if (tos_type == ftos) { -- SET_STACK_FLOAT(obj->float_field(field_offset), -1); -- } else { -- SET_STACK_DOUBLE(obj->double_field(field_offset), 0); -- MORE_STACK(1); -- } -- } -- -- UPDATE_PC_AND_CONTINUE(3); -- } -- -- CASE(_putfield): -- CASE(_putstatic): -- { -- u2 index = Bytes::get_native_u2(pc+1); -- ConstantPoolCacheEntry* cache = cp->entry_at(index); -- if (!cache->is_resolved((Bytecodes::Code)opcode)) { -- CALL_VM(InterpreterRuntime::resolve_get_put(THREAD, (Bytecodes::Code)opcode), -- handle_exception); -- cache = cp->entry_at(index); -- } -- --#ifdef VM_JVMTI -- if (_jvmti_interp_events) { -- int *count_addr; -- oop obj; -- // Check to see if a field modification watch has been set -- // before we take the time to call into the VM. -- count_addr = (int *)JvmtiExport::get_field_modification_count_addr(); -- if ( *count_addr > 0 ) { -- if ((Bytecodes::Code)opcode == Bytecodes::_putstatic) { -- obj = (oop)NULL; -- } -- else { -- if (cache->is_long() || cache->is_double()) { -- obj = (oop) STACK_OBJECT(-3); -- } else { -- obj = (oop) STACK_OBJECT(-2); -- } -- } -- -- CALL_VM(InterpreterRuntime::post_field_modification(THREAD, -- obj, -- cache, -- (jvalue *)STACK_SLOT(-1)), -- handle_exception); -- } -- } --#endif /* VM_JVMTI */ -- -- // QQQ Need to make this as inlined as possible. Probably need to split all the bytecode cases -- // out so c++ compiler has a chance for constant prop to fold everything possible away. -- -- oop obj; -- int count; -- TosState tos_type = cache->flag_state(); -- -- count = -1; -- if (tos_type == ltos || tos_type == dtos) { -- --count; -- } -- if ((Bytecodes::Code)opcode == Bytecodes::_putstatic) { -- obj = (oop) cache->f1(); -- } else { -- --count; -- obj = (oop) STACK_OBJECT(count); -- CHECK_NULL(obj); -- } -- -- // -- // Now store the result -- // -- int field_offset = cache->f2(); -- if (cache->is_volatile()) { -- if (tos_type == itos) { -- obj->release_int_field_put(field_offset, STACK_INT(-1)); -- } else if (tos_type == atos) { -- obj->release_obj_field_put(field_offset, STACK_OBJECT(-1)); -- OrderAccess::release_store(&BYTE_MAP_BASE[(uintptr_t)obj >> CardTableModRefBS::card_shift], 0); -- } else if (tos_type == btos) { -- obj->release_byte_field_put(field_offset, STACK_INT(-1)); -- } else if (tos_type == ltos) { -- obj->release_long_field_put(field_offset, STACK_LONG(-1)); -- } else if (tos_type == ctos) { -- obj->release_char_field_put(field_offset, STACK_INT(-1)); -- } else if (tos_type == stos) { -- obj->release_short_field_put(field_offset, STACK_INT(-1)); -- } else if (tos_type == ftos) { -- obj->release_float_field_put(field_offset, STACK_FLOAT(-1)); -- } else { -- obj->release_double_field_put(field_offset, STACK_DOUBLE(-1)); -- } -- OrderAccess::storeload(); -- } else { -- if (tos_type == itos) { -- obj->int_field_put(field_offset, STACK_INT(-1)); -- } else if (tos_type == atos) { -- obj->obj_field_put(field_offset, STACK_OBJECT(-1)); -- OrderAccess::release_store(&BYTE_MAP_BASE[(uintptr_t)obj >> CardTableModRefBS::card_shift], 0); -- } else if (tos_type == btos) { -- obj->byte_field_put(field_offset, STACK_INT(-1)); -- } else if (tos_type == ltos) { -- obj->long_field_put(field_offset, STACK_LONG(-1)); -- } else if (tos_type == ctos) { -- obj->char_field_put(field_offset, STACK_INT(-1)); -- } else if (tos_type == stos) { -- obj->short_field_put(field_offset, STACK_INT(-1)); -- } else if (tos_type == ftos) { -- obj->float_field_put(field_offset, STACK_FLOAT(-1)); -- } else { -- obj->double_field_put(field_offset, STACK_DOUBLE(-1)); -- } -- } -- -- UPDATE_PC_AND_TOS_AND_CONTINUE(3, count); -- } -- -- CASE(_new): { -- u2 index = Bytes::get_Java_u2(pc+1); -- constantPoolOop constants = istate->method()->constants(); -- if (!constants->tag_at(index).is_unresolved_klass()) { -- // Make sure klass is initialized and doesn't have a finalizer -- oop entry = (klassOop) *constants->obj_at_addr(index); -- assert(entry->is_klass(), "Should be resolved klass"); -- klassOop k_entry = (klassOop) entry; -- assert(k_entry->klass_part()->oop_is_instance(), "Should be instanceKlass"); -- instanceKlass* ik = (instanceKlass*) k_entry->klass_part(); -- if ( ik->is_initialized() && ik->can_be_fastpath_allocated() ) { -- size_t obj_size = ik->size_helper(); -- oop result = NULL; -- bool need_zero = false; -- if (UseTLAB) { -- result = (oop) THREAD->tlab().allocate(obj_size); -- } -- if (result == NULL) { -- need_zero = true; -- // Try allocate in shared eden -- retry: -- HeapWord* compare_to = *Universe::heap()->top_addr(); -- HeapWord* new_top = compare_to + obj_size; -- if (new_top <= *Universe::heap()->end_addr()) { -- if (Atomic::cmpxchg_ptr(new_top, Universe::heap()->top_addr(), compare_to) != compare_to) { -- goto retry; -- } -- result = (oop) compare_to; -- } -- } -- if (result != NULL) { -- // Initialize object (if nonzero size and need) and then the header -- if (need_zero ) { -- HeapWord* to_zero = (HeapWord*) result + sizeof(oopDesc) / oopSize; -- obj_size -= sizeof(oopDesc) / oopSize; -- if (obj_size > 0 ) { -- memset(to_zero, 0, obj_size * HeapWordSize); -- } -- } -- if (UseBiasedLocking) { -- result->set_mark(ik->prototype_header()); -- } else { -- result->set_mark(markOopDesc::prototype()); -- } -- result->set_klass(k_entry); -- SET_STACK_OBJECT(result, 0); -- UPDATE_PC_AND_TOS_AND_CONTINUE(3, 1); -- } -- } -- } -- // Slow case allocation -- CALL_VM(InterpreterRuntime::_new(THREAD, istate->method()->constants(), index), -- handle_exception); -- SET_STACK_OBJECT(THREAD->vm_result(), 0); -- THREAD->set_vm_result(NULL); -- UPDATE_PC_AND_TOS_AND_CONTINUE(3, 1); -- } -- CASE(_anewarray): { -- u2 index = Bytes::get_Java_u2(pc+1); -- jint size = STACK_INT(-1); -- CALL_VM(InterpreterRuntime::anewarray(THREAD, istate->method()->constants(), index, size), -- handle_exception); -- SET_STACK_OBJECT(THREAD->vm_result(), -1); -- THREAD->set_vm_result(NULL); -- UPDATE_PC_AND_CONTINUE(3); -- } -- CASE(_multianewarray): { -- jint dims = *(pc+3); -- jint size = STACK_INT(-1); -- // stack grows down, dimensions are up! -- jint *dimarray = -- (jint*)&topOfStack[dims * Interpreter::stackElementWords()+ -- Interpreter::stackElementWords()-1]; -- //adjust pointer to start of stack element -- CALL_VM(InterpreterRuntime::multianewarray(THREAD, dimarray), -- handle_exception); -- SET_STACK_OBJECT(THREAD->vm_result(), -dims); -- THREAD->set_vm_result(NULL); -- UPDATE_PC_AND_TOS_AND_CONTINUE(4, -(dims-1)); -- } -- CASE(_checkcast): -- if (STACK_OBJECT(-1) != NULL) { -- u2 index = Bytes::get_Java_u2(pc+1); -- if (ProfileInterpreter) { -- // needs Profile_checkcast QQQ -- ShouldNotReachHere(); -- } -- // Constant pool may have actual klass or unresolved klass. If it is -- // unresolved we must resolve it -- if (istate->method()->constants()->tag_at(index).is_unresolved_klass()) { -- CALL_VM(InterpreterRuntime::quicken_io_cc(THREAD), handle_exception); -- } -- klassOop klassOf = (klassOop) *(istate->method()->constants()->obj_at_addr(index)); -- klassOop objKlassOop = STACK_OBJECT(-1)->klass(); //ebx -- // -- // Check for compatibilty. This check must not GC!! -- // Seems way more expensive now that we must dispatch -- // -- if (objKlassOop != klassOf && -- !objKlassOop->klass_part()->is_subtype_of(klassOf)) { -- ResourceMark rm(THREAD); -- const char* objName = Klass::cast(objKlassOop)->external_name(); -- const char* klassName = Klass::cast(klassOf)->external_name(); -- char* message = SharedRuntime::generate_class_cast_message( -- objName, klassName); -- VM_JAVA_ERROR(vmSymbols::java_lang_ClassCastException(), message); -- } -- } else { -- if (UncommonNullCast) { --// istate->method()->set_null_cast_seen(); --// [RGV] Not sure what to do here! -- ShouldNotReachHere(); -- -- } -- } -- UPDATE_PC_AND_CONTINUE(3); -- -- CASE(_instanceof): -- if (STACK_OBJECT(-1) == NULL) { -- SET_STACK_INT(0, -1); -- } else { -- u2 index = Bytes::get_Java_u2(pc+1); -- // Constant pool may have actual klass or unresolved klass. If it is -- // unresolved we must resolve it -- if (istate->method()->constants()->tag_at(index).is_unresolved_klass()) { -- CALL_VM(InterpreterRuntime::quicken_io_cc(THREAD), handle_exception); -- } -- klassOop klassOf = (klassOop) *(istate->method()->constants()->obj_at_addr(index)); -- klassOop objKlassOop = STACK_OBJECT(-1)->klass(); -- // -- // Check for compatibilty. This check must not GC!! -- // Seems way more expensive now that we must dispatch -- // -- if ( objKlassOop == klassOf || objKlassOop->klass_part()->is_subtype_of(klassOf)) { -- SET_STACK_INT(1, -1); -- } else { -- SET_STACK_INT(0, -1); -- } -- } -- UPDATE_PC_AND_CONTINUE(3); -- -- CASE(_ldc_w): -- CASE(_ldc): -- { -- u2 index; -- bool wide = false; -- int incr = 2; // frequent case -- if (opcode == Bytecodes::_ldc) { -- index = pc[1]; -- } else { -- index = Bytes::get_Java_u2(pc+1); -- incr = 3; -- wide = true; -- } -- -- constantPoolOop constants = istate->method()->constants(); -- switch (constants->tag_at(index).value()) { -- case JVM_CONSTANT_Integer: -- SET_STACK_INT(constants->int_at(index), 0); -- break; -- -- case JVM_CONSTANT_Float: -- SET_STACK_FLOAT(constants->float_at(index), 0); -- break; -- -- case JVM_CONSTANT_String: -- SET_STACK_OBJECT(constants->resolved_string_at(index), 0); -- break; -- -- case JVM_CONSTANT_Class: -- SET_STACK_OBJECT(constants->resolved_klass_at(index)->klass_part()->java_mirror(), 0); -- break; -- -- case JVM_CONSTANT_UnresolvedString: -- case JVM_CONSTANT_UnresolvedClass: -- case JVM_CONSTANT_UnresolvedClassInError: -- CALL_VM(InterpreterRuntime::ldc(THREAD, wide), handle_exception); -- SET_STACK_OBJECT(THREAD->vm_result(), 0); -- THREAD->set_vm_result(NULL); -- break; -- --#if 0 -- CASE(_fast_igetfield): -- CASE(_fastagetfield): -- CASE(_fast_aload_0): -- CASE(_fast_iaccess_0): -- CASE(__fast_aaccess_0): -- CASE(_fast_linearswitch): -- CASE(_fast_binaryswitch): -- fatal("unsupported fast bytecode"); --#endif -- -- default: ShouldNotReachHere(); -- } -- UPDATE_PC_AND_TOS_AND_CONTINUE(incr, 1); -- } -- -- CASE(_ldc2_w): -- { -- u2 index = Bytes::get_Java_u2(pc+1); -- -- constantPoolOop constants = istate->method()->constants(); -- switch (constants->tag_at(index).value()) { -- -- case JVM_CONSTANT_Long: -- SET_STACK_LONG(constants->long_at(index), 1); -- break; -- -- case JVM_CONSTANT_Double: -- SET_STACK_DOUBLE(constants->double_at(index), 1); -- break; -- default: ShouldNotReachHere(); -- } -- UPDATE_PC_AND_TOS_AND_CONTINUE(3, 2); -- } -- -- CASE(_invokeinterface): { -- u2 index = Bytes::get_native_u2(pc+1); -- -- // QQQ Need to make this as inlined as possible. Probably need to split all the bytecode cases -- // out so c++ compiler has a chance for constant prop to fold everything possible away. -- -- ConstantPoolCacheEntry* cache = cp->entry_at(index); -- if (!cache->is_resolved((Bytecodes::Code)opcode)) { -- CALL_VM(InterpreterRuntime::resolve_invoke(THREAD, (Bytecodes::Code)opcode), -- handle_exception); -- cache = cp->entry_at(index); -- } -- -- istate->set_msg(call_method); -- -- // Special case of invokeinterface called for virtual method of -- // java.lang.Object. See cpCacheOop.cpp for details. -- // This code isn't produced by javac, but could be produced by -- // another compliant java compiler. -- if (cache->is_methodInterface()) { -- methodOop callee; -- CHECK_NULL(STACK_OBJECT(-(cache->parameter_size()))); -- if (cache->is_vfinal()) { -- callee = (methodOop) cache->f2(); -- } else { -- // get receiver -- int parms = cache->parameter_size(); -- // Same comments as invokevirtual apply here -- instanceKlass* rcvrKlass = (instanceKlass*) -- STACK_OBJECT(-parms)->klass()->klass_part(); -- callee = (methodOop) rcvrKlass->start_of_vtable()[ cache->f2()]; -- } -- istate->set_callee(callee); -- istate->set_callee_entry_point(callee->from_interpreted_entry()); --#ifdef VM_JVMTI -- if (JvmtiExport::can_post_interpreter_events() && THREAD->is_interp_only_mode()) { -- istate->set_callee_entry_point(callee->interpreter_entry()); -- } --#endif /* VM_JVMTI */ -- istate->set_bcp_advance(5); -- UPDATE_PC_AND_RETURN(0); // I'll be back... -- } -- -- // this could definitely be cleaned up QQQ -- methodOop callee; -- klassOop iclass = (klassOop)cache->f1(); -- // instanceKlass* interface = (instanceKlass*) iclass->klass_part(); -- // get receiver -- int parms = cache->parameter_size(); -- oop rcvr = STACK_OBJECT(-parms); -- CHECK_NULL(rcvr); -- instanceKlass* int2 = (instanceKlass*) rcvr->klass()->klass_part(); -- itableOffsetEntry* ki = (itableOffsetEntry*) int2->start_of_itable(); -- int i; -- for ( i = 0 ; i < int2->itable_length() ; i++, ki++ ) { -- if (ki->interface_klass() == iclass) break; -- } -- // If the interface isn't found, this class doesn't implement this -- // interface. The link resolver checks this but only for the first -- // time this interface is called. -- if (i == int2->itable_length()) { -- VM_JAVA_ERROR(vmSymbols::java_lang_IncompatibleClassChangeError(), ""); -- } -- int mindex = cache->f2(); -- itableMethodEntry* im = ki->first_method_entry(rcvr->klass()); -- callee = im[mindex].method(); -- if (callee == NULL) { -- VM_JAVA_ERROR(vmSymbols::java_lang_AbstractMethodError(), ""); -- } -- -- istate->set_callee(callee); -- istate->set_callee_entry_point(callee->from_interpreted_entry()); --#ifdef VM_JVMTI -- if (JvmtiExport::can_post_interpreter_events() && THREAD->is_interp_only_mode()) { -- istate->set_callee_entry_point(callee->interpreter_entry()); -- } --#endif /* VM_JVMTI */ -- istate->set_bcp_advance(5); -- UPDATE_PC_AND_RETURN(0); // I'll be back... -- } -- -- CASE(_invokevirtual): -- CASE(_invokespecial): -- CASE(_invokestatic): { -- u2 index = Bytes::get_native_u2(pc+1); -- -- ConstantPoolCacheEntry* cache = cp->entry_at(index); -- // QQQ Need to make this as inlined as possible. Probably need to split all the bytecode cases -- // out so c++ compiler has a chance for constant prop to fold everything possible away. -- -- if (!cache->is_resolved((Bytecodes::Code)opcode)) { -- CALL_VM(InterpreterRuntime::resolve_invoke(THREAD, (Bytecodes::Code)opcode), -- handle_exception); -- cache = cp->entry_at(index); -- } -- -- istate->set_msg(call_method); -- { -- methodOop callee; -- if ((Bytecodes::Code)opcode == Bytecodes::_invokevirtual) { -- CHECK_NULL(STACK_OBJECT(-(cache->parameter_size()))); -- if (cache->is_vfinal()) callee = (methodOop) cache->f2(); -- else { -- // get receiver -- int parms = cache->parameter_size(); -- // this works but needs a resourcemark and seems to create a vtable on every call: -- // methodOop callee = rcvr->klass()->klass_part()->vtable()->method_at(cache->f2()); -- // -- // this fails with an assert -- // instanceKlass* rcvrKlass = instanceKlass::cast(STACK_OBJECT(-parms)->klass()); -- // but this works -- instanceKlass* rcvrKlass = (instanceKlass*) STACK_OBJECT(-parms)->klass()->klass_part(); -- /* -- Executing this code in java.lang.String: -- public String(char value[]) { -- this.count = value.length; -- this.value = (char[])value.clone(); -- } -- -- a find on rcvr->klass()->klass_part() reports: -- {type array char}{type array class} -- - klass: {other class} -- -- but using instanceKlass::cast(STACK_OBJECT(-parms)->klass()) causes in assertion failure -- because rcvr->klass()->klass_part()->oop_is_instance() == 0 -- However it seems to have a vtable in the right location. Huh? -- -- */ -- callee = (methodOop) rcvrKlass->start_of_vtable()[ cache->f2()]; -- } -- } else { -- if ((Bytecodes::Code)opcode == Bytecodes::_invokespecial) { -- CHECK_NULL(STACK_OBJECT(-(cache->parameter_size()))); -- } -- callee = (methodOop) cache->f1(); -- } -- -- istate->set_callee(callee); -- istate->set_callee_entry_point(callee->from_interpreted_entry()); --#ifdef VM_JVMTI -- if (JvmtiExport::can_post_interpreter_events() && THREAD->is_interp_only_mode()) { -- istate->set_callee_entry_point(callee->interpreter_entry()); -- } --#endif /* VM_JVMTI */ -- istate->set_bcp_advance(3); -- UPDATE_PC_AND_RETURN(0); // I'll be back... -- } -- } -- -- /* Allocate memory for a new java object. */ -- -- CASE(_newarray): { -- BasicType atype = (BasicType) *(pc+1); -- jint size = STACK_INT(-1); -- CALL_VM(InterpreterRuntime::newarray(THREAD, atype, size), -- handle_exception); -- SET_STACK_OBJECT(THREAD->vm_result(), -1); -- THREAD->set_vm_result(NULL); -- -- UPDATE_PC_AND_CONTINUE(2); -- } -- -- /* Throw an exception. */ -- -- CASE(_athrow): { -- oop except_oop = STACK_OBJECT(-1); -- CHECK_NULL(except_oop); -- // set pending_exception so we use common code -- THREAD->set_pending_exception(except_oop, NULL, 0); -- goto handle_exception; -- } -- -- /* goto and jsr. They are exactly the same except jsr pushes -- * the address of the next instruction first. -- */ -- -- CASE(_jsr): { -- /* push bytecode index on stack */ -- SET_STACK_SLOT(((address)pc - (intptr_t)(istate->method()->code_base()) + 3), 0); -- MORE_STACK(1); -- /* FALL THROUGH */ -- } -- -- CASE(_goto): -- { -- int16_t offset = (int16_t)Bytes::get_Java_u2(pc + 1); -- address branch_pc = pc; -- UPDATE_PC(offset); -- DO_BACKEDGE_CHECKS(offset, branch_pc); -- CONTINUE; -- } -- -- CASE(_jsr_w): { -- /* push return address on the stack */ -- SET_STACK_SLOT(((address)pc - (intptr_t)(istate->method()->code_base()) + 5), 0); -- MORE_STACK(1); -- /* FALL THROUGH */ -- } -- -- CASE(_goto_w): -- { -- int32_t offset = Bytes::get_Java_u4(pc + 1); -- address branch_pc = pc; -- UPDATE_PC(offset); -- DO_BACKEDGE_CHECKS(offset, branch_pc); -- CONTINUE; -- } -- -- /* return from a jsr or jsr_w */ -- -- CASE(_ret): { -- pc = istate->method()->code_base() + (intptr_t)(LOCALS_SLOT(pc[1])); -- UPDATE_PC_AND_CONTINUE(0); -- } -- -- /* debugger breakpoint */ -- -- CASE(_breakpoint): { -- Bytecodes::Code original_bytecode; -- DECACHE_STATE(); -- SET_LAST_JAVA_FRAME(); -- original_bytecode = InterpreterRuntime::get_original_bytecode_at(THREAD, -- istate->method(), pc); -- RESET_LAST_JAVA_FRAME(); -- CACHE_STATE(); -- if (THREAD->pending_exception()) goto handle_exception; -- CALL_VM(InterpreterRuntime::_breakpoint(THREAD, istate->method(), pc), -- handle_exception); -- -- opcode = (jubyte)original_bytecode; -- goto opcode_switch; -- } -- -- DEFAULT: -- fatal2("\t*** Unimplemented opcode: %d = %s\n", -- opcode, Bytecodes::name((Bytecodes::Code)opcode)); -- goto finish; -- -- } /* switch(opc) */ -- -- --#ifdef USELABELS -- check_for_exception: --#endif -- { -- if (!THREAD->has_pending_exception()) { -- CONTINUE; -- } -- /* We will be gcsafe soon, so flush our state. */ -- DECACHE_PC(); -- goto handle_exception; -- } -- do_continue: ; -- -- } /* while (1) interpreter loop */ -- -- -- // An exception exists in the thread state see whether this activation can handle it -- handle_exception: { -- -- HandleMarkCleaner __hmc(THREAD); -- Handle except_oop(THREAD, THREAD->pending_exception()); -- // Prevent any subsequent HandleMarkCleaner in the VM -- // from freeing the except_oop handle. -- HandleMark __hm(THREAD); -- -- THREAD->clear_pending_exception(); -- assert(except_oop(), "No exception to process"); -- intptr_t continuation_bci; -- // expression stack is emptied -- topOfStack = istate->stack_base() - Interpreter::stackElementWords(); -- CALL_VM(continuation_bci = (intptr_t)InterpreterRuntime::exception_handler_for_exception(THREAD, except_oop()), -- handle_exception); -- -- except_oop = (oop) THREAD->vm_result(); -- THREAD->set_vm_result(NULL); -- if (continuation_bci >= 0) { -- // Place exception on top of stack -- SET_STACK_OBJECT(except_oop(), 0); -- MORE_STACK(1); -- pc = istate->method()->code_base() + continuation_bci; -- if (TraceExceptions) { -- ttyLocker ttyl; -- ResourceMark rm; -- tty->print_cr("Exception <%s> (" INTPTR_FORMAT ")", except_oop->print_value_string(), except_oop()); -- tty->print_cr(" thrown in interpreter method <%s>", istate->method()->print_value_string()); -- tty->print_cr(" at bci %d, continuing at %d for thread " INTPTR_FORMAT, -- pc - (intptr_t)istate->method()->code_base(), -- continuation_bci, THREAD); -- } -- // for AbortVMOnException flag -- NOT_PRODUCT(Exceptions::debug_check_abort(except_oop)); -- goto run; -- } -- if (TraceExceptions) { -- ttyLocker ttyl; -- ResourceMark rm; -- tty->print_cr("Exception <%s> (" INTPTR_FORMAT ")", except_oop->print_value_string(), except_oop()); -- tty->print_cr(" thrown in interpreter method <%s>", istate->method()->print_value_string()); -- tty->print_cr(" at bci %d, unwinding for thread " INTPTR_FORMAT, -- pc - (intptr_t) istate->method()->code_base(), -- THREAD); -- } -- // for AbortVMOnException flag -- NOT_PRODUCT(Exceptions::debug_check_abort(except_oop)); -- // No handler in this activation, unwind and try again -- THREAD->set_pending_exception(except_oop(), NULL, 0); -- goto handle_return; -- } /* handle_exception: */ -- -- -- -- // Return from an interpreter invocation with the result of the interpretation -- // on the top of the Java Stack (or a pending exception) -- --handle_Pop_Frame: -- -- // We don't really do anything special here except we must be aware -- // that we can get here without ever locking the method (if sync). -- // Also we skip the notification of the exit. -- -- istate->set_msg(popping_frame); -- // Clear pending so while the pop is in process -- // we don't start another one if a call_vm is done. -- THREAD->clr_pop_frame_pending(); -- // Let interpreter (only) see the we're in the process of popping a frame -- THREAD->set_pop_frame_in_process(); -- --handle_return: -- { -- DECACHE_STATE(); -- -- bool suppress_error = istate->msg() == popping_frame; -- bool suppress_exit_event = THREAD->has_pending_exception() || suppress_error; -- Handle original_exception(THREAD, THREAD->pending_exception()); -- Handle illegal_state_oop(THREAD, NULL); -- -- // We'd like a HandleMark here to prevent any subsequent HandleMarkCleaner -- // in any following VM entries from freeing our live handles, but illegal_state_oop -- // isn't really allocated yet and so doesn't become live until later and -- // in unpredicatable places. Instead we must protect the places where we enter the -- // VM. It would be much simpler (and safer) if we could allocate a real handle with -- // a NULL oop in it and then overwrite the oop later as needed. This isn't -- // unfortunately isn't possible. -- -- THREAD->clear_pending_exception(); -- -- // -- // As far as we are concerned we have returned. If we have a pending exception -- // that will be returned as this invocation's result. However if we get any -- // exception(s) while checking monitor state one of those IllegalMonitorStateExceptions -- // will be our final result (i.e. monitor exception trumps a pending exception). -- // -- -- // If we never locked the method (or really passed the point where we would have), -- // there is no need to unlock it (or look for other monitors), since that -- // could not have happened. -- -- if (!THREAD->do_not_unlock()) { -- // At this point we consider that we have returned. We now check that the -- // locks were properly block structured. If we find that they were not -- // used properly we will return with an illegal monitor exception. -- // The exception is checked by the caller not the callee since this -- // checking is considered to be part of the invocation and therefore -- // in the callers scope (JVM spec 8.13). -- // -- // Another weird thing to watch for is if the method was locked -- // recursively and then not exited properly. This means we must -- // examine all the entries in reverse time(and stack) order and -- // unlock as we find them. If we find the method monitor before -- // we are at the initial entry then we should throw an exception. -- // It is not clear the template based interpreter does this -- // correctly -- -- BasicObjectLock* base = istate->monitor_base(); -- BasicObjectLock* end = (BasicObjectLock*) istate->stack_base(); -- bool method_unlock_needed = istate->method()->is_synchronized(); -- // We know the initial monitor was used for the method don't check that -- // slot in the loop -- if (method_unlock_needed) base--; -- -- // Check all the monitors to see they are unlocked. Install exception if found to be locked. -- while (end < base) { -- oop lockee = end->obj(); -- if (lockee != NULL) { -- BasicLock* lock = end->lock(); -- markOop header = lock->displaced_header(); -- end->set_obj(NULL); -- // If it isn't recursive we either must swap old header or call the runtime -- if (header != NULL) { -- if (Atomic::cmpxchg_ptr(header, lockee->mark_addr(), lock) != lock) { -- // restore object for the slow case -- end->set_obj(lockee); -- { -- // Prevent any HandleMarkCleaner from freeing our live handles -- HandleMark __hm(THREAD); -- CALL_VM_NOCHECK(InterpreterRuntime::monitorexit(THREAD, end)); -- } -- } -- } -- // One error is plenty -- if (illegal_state_oop() == NULL && !suppress_error) { -- { -- // Prevent any HandleMarkCleaner from freeing our live handles -- HandleMark __hm(THREAD); -- CALL_VM_NOCHECK(InterpreterRuntime::throw_illegal_monitor_state_exception(THREAD)); -- } -- assert(THREAD->has_pending_exception(), "Lost our exception!"); -- illegal_state_oop = THREAD->pending_exception(); -- THREAD->clear_pending_exception(); -- } -- } -- end++; -- } -- // Unlock the method if needed -- if (method_unlock_needed) { -- if (base->obj() == NULL) { -- // The method is already unlocked this is not good. -- if (illegal_state_oop() == NULL && !suppress_error) { -- { -- // Prevent any HandleMarkCleaner from freeing our live handles -- HandleMark __hm(THREAD); -- CALL_VM_NOCHECK(InterpreterRuntime::throw_illegal_monitor_state_exception(THREAD)); -- } -- assert(THREAD->has_pending_exception(), "Lost our exception!"); -- illegal_state_oop = THREAD->pending_exception(); -- THREAD->clear_pending_exception(); -- } -- } else { -- // -- // The initial monitor is always used for the method -- // However if that slot is no longer the oop for the method it was unlocked -- // and reused by something that wasn't unlocked! -- // -- // deopt can come in with rcvr dead because c2 knows -- // its value is preserved in the monitor. So we can't use locals[0] at all -- // and must use first monitor slot. -- // -- oop rcvr = base->obj(); -- if (rcvr == NULL) { -- if (!suppress_error) { -- VM_JAVA_ERROR_NO_JUMP(vmSymbols::java_lang_NullPointerException(), ""); -- illegal_state_oop = THREAD->pending_exception(); -- THREAD->clear_pending_exception(); -- } -- } else { -- BasicLock* lock = base->lock(); -- markOop header = lock->displaced_header(); -- base->set_obj(NULL); -- // If it isn't recursive we either must swap old header or call the runtime -- if (header != NULL) { -- if (Atomic::cmpxchg_ptr(header, rcvr->mark_addr(), lock) != lock) { -- // restore object for the slow case -- base->set_obj(rcvr); -- { -- // Prevent any HandleMarkCleaner from freeing our live handles -- HandleMark __hm(THREAD); -- CALL_VM_NOCHECK(InterpreterRuntime::monitorexit(THREAD, base)); -- } -- if (THREAD->has_pending_exception()) { -- if (!suppress_error) illegal_state_oop = THREAD->pending_exception(); -- THREAD->clear_pending_exception(); -- } -- } -- } -- } -- } -- } -- } -- -- // -- // Notify jvmti -- // -- // NOTE: we do not notify a method_exit if we have a pending exception, -- // including an exception we generate for unlocking checks. In the former -- // case, JVMDI has already been notified by our call for the exception handler -- // and in both cases as far as JVMDI is concerned we have already returned. -- // If we notify it again JVMDI will be all confused about how many frames -- // are still on the stack (4340444). -- // -- // -- // NOTE Further! It turns out the the JVMTI spec in fact expects to see -- // method_exit events whenever we leave an activation unless it was done -- // for popframe. This is nothing like jvmdi. However -- // we are passing the tests at the moment (apparently becuase they are -- // jvmdi based) so rather than change this code and possibly fail tests -- // we will leave it alone (with this note) in anticipation of changing -- // the vm and the tests simultaneously. -- -- -- // -- suppress_exit_event = suppress_exit_event || illegal_state_oop() != NULL; -- -- -- --#ifdef VM_JVMTI -- if (_jvmti_interp_events) { -- // Whenever JVMTI puts a thread in interp_only_mode, method -- // entry/exit events are sent for that thread to track stack depth. -- if ( !suppress_exit_event && THREAD->is_interp_only_mode() ) { -- { -- // Prevent any HandleMarkCleaner from freeing our live handles -- HandleMark __hm(THREAD); -- CALL_VM_NOCHECK(InterpreterRuntime::post_method_exit(THREAD)); -- } -- } -- } --#endif /* VM_JVMTI */ -- -- // -- // See if we are returning any exception -- // A pending exception that was pending prior to a possible popping frame -- // overrides the popping frame. -- // -- assert(!suppress_error || suppress_error && illegal_state_oop() == NULL, "Error was not suppressed"); -- if (illegal_state_oop() != NULL || original_exception() != NULL) { -- // inform the frame manager we have no result -- istate->set_msg(throwing_exception); -- if (illegal_state_oop() != NULL) -- THREAD->set_pending_exception(illegal_state_oop(), NULL, 0); -- else -- THREAD->set_pending_exception(original_exception(), NULL, 0); -- istate->set_return_kind((Bytecodes::Code)opcode); -- UPDATE_PC_AND_RETURN(0); -- } -- -- if (istate->msg() == popping_frame) { -- // Make it simpler on the assembly code and set the message for the frame pop. -- // returns -- if (istate->prev() == NULL) { -- // We must be returning to a deoptimized frame (because popframe only happens between -- // two interpreted frames). We need to save the current arguments in C heap so that -- // the deoptimized frame when it restarts can copy the arguments to its expression -- // stack and re-execute the call. We also have to notify deoptimization that this -- // has occured and to pick the preerved args copy them to the deoptimized frame's -- // java expression stack. Yuck. -- // -- THREAD->popframe_preserve_args(in_ByteSize(istate->method()->size_of_parameters() * wordSize), -- LOCALS_SLOT(istate->method()->size_of_parameters() - 1)); -- THREAD->set_popframe_condition_bit(JavaThread::popframe_force_deopt_reexecution_bit); -- } -- UPDATE_PC_AND_RETURN(1); -- } else { -- // Normal return -- // Advance the pc and return to frame manager -- istate->set_msg(return_from_method); -- istate->set_return_kind((Bytecodes::Code)opcode); -- UPDATE_PC_AND_RETURN(1); -- } -- } /* handle_return: */ -- --// This is really a fatal error return -- --finish: -- DECACHE_TOS(); -- DECACHE_PC(); -- -- return; --} -- --#endif // CC_INTERP -- -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/cInterpreter.cpp openjdk/hotspot/src/share/vm/interpreter/cInterpreter.cpp ---- openjdk6/hotspot/src/share/vm/interpreter/cInterpreter.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/interpreter/cInterpreter.cpp 1970-01-01 01:00:00.000000000 +0100 -@@ -1,359 +0,0 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)cInterpreter.cpp 1.30 07/05/17 15:54:05 JVM" --#endif --/* -- * Copyright 2002-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, -- * CA 95054 USA or visit www.sun.com if you need additional information or -- * have any questions. -- * -- */ -- --/* -- * Note: -- * In order to eliminate the overhead of testing JVMTI flags -- * during non debuging execution, we generate two version of the Interpreter. -- * The first one is generated via the dependency in the includeDB mechanism -- * and is read in as part of the _cInterpreter.cpp.incl line below. -- * -- * The second and JVMTI enabled interpreter is brought in below after -- * the line defining VM_JVMTI to 1. -- * -- * On startup, the assembly generated to enter the Interpreter will be -- * pointed at either InterpretMethod or InterpretMethodWithChecks depending -- * on the state of the JVMTI flags.. -- */ --#undef VM_JVMTI -- --#include "incls/_precompiled.incl" --#include "incls/_cInterpreter.cpp.incl" -- --#ifdef CC_INTERP -- -- --#define VM_JVMTI 1 -- --// Build the Interpreter that is used if JVMTI is enabled --#include "cInterpretMethod.hpp" -- --// This constructor should only be used to contruct the object to signal --// interpreter initialization. All other instances should be created by --// the frame manager. --cInterpreter::cInterpreter(messages msg) { -- if (msg != initialize) ShouldNotReachHere(); -- _msg = msg; -- _self_link = this; -- _prev_link = NULL; --} -- --// Dummy function so we can determine if a pc is within the interpreter. --// This is really a hack. Seems like adding state to thread ala last_Java_sp, etc. --// would be cleaner. --// --void cInterpreter::End_Of_Interpreter(void) { --} -- --// Inline static functions for Java Stack and Local manipulation -- --// The implementations are platform dependent. We have to worry about alignment --// issues on some machines which can change on the same platform depending on --// whether it is an LP64 machine also. --#ifdef ASSERT --void cInterpreter::verify_stack_tag(intptr_t *tos, frame::Tag tag, int offset) { -- if (TaggedStackInterpreter) { -- frame::Tag t = (frame::Tag)tos[Interpreter::expr_tag_index_at(-offset)]; -- assert(t == tag, "stack tag mismatch"); -- } --} --#endif // ASSERT -- --address cInterpreter::stack_slot(intptr_t *tos, int offset) { -- debug_only(verify_stack_tag(tos, frame::TagValue, offset)); -- return (address) tos[Interpreter::expr_index_at(-offset)]; --} -- --jint cInterpreter::stack_int(intptr_t *tos, int offset) { -- debug_only(verify_stack_tag(tos, frame::TagValue, offset)); -- return *((jint*) &tos[Interpreter::expr_index_at(-offset)]); --} -- --jfloat cInterpreter::stack_float(intptr_t *tos, int offset) { -- debug_only(verify_stack_tag(tos, frame::TagValue, offset)); -- return *((jfloat *) &tos[Interpreter::expr_index_at(-offset)]); --} -- --oop cInterpreter::stack_object(intptr_t *tos, int offset) { -- debug_only(verify_stack_tag(tos, frame::TagReference, offset)); -- return (oop)tos [Interpreter::expr_index_at(-offset)]; --} -- --jdouble cInterpreter::stack_double(intptr_t *tos, int offset) { -- debug_only(verify_stack_tag(tos, frame::TagValue, offset)); -- debug_only(verify_stack_tag(tos, frame::TagValue, offset-1)); -- return ((VMJavaVal64*) &tos[Interpreter::expr_index_at(-offset)])->d; --} -- --jlong cInterpreter::stack_long(intptr_t *tos, int offset) { -- debug_only(verify_stack_tag(tos, frame::TagValue, offset)); -- debug_only(verify_stack_tag(tos, frame::TagValue, offset-1)); -- return ((VMJavaVal64 *) &tos[Interpreter::expr_index_at(-offset)])->l; --} -- --void cInterpreter::tag_stack(intptr_t *tos, frame::Tag tag, int offset) { -- if (TaggedStackInterpreter) -- tos[Interpreter::expr_tag_index_at(-offset)] = (intptr_t)tag; --} -- --// only used for value types --void cInterpreter::set_stack_slot(intptr_t *tos, address value, -- int offset) { -- tag_stack(tos, frame::TagValue, offset); -- *((address *)&tos[Interpreter::expr_index_at(-offset)]) = value; --} -- --void cInterpreter::set_stack_int(intptr_t *tos, int value, -- int offset) { -- tag_stack(tos, frame::TagValue, offset); -- *((jint *)&tos[Interpreter::expr_index_at(-offset)]) = value; --} -- --void cInterpreter::set_stack_float(intptr_t *tos, jfloat value, -- int offset) { -- tag_stack(tos, frame::TagValue, offset); -- *((jfloat *)&tos[Interpreter::expr_index_at(-offset)]) = value; --} -- --void cInterpreter::set_stack_object(intptr_t *tos, oop value, -- int offset) { -- tag_stack(tos, frame::TagReference, offset); -- *((oop *)&tos[Interpreter::expr_index_at(-offset)]) = value; --} -- --// needs to be platform dep for the 32 bit platforms. --void cInterpreter::set_stack_double(intptr_t *tos, jdouble value, -- int offset) { -- tag_stack(tos, frame::TagValue, offset); -- tag_stack(tos, frame::TagValue, offset-1); -- ((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset)])->d = value; --} -- --void cInterpreter::set_stack_double_from_addr(intptr_t *tos, -- address addr, int offset) { -- tag_stack(tos, frame::TagValue, offset); -- tag_stack(tos, frame::TagValue, offset-1); -- (((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset)])->d = -- ((VMJavaVal64*)addr)->d); --} -- --void cInterpreter::set_stack_long(intptr_t *tos, jlong value, -- int offset) { -- tag_stack(tos, frame::TagValue, offset); -- ((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset+1)])->l = 0xdeedbeeb; -- tag_stack(tos, frame::TagValue, offset-1); -- ((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset)])->l = value; --} -- --void cInterpreter::set_stack_long_from_addr(intptr_t *tos, -- address addr, int offset) { -- tag_stack(tos, frame::TagValue, offset); -- ((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset+1)])->l = 0xdeedbeeb; -- tag_stack(tos, frame::TagValue, offset-1); -- ((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset)])->l = -- ((VMJavaVal64*)addr)->l; --} -- --// Locals -- --#ifdef ASSERT --void cInterpreter::verify_locals_tag(intptr_t *locals, frame::Tag tag, -- int offset) { -- if (TaggedStackInterpreter) { -- frame::Tag t = (frame::Tag)locals[Interpreter::local_tag_index_at(-offset)]; -- assert(t == tag, "locals tag mismatch"); -- } --} --#endif // ASSERT --address cInterpreter::locals_slot(intptr_t* locals, int offset) { -- debug_only(verify_locals_tag(locals, frame::TagValue, offset)); -- return (address)locals[Interpreter::local_index_at(-offset)]; --} --jint cInterpreter::locals_int(intptr_t* locals, int offset) { -- debug_only(verify_locals_tag(locals, frame::TagValue, offset)); -- return (jint)locals[Interpreter::local_index_at(-offset)]; --} --jfloat cInterpreter::locals_float(intptr_t* locals, int offset) { -- debug_only(verify_locals_tag(locals, frame::TagValue, offset)); -- return (jfloat)locals[Interpreter::local_index_at(-offset)]; --} --oop cInterpreter::locals_object(intptr_t* locals, int offset) { -- debug_only(verify_locals_tag(locals, frame::TagReference, offset)); -- return (oop)locals[Interpreter::local_index_at(-offset)]; --} --jdouble cInterpreter::locals_double(intptr_t* locals, int offset) { -- debug_only(verify_locals_tag(locals, frame::TagValue, offset)); -- debug_only(verify_locals_tag(locals, frame::TagValue, offset)); -- return ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->d; --} --jlong cInterpreter::locals_long(intptr_t* locals, int offset) { -- debug_only(verify_locals_tag(locals, frame::TagValue, offset)); -- debug_only(verify_locals_tag(locals, frame::TagValue, offset+1)); -- return ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->l; --} -- --// Returns the address of locals value. --address cInterpreter::locals_long_at(intptr_t* locals, int offset) { -- debug_only(verify_locals_tag(locals, frame::TagValue, offset)); -- debug_only(verify_locals_tag(locals, frame::TagValue, offset+1)); -- return ((address)&locals[Interpreter::local_index_at(-(offset+1))]); --} --address cInterpreter::locals_double_at(intptr_t* locals, int offset) { -- debug_only(verify_locals_tag(locals, frame::TagValue, offset)); -- debug_only(verify_locals_tag(locals, frame::TagValue, offset+1)); -- return ((address)&locals[Interpreter::local_index_at(-(offset+1))]); --} -- --void cInterpreter::tag_locals(intptr_t *locals, frame::Tag tag, int offset) { -- if (TaggedStackInterpreter) -- locals[Interpreter::local_tag_index_at(-offset)] = (intptr_t)tag; --} -- --// Used for local value or returnAddress --void cInterpreter::set_locals_slot(intptr_t *locals, -- address value, int offset) { -- tag_locals(locals, frame::TagValue, offset); -- *((address*)&locals[Interpreter::local_index_at(-offset)]) = value; --} --void cInterpreter::set_locals_int(intptr_t *locals, -- jint value, int offset) { -- tag_locals(locals, frame::TagValue, offset); -- *((jint *)&locals[Interpreter::local_index_at(-offset)]) = value; --} --void cInterpreter::set_locals_float(intptr_t *locals, -- jfloat value, int offset) { -- tag_locals(locals, frame::TagValue, offset); -- *((jfloat *)&locals[Interpreter::local_index_at(-offset)]) = value; --} --void cInterpreter::set_locals_object(intptr_t *locals, -- oop value, int offset) { -- tag_locals(locals, frame::TagReference, offset); -- *((oop *)&locals[Interpreter::local_index_at(-offset)]) = value; --} --void cInterpreter::set_locals_double(intptr_t *locals, -- jdouble value, int offset) { -- tag_locals(locals, frame::TagValue, offset); -- tag_locals(locals, frame::TagValue, offset+1); -- ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->d = value; --} --void cInterpreter::set_locals_long(intptr_t *locals, -- jlong value, int offset) { -- tag_locals(locals, frame::TagValue, offset); -- tag_locals(locals, frame::TagValue, offset+1); -- ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->l = value; --} --void cInterpreter::set_locals_double_from_addr(intptr_t *locals, -- address addr, int offset) { -- tag_locals(locals, frame::TagValue, offset); -- tag_locals(locals, frame::TagValue, offset+1); -- ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->d = ((VMJavaVal64*)addr)->d; --} --void cInterpreter::set_locals_long_from_addr(intptr_t *locals, -- address addr, int offset) { -- tag_locals(locals, frame::TagValue, offset); -- tag_locals(locals, frame::TagValue, offset+1); -- ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->l = ((VMJavaVal64*)addr)->l; --} -- --void cInterpreter::astore(intptr_t* tos, int stack_offset, -- intptr_t* locals, int locals_offset) { -- // Copy tag from stack to locals. astore's operand can be returnAddress -- // and may not be TagReference -- if (TaggedStackInterpreter) { -- frame::Tag t = (frame::Tag) tos[Interpreter::expr_tag_index_at(-stack_offset)]; -- locals[Interpreter::local_tag_index_at(-locals_offset)] = (intptr_t)t; -- } -- intptr_t value = tos[Interpreter::expr_index_at(-stack_offset)]; -- locals[Interpreter::local_index_at(-locals_offset)] = value; --} -- -- --void cInterpreter::copy_stack_slot(intptr_t *tos, int from_offset, -- int to_offset) { -- if (TaggedStackInterpreter) { -- tos[Interpreter::expr_tag_index_at(-to_offset)] = -- (intptr_t)tos[Interpreter::expr_tag_index_at(-from_offset)]; -- } -- tos[Interpreter::expr_index_at(-to_offset)] = -- (intptr_t)tos[Interpreter::expr_index_at(-from_offset)]; --} -- --void cInterpreter::dup(intptr_t *tos) { -- copy_stack_slot(tos, -1, 0); --} --void cInterpreter::dup2(intptr_t *tos) { -- copy_stack_slot(tos, -2, 0); -- copy_stack_slot(tos, -1, 1); --} -- --void cInterpreter::dup_x1(intptr_t *tos) { -- /* insert top word two down */ -- copy_stack_slot(tos, -1, 0); -- copy_stack_slot(tos, -2, -1); -- copy_stack_slot(tos, 0, -2); --} -- --void cInterpreter::dup_x2(intptr_t *tos) { -- /* insert top word three down */ -- copy_stack_slot(tos, -1, 0); -- copy_stack_slot(tos, -2, -1); -- copy_stack_slot(tos, -3, -2); -- copy_stack_slot(tos, 0, -3); --} --void cInterpreter::dup2_x1(intptr_t *tos) { -- /* insert top 2 slots three down */ -- copy_stack_slot(tos, -1, 1); -- copy_stack_slot(tos, -2, 0); -- copy_stack_slot(tos, -3, -1); -- copy_stack_slot(tos, 1, -2); -- copy_stack_slot(tos, 0, -3); --} --void cInterpreter::dup2_x2(intptr_t *tos) { -- /* insert top 2 slots four down */ -- copy_stack_slot(tos, -1, 1); -- copy_stack_slot(tos, -2, 0); -- copy_stack_slot(tos, -3, -1); -- copy_stack_slot(tos, -4, -2); -- copy_stack_slot(tos, 1, -3); -- copy_stack_slot(tos, 0, -4); --} -- -- --void cInterpreter::swap(intptr_t *tos) { -- // swap top two elements -- intptr_t val = tos[Interpreter::expr_index_at(1)]; -- frame::Tag t; -- if (TaggedStackInterpreter) { -- t = (frame::Tag) tos[Interpreter::expr_tag_index_at(1)]; -- } -- // Copy -2 entry to -1 -- copy_stack_slot(tos, -2, -1); -- // Store saved -1 entry into -2 -- tos[Interpreter::expr_tag_index_at(2)] = (intptr_t)t; -- tos[Interpreter::expr_index_at(2)] = val; --} --#endif -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/cInterpreter.hpp openjdk/hotspot/src/share/vm/interpreter/cInterpreter.hpp ---- openjdk6/hotspot/src/share/vm/interpreter/cInterpreter.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/interpreter/cInterpreter.hpp 1970-01-01 01:00:00.000000000 +0100 -@@ -1,565 +0,0 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)cInterpreter.hpp 1.23 07/05/17 15:54:24 JVM" --#endif --/* -- * Copyright 2002-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, -- * CA 95054 USA or visit www.sun.com if you need additional information or -- * have any questions. -- * -- */ -- --#ifdef CC_INTERP -- --// CVM definitions find hotspot equivalents... -- --union VMJavaVal64 { -- jlong l; -- jdouble d; -- uint32_t v[2]; --}; -- -- --typedef class cInterpreter* interpreterState; -- --struct call_message { -- methodOop _callee; /* method to call during call_method request */ -- address _callee_entry_point; /* address to jump to for call_method request */ -- int _bcp_advance; /* size of the invoke bytecode operation */ --}; -- --struct osr_message { -- address _osr_buf; /* the osr buffer */ -- address _osr_entry; /* the entry to the osr method */ --}; -- --// Result returned to frame manager --union frame_manager_message { -- call_message _to_call; /* describes callee */ -- Bytecodes::Code _return_kind; /* i_return, a_return, ... */ -- osr_message _osr; /* describes the osr */ --}; -- --class cInterpreter : StackObj { --friend class AbstractInterpreterGenerator; --friend class InterpreterGenerator; --friend class InterpreterMacroAssembler; --friend class frame; --friend class VMStructs; -- --public: -- enum messages { -- no_request = 0, // unused -- initialize, // Perform one time interpreter initializations (assumes all switches set) -- // status message to C++ interpreter -- method_entry, // initial method entry to interpreter -- method_resume, // frame manager response to return_from_method request (assuming a frame to resume) -- deopt_resume, // returning from a native call into a deopted frame -- deopt_resume2, // deopt resume as a result of a PopFrame -- got_monitors, // frame manager response to more_monitors request -- rethrow_exception, // unwinding and throwing exception -- // requests to frame manager from C++ interpreter -- call_method, // request for new frame from interpreter, manager responds with method_entry -- do_osr, // osr the current method -- return_from_method, // request from interpreter to unwind, manager responds with method_continue -- more_monitors, // need a new monitor -- throwing_exception, // unwind stack and rethrow -- popping_frame // unwind call and retry call -- }; -- --private: -- JavaThread* _thread; // the vm's java thread pointer -- address _bcp; // instruction pointer -- intptr_t* _locals; // local variable pointer -- constantPoolCacheOop _constants; // constant pool cache -- methodOop _method; // method being executed -- DataLayout* _mdx; // compiler profiling data for current bytecode -- intptr_t* _stack; // expression stack -- messages _msg; // frame manager <-> interpreter message -- frame_manager_message _result; // result to frame manager -- interpreterState _prev_link; // previous interpreter state -- oop _oop_temp; // mirror for interpreted native, null otherwise -- // These are likely platform dependent fields -- // jint* sender_sp; // previous stack pointer -- intptr_t* _stack_base; // base of expression stack -- intptr_t* _stack_limit; // limit of expression stack -- BasicObjectLock* _monitor_base; // base of monitors on the native stack -- -- --public: -- // Constructor is only used by the initialization step. All other instances are created -- // by the frame manager. -- cInterpreter(messages msg); -- --// --// Deoptimization support --// --static void layout_interpreterState(interpreterState to_fill, -- frame* caller, -- frame* interpreter_frame, -- methodOop method, -- intptr_t* locals, -- intptr_t* stack, -- intptr_t* stack_base, -- intptr_t* monitor_base, -- intptr_t* frame_bottom, -- bool top_frame); -- --/* -- * Generic 32-bit wide "Java slot" definition. This type occurs -- * in operand stacks, Java locals, object fields, constant pools. -- */ --union VMJavaVal32 { -- jint i; -- jfloat f; -- oop r; -- uint32_t raw; --}; -- --/* -- * Generic 64-bit Java value definition -- */ --union VMJavaVal64 { -- jlong l; -- jdouble d; -- uint32_t v[2]; --}; -- --/* -- * Generic 32-bit wide "Java slot" definition. This type occurs -- * in Java locals, object fields, constant pools, and -- * operand stacks (as a CVMStackVal32). -- */ --typedef union VMSlotVal32 { -- VMJavaVal32 j; /* For "Java" values */ -- address a; /* a return created by jsr or jsr_w */ --} VMSlotVal32; -- -- --/* -- * Generic 32-bit wide stack slot definition. -- */ --union VMStackVal32 { -- VMJavaVal32 j; /* For "Java" values */ -- VMSlotVal32 s; /* any value from a "slot" or locals[] */ --}; -- --inline JavaThread* thread() { return _thread; } -- --inline address bcp() { return _bcp; } --inline void set_bcp(address new_bcp) { _bcp = new_bcp; } -- --inline intptr_t* locals() { return _locals; } -- --inline constantPoolCacheOop constants() { return _constants; } --inline methodOop method() { return _method; } --inline DataLayout* mdx() { return _mdx; } -- --inline messages msg() { return _msg; } --inline void set_msg(messages new_msg) { _msg = new_msg; } -- --inline methodOop callee() { return _result._to_call._callee; } --inline void set_callee(methodOop new_callee) { _result._to_call._callee = new_callee; } --inline void set_callee_entry_point(address entry) { _result._to_call._callee_entry_point = entry; } --inline void set_osr_buf(address buf) { _result._osr._osr_buf = buf; } --inline void set_osr_entry(address entry) { _result._osr._osr_entry = entry; } --inline int bcp_advance() { return _result._to_call._bcp_advance; } --inline void set_bcp_advance(int count) { _result._to_call._bcp_advance = count; } -- --inline void set_return_kind(Bytecodes::Code kind) { _result._return_kind = kind; } -- --inline interpreterState prev() { return _prev_link; } -- --inline intptr_t* stack() { return _stack; } --inline void set_stack(intptr_t* new_stack) { _stack = new_stack; } -- -- --inline intptr_t* stack_base() { return _stack_base; } --inline intptr_t* stack_limit() { return _stack_limit; } -- --inline BasicObjectLock* monitor_base() { return _monitor_base; } -- --/* -- * 64-bit Arithmetic: -- * -- * The functions below follow the semantics of the -- * ladd, land, ldiv, lmul, lor, lxor, and lrem bytecodes, -- * respectively. -- */ -- --static jlong VMlongAdd(jlong op1, jlong op2); --static jlong VMlongAnd(jlong op1, jlong op2); --static jlong VMlongDiv(jlong op1, jlong op2); --static jlong VMlongMul(jlong op1, jlong op2); --static jlong VMlongOr (jlong op1, jlong op2); --static jlong VMlongSub(jlong op1, jlong op2); --static jlong VMlongXor(jlong op1, jlong op2); --static jlong VMlongRem(jlong op1, jlong op2); -- --/* -- * Shift: -- * -- * The functions below follow the semantics of the -- * lushr, lshl, and lshr bytecodes, respectively. -- */ -- --static jlong VMlongUshr(jlong op1, jint op2); --static jlong VMlongShl (jlong op1, jint op2); --static jlong VMlongShr (jlong op1, jint op2); -- --/* -- * Unary: -- * -- * Return the negation of "op" (-op), according to -- * the semantics of the lneg bytecode. -- */ -- --static jlong VMlongNeg(jlong op); -- --/* -- * Return the complement of "op" (~op) -- */ -- --static jlong VMlongNot(jlong op); -- -- --/* -- * Comparisons to 0: -- */ -- --static int32_t VMlongLtz(jlong op); /* op <= 0 */ --static int32_t VMlongGez(jlong op); /* op >= 0 */ --static int32_t VMlongEqz(jlong op); /* op == 0 */ -- --/* -- * Between operands: -- */ -- --static int32_t VMlongEq(jlong op1, jlong op2); /* op1 == op2 */ --static int32_t VMlongNe(jlong op1, jlong op2); /* op1 != op2 */ --static int32_t VMlongGe(jlong op1, jlong op2); /* op1 >= op2 */ --static int32_t VMlongLe(jlong op1, jlong op2); /* op1 <= op2 */ --static int32_t VMlongLt(jlong op1, jlong op2); /* op1 < op2 */ --static int32_t VMlongGt(jlong op1, jlong op2); /* op1 > op2 */ -- --/* -- * Comparisons (returning an jint value: 0, 1, or -1) -- * -- * Between operands: -- * -- * Compare "op1" and "op2" according to the semantics of the -- * "lcmp" bytecode. -- */ -- --static int32_t VMlongCompare(jlong op1, jlong op2); -- --/* -- * Convert int to long, according to "i2l" bytecode semantics -- */ --static jlong VMint2Long(jint val); -- --/* -- * Convert long to int, according to "l2i" bytecode semantics -- */ --static jint VMlong2Int(jlong val); -- --/* -- * Convert long to float, according to "l2f" bytecode semantics -- */ --static jfloat VMlong2Float(jlong val); -- --/* -- * Convert long to double, according to "l2d" bytecode semantics -- */ --static jdouble VMlong2Double(jlong val); -- --/* -- * Java floating-point float value manipulation. -- * -- * The result argument is, once again, an lvalue. -- * -- * Arithmetic: -- * -- * The functions below follow the semantics of the -- * fadd, fsub, fmul, fdiv, and frem bytecodes, -- * respectively. -- */ -- --static jfloat VMfloatAdd(jfloat op1, jfloat op2); --static jfloat VMfloatSub(jfloat op1, jfloat op2); --static jfloat VMfloatMul(jfloat op1, jfloat op2); --static jfloat VMfloatDiv(jfloat op1, jfloat op2); --static jfloat VMfloatRem(jfloat op1, jfloat op2); -- --/* -- * Unary: -- * -- * Return the negation of "op" (-op), according to -- * the semantics of the fneg bytecode. -- */ -- --static jfloat VMfloatNeg(jfloat op); -- --/* -- * Comparisons (returning an int value: 0, 1, or -1) -- * -- * Between operands: -- * -- * Compare "op1" and "op2" according to the semantics of the -- * "fcmpl" (direction is -1) or "fcmpg" (direction is 1) bytecodes. -- */ -- --static int32_t VMfloatCompare(jfloat op1, jfloat op2, -- int32_t direction); --/* -- * Conversion: -- */ -- --/* -- * Convert float to double, according to "f2d" bytecode semantics -- */ -- --static jdouble VMfloat2Double(jfloat op); -- --/* -- ****************************************** -- * Java double floating-point manipulation. -- ****************************************** -- * -- * The result argument is, once again, an lvalue. -- * -- * Conversions: -- */ -- --/* -- * Convert double to int, according to "d2i" bytecode semantics -- */ -- --static jint VMdouble2Int(jdouble val); -- --/* -- * Convert double to float, according to "d2f" bytecode semantics -- */ -- --static jfloat VMdouble2Float(jdouble val); -- --/* -- * Convert int to double, according to "i2d" bytecode semantics -- */ -- --static jdouble VMint2Double(jint val); -- --/* -- * Arithmetic: -- * -- * The functions below follow the semantics of the -- * dadd, dsub, ddiv, dmul, and drem bytecodes, respectively. -- */ -- --static jdouble VMdoubleAdd(jdouble op1, jdouble op2); --static jdouble VMdoubleSub(jdouble op1, jdouble op2); --static jdouble VMdoubleDiv(jdouble op1, jdouble op2); --static jdouble VMdoubleMul(jdouble op1, jdouble op2); --static jdouble VMdoubleRem(jdouble op1, jdouble op2); -- --/* -- * Unary: -- * -- * Return the negation of "op" (-op), according to -- * the semantics of the dneg bytecode. -- */ -- --static jdouble VMdoubleNeg(jdouble op); -- --/* -- * Comparisons (returning an int32_t value: 0, 1, or -1) -- * -- * Between operands: -- * -- * Compare "op1" and "op2" according to the semantics of the -- * "dcmpl" (direction is -1) or "dcmpg" (direction is 1) bytecodes. -- */ -- --static int32_t VMdoubleCompare(jdouble op1, jdouble op2, int32_t direction); -- --/* -- * Copy two typeless 32-bit words from one location to another. -- * This is semantically equivalent to: -- * -- * to[0] = from[0]; -- * to[1] = from[1]; -- * -- * but this interface is provided for those platforms that could -- * optimize this into a single 64-bit transfer. -- */ -- --static void VMmemCopy64(uint32_t to[2], const uint32_t from[2]); -- -- --// Arithmetic operations -- --/* -- * Java arithmetic methods. -- * The functions below follow the semantics of the -- * iadd, isub, imul, idiv, irem, iand, ior, ixor, -- * and ineg bytecodes, respectively. -- */ -- --static jint VMintAdd(jint op1, jint op2); --static jint VMintSub(jint op1, jint op2); --static jint VMintMul(jint op1, jint op2); --static jint VMintDiv(jint op1, jint op2); --static jint VMintRem(jint op1, jint op2); --static jint VMintAnd(jint op1, jint op2); --static jint VMintOr (jint op1, jint op2); --static jint VMintXor(jint op1, jint op2); -- --/* -- * Shift Operation: -- * The functions below follow the semantics of the -- * iushr, ishl, and ishr bytecodes, respectively. -- */ -- --static jint VMintUshr(jint op, jint num); --static jint VMintShl (jint op, jint num); --static jint VMintShr (jint op, jint num); -- --/* -- * Unary Operation: -- * -- * Return the negation of "op" (-op), according to -- * the semantics of the ineg bytecode. -- */ -- --static jint VMintNeg(jint op); -- --/* -- * Int Conversions: -- */ -- --/* -- * Convert int to float, according to "i2f" bytecode semantics -- */ -- --static jfloat VMint2Float(jint val); -- --/* -- * Convert int to byte, according to "i2b" bytecode semantics -- */ -- --static jbyte VMint2Byte(jint val); -- --/* -- * Convert int to char, according to "i2c" bytecode semantics -- */ -- --static jchar VMint2Char(jint val); -- --/* -- * Convert int to short, according to "i2s" bytecode semantics -- */ -- --static jshort VMint2Short(jint val); -- --/*========================================================================= -- * Bytecode interpreter operations -- *=======================================================================*/ -- --static void dup(intptr_t *tos); --static void dup2(intptr_t *tos); --static void dup_x1(intptr_t *tos); /* insert top word two down */ --static void dup_x2(intptr_t *tos); /* insert top word three down */ --static void dup2_x1(intptr_t *tos); /* insert top 2 slots three down */ --static void dup2_x2(intptr_t *tos); /* insert top 2 slots four down */ --static void swap(intptr_t *tos); /* swap top two elements */ -- --// umm don't like this method modifies its object -- --// The Interpreter used when --static void InterpretMethod(interpreterState istate); --// The interpreter used if JVMTI needs interpreter events --static void InterpretMethodWithChecks(interpreterState istate); --static void End_Of_Interpreter(void); -- --// Inline static functions for Java Stack and Local manipulation -- --static address stack_slot(intptr_t *tos, int offset); --static jint stack_int(intptr_t *tos, int offset); --static jfloat stack_float(intptr_t *tos, int offset); --static oop stack_object(intptr_t *tos, int offset); --static jdouble stack_double(intptr_t *tos, int offset); --static jlong stack_long(intptr_t *tos, int offset); -- --static void tag_stack(intptr_t *tos, frame::Tag tag, int offset); -- --// only used for value types --static void set_stack_slot(intptr_t *tos, address value, int offset); --static void set_stack_int(intptr_t *tos, int value, int offset); --static void set_stack_float(intptr_t *tos, jfloat value, int offset); --static void set_stack_object(intptr_t *tos, oop value, int offset); -- --// needs to be platform dep for the 32 bit platforms. --static void set_stack_double(intptr_t *tos, jdouble value, int offset); --static void set_stack_long(intptr_t *tos, jlong value, int offset); -- --static void set_stack_double_from_addr(intptr_t *tos, address addr, int offset); --static void set_stack_long_from_addr(intptr_t *tos, address addr, int offset); -- --// Locals -- --static address locals_slot(intptr_t* locals, int offset); --static jint locals_int(intptr_t* locals, int offset); --static jfloat locals_float(intptr_t* locals, int offset); --static oop locals_object(intptr_t* locals, int offset); --static jdouble locals_double(intptr_t* locals, int offset); --static jlong locals_long(intptr_t* locals, int offset); -- --static address locals_long_at(intptr_t* locals, int offset); --static address locals_double_at(intptr_t* locals, int offset); -- --static void tag_locals(intptr_t *locals, frame::Tag tag, int offset); -- --static void set_locals_slot(intptr_t *locals, address value, int offset); --static void set_locals_int(intptr_t *locals, jint value, int offset); --static void set_locals_float(intptr_t *locals, jfloat value, int offset); --static void set_locals_object(intptr_t *locals, oop value, int offset); --static void set_locals_double(intptr_t *locals, jdouble value, int offset); --static void set_locals_long(intptr_t *locals, jlong value, int offset); --static void set_locals_double_from_addr(intptr_t *locals, -- address addr, int offset); --static void set_locals_long_from_addr(intptr_t *locals, -- address addr, int offset); -- --static void astore(intptr_t* topOfStack, int stack_offset, -- intptr_t* locals, int locals_offset); -- --// Support for dup and swap --static void copy_stack_slot(intptr_t *tos, int from_offset, int to_offset); -- --#ifndef PRODUCT --static void verify_locals_tag(intptr_t *locals, frame::Tag tag, int offset); --static void verify_stack_tag(intptr_t *tos, frame::Tag tag, int offset); --#endif // PRODUCT -- -- // Platform fields/methods --# include "incls/_cInterpreter_pd.hpp.incl" -- --}; // cInterpreter -- --#endif // CC_INTERP -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/cInterpreter.inline.hpp openjdk/hotspot/src/share/vm/interpreter/cInterpreter.inline.hpp ---- openjdk6/hotspot/src/share/vm/interpreter/cInterpreter.inline.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/interpreter/cInterpreter.inline.hpp 1970-01-01 01:00:00.000000000 +0100 -@@ -1,47 +0,0 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)cInterpreter.inline.hpp 1.9 07/05/05 17:05:37 JVM" --#endif --/* -- * Copyright 2002 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, -- * CA 95054 USA or visit www.sun.com if you need additional information or -- * have any questions. -- * -- */ -- --// This file holds platform-independant bodies of inline functions for the C++ based interpreter -- --#ifdef CC_INTERP -- --#ifdef ASSERT --extern "C" { typedef void (*verify_oop_fn_t)(oop, const char *);}; --#define VERIFY_OOP(o) \ -- /*{ verify_oop_fn_t verify_oop_entry = \ -- *StubRoutines::verify_oop_subroutine_entry_address(); \ -- if (verify_oop_entry) { \ -- (*verify_oop_entry)((o), "Not an oop!"); \ -- } \ -- }*/ --#else --#define VERIFY_OOP(o) --#endif -- --// Platform dependent data manipulation --# include "incls/_cInterpreter_pd.inline.hpp.incl" --#endif // CC_INTERP -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/cppInterpreter.cpp openjdk/hotspot/src/share/vm/interpreter/cppInterpreter.cpp ---- openjdk6/hotspot/src/share/vm/interpreter/cppInterpreter.cpp 1970-01-01 01:00:00.000000000 +0100 -+++ openjdk/hotspot/src/share/vm/interpreter/cppInterpreter.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -0,0 +1,135 @@ -+/* -+ * Copyright 1997-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, -+ * CA 95054 USA or visit www.sun.com if you need additional information or -+ * have any questions. -+ * -+ */ -+ -+#include "incls/_precompiled.incl" -+#include "incls/_cppInterpreter.cpp.incl" -+ -+#ifdef CC_INTERP -+# define __ _masm-> -+ -+void CppInterpreter::initialize() { -+ if (_code != NULL) return; -+ AbstractInterpreter::initialize(); -+ -+ // generate interpreter -+ { ResourceMark rm; -+ TraceTime timer("Interpreter generation", TraceStartupTime); -+ int code_size = InterpreterCodeSize; -+ NOT_PRODUCT(code_size *= 4;) // debug uses extra interpreter code space -+ _code = new StubQueue(new InterpreterCodeletInterface, code_size, NULL, -+ "Interpreter"); -+ InterpreterGenerator g(_code); -+ if (PrintInterpreter) print(); -+ } -+ -+ -+ // Allow c++ interpreter to do one initialization now that switches are set, etc. -+ BytecodeInterpreter start_msg(BytecodeInterpreter::initialize); -+ if (JvmtiExport::can_post_interpreter_events()) -+ BytecodeInterpreter::runWithChecks(&start_msg); -+ else -+ BytecodeInterpreter::run(&start_msg); -+} -+ -+ -+address CppInterpreter::_tosca_to_stack [AbstractInterpreter::number_of_result_handlers]; -+address CppInterpreter::_stack_to_stack [AbstractInterpreter::number_of_result_handlers]; -+address CppInterpreter::_stack_to_native_abi [AbstractInterpreter::number_of_result_handlers]; -+ -+CppInterpreterGenerator::CppInterpreterGenerator(StubQueue* _code): AbstractInterpreterGenerator(_code) { -+} -+ -+static const BasicType types[Interpreter::number_of_result_handlers] = { -+ T_BOOLEAN, -+ T_CHAR , -+ T_BYTE , -+ T_SHORT , -+ T_INT , -+ T_LONG , -+ T_VOID , -+ T_FLOAT , -+ T_DOUBLE , -+ T_OBJECT -+}; -+ -+void CppInterpreterGenerator::generate_all() { -+ AbstractInterpreterGenerator::generate_all(); -+ -+ { CodeletMark cm(_masm, "result handlers for native calls"); -+ // The various result converter stublets. -+ int is_generated[Interpreter::number_of_result_handlers]; -+ memset(is_generated, 0, sizeof(is_generated)); -+ int _tosca_to_stack_is_generated[Interpreter::number_of_result_handlers]; -+ int _stack_to_stack_is_generated[Interpreter::number_of_result_handlers]; -+ int _stack_to_native_abi_is_generated[Interpreter::number_of_result_handlers]; -+ -+ memset(_tosca_to_stack_is_generated, 0, sizeof(_tosca_to_stack_is_generated)); -+ memset(_stack_to_stack_is_generated, 0, sizeof(_stack_to_stack_is_generated)); -+ memset(_stack_to_native_abi_is_generated, 0, sizeof(_stack_to_native_abi_is_generated)); -+ for (int i = 0; i < Interpreter::number_of_result_handlers; i++) { -+ BasicType type = types[i]; -+ if (!is_generated[Interpreter::BasicType_as_index(type)]++) { -+ Interpreter::_native_abi_to_tosca[Interpreter::BasicType_as_index(type)] = generate_result_handler_for(type); -+ } -+ if (!_tosca_to_stack_is_generated[Interpreter::BasicType_as_index(type)]++) { -+ Interpreter::_tosca_to_stack[Interpreter::BasicType_as_index(type)] = generate_tosca_to_stack_converter(type); -+ } -+ if (!_stack_to_stack_is_generated[Interpreter::BasicType_as_index(type)]++) { -+ Interpreter::_stack_to_stack[Interpreter::BasicType_as_index(type)] = generate_stack_to_stack_converter(type); -+ } -+ if (!_stack_to_native_abi_is_generated[Interpreter::BasicType_as_index(type)]++) { -+ Interpreter::_stack_to_native_abi[Interpreter::BasicType_as_index(type)] = generate_stack_to_native_abi_converter(type); -+ } -+ } -+ } -+ -+ -+#define method_entry(kind) Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind) -+ -+ { CodeletMark cm(_masm, "(kind = frame_manager)"); -+ // all non-native method kinds -+ method_entry(zerolocals); -+ method_entry(zerolocals_synchronized); -+ method_entry(empty); -+ method_entry(accessor); -+ method_entry(abstract); -+ method_entry(java_lang_math_sin ); -+ method_entry(java_lang_math_cos ); -+ method_entry(java_lang_math_tan ); -+ method_entry(java_lang_math_abs ); -+ method_entry(java_lang_math_sqrt ); -+ method_entry(java_lang_math_log ); -+ method_entry(java_lang_math_log10 ); -+ Interpreter::_native_entry_begin = Interpreter::code()->code_end(); -+ method_entry(native); -+ method_entry(native_synchronized); -+ Interpreter::_native_entry_end = Interpreter::code()->code_end(); -+ } -+ -+ -+#undef method_entry -+ -+} -+ -+#endif // CC_INTERP -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/cppInterpreter.hpp openjdk/hotspot/src/share/vm/interpreter/cppInterpreter.hpp ---- openjdk6/hotspot/src/share/vm/interpreter/cppInterpreter.hpp 1970-01-01 01:00:00.000000000 +0100 -+++ openjdk/hotspot/src/share/vm/interpreter/cppInterpreter.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -0,0 +1,83 @@ -+/* -+ * Copyright 1997-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, -+ * CA 95054 USA or visit www.sun.com if you need additional information or -+ * have any questions. -+ * -+ */ -+ -+#ifdef CC_INTERP -+ -+// This file contains the platform-independant parts -+// of the c++ interpreter -+ -+class CppInterpreter: public AbstractInterpreter { -+ friend class VMStructs; -+ friend class Interpreter; // contains() -+ friend class InterpreterGenerator; // result handlers -+ friend class CppInterpreterGenerator; // result handlers -+ public: -+ -+ -+ protected: -+ -+ // tosca result -> stack result -+ static address _tosca_to_stack[number_of_result_handlers]; // converts tosca to C++ interpreter stack result -+ // stack result -> stack result -+ static address _stack_to_stack[number_of_result_handlers]; // pass result between C++ interpreter calls -+ // stack result -> native abi result -+ static address _stack_to_native_abi[number_of_result_handlers]; // converts C++ interpreter results to native abi -+ -+ // this is to allow frame and only frame to use contains(). -+ friend class frame; -+ -+ public: -+ // Initialization/debugging -+ static void initialize(); -+ // this only returns whether a pc is within generated code for the interpreter. -+ -+ // This is a moderately dubious interface for the c++ interpreter. Only -+ // frame code and debug.cpp should be using it. -+ static bool contains(address pc); -+ -+ public: -+ -+ -+ // No displatch table to switch so no need for these to do anything special -+ static void notice_safepoints() {} -+ static void ignore_safepoints() {} -+ -+ static address native_result_to_tosca() { return (address)_native_abi_to_tosca; } // aka result handler -+ static address tosca_result_to_stack() { return (address)_tosca_to_stack; } -+ static address stack_result_to_stack() { return (address)_stack_to_stack; } -+ static address stack_result_to_native() { return (address)_stack_to_native_abi; } -+ -+ static address native_result_to_tosca(int index) { return _native_abi_to_tosca[index]; } // aka result handler -+ static address tosca_result_to_stack(int index) { return _tosca_to_stack[index]; } -+ static address stack_result_to_stack(int index) { return _stack_to_stack[index]; } -+ static address stack_result_to_native(int index) { return _stack_to_native_abi[index]; } -+ -+ static address return_entry (TosState state, int length); -+ static address deopt_entry (TosState state, int length); -+ -+#include "incls/_cppInterpreter_pd.hpp.incl" -+ -+}; -+ -+#endif // CC_INTERP -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/cppInterpreterGenerator.hpp openjdk/hotspot/src/share/vm/interpreter/cppInterpreterGenerator.hpp ---- openjdk6/hotspot/src/share/vm/interpreter/cppInterpreterGenerator.hpp 1970-01-01 01:00:00.000000000 +0100 -+++ openjdk/hotspot/src/share/vm/interpreter/cppInterpreterGenerator.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -0,0 +1,47 @@ -+/* -+ * Copyright 1997-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, -+ * CA 95054 USA or visit www.sun.com if you need additional information or -+ * have any questions. -+ * -+ */ -+ -+// This file contains the platform-independant parts -+// of the template interpreter generator. -+ -+#ifdef CC_INTERP -+ -+class CppInterpreterGenerator: public AbstractInterpreterGenerator { -+ protected: -+ // shared code sequences -+ // Converter for native abi result to tosca result -+ address generate_result_handler_for(BasicType type); -+ address generate_tosca_to_stack_converter(BasicType type); -+ address generate_stack_to_stack_converter(BasicType type); -+ address generate_stack_to_native_abi_converter(BasicType type); -+ -+ void generate_all(); -+ -+ public: -+ CppInterpreterGenerator(StubQueue* _code); -+ -+ #include "incls/_cppInterpreterGenerator_pd.hpp.incl" -+}; -+ -+#endif // CC_INTERP -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/interpreter.cpp openjdk/hotspot/src/share/vm/interpreter/interpreter.cpp ---- openjdk6/hotspot/src/share/vm/interpreter/interpreter.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/interpreter/interpreter.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)interpreter.cpp 1.246 07/06/08 15:21:43 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -63,58 +60,20 @@ - - - //------------------------------------------------------------------------------------------------------------------------ --// Implementation of AbstractInterpreter -- -- --// Define a prototype interface --DEF_STUB_INTERFACE(InterpreterCodelet); -- -+// Implementation of platform independent aspects of Interpreter - - void AbstractInterpreter::initialize() { - if (_code != NULL) return; - -- // assertions --#ifndef CC_INTERP -- assert((int)Bytecodes::number_of_codes <= (int)DispatchTable::length, -- "dispatch table too small"); --#endif /* !CC_INTERP */ -- - // make sure 'imported' classes are initialized - if (CountBytecodes || TraceBytecodes || StopInterpreterAt) BytecodeCounter::reset(); - if (PrintBytecodeHistogram) BytecodeHistogram::reset(); - if (PrintBytecodePairHistogram) BytecodePairHistogram::reset(); --#ifndef CC_INTERP -- TemplateTable::initialize(); --#endif /* !CC_INTERP */ -- InvocationCounter::reinitialize(DelayCompilationDuringStartup); - -- // generate interpreter -- { ResourceMark rm; -- TraceTime timer("Interpreter generation", TraceStartupTime); -- int code_size = Interpreter::InterpreterCodeSize; -- NOT_PRODUCT(code_size *= 4;) // debug uses extra interpreter code space -- _code = new StubQueue(new InterpreterCodeletInterface, code_size, NULL, -- "Interpreter"); -- InterpreterGenerator g(_code); -- if (PrintInterpreter) print(); -- } -+ InvocationCounter::reinitialize(DelayCompilationDuringStartup); - --#ifdef CC_INTERP -- { -- // Allow c++ interpreter to do one initialization now that switches are set, etc. -- cInterpreter start_msg(cInterpreter::initialize); -- if (JvmtiExport::can_post_interpreter_events()) -- cInterpreter::InterpretMethodWithChecks(&start_msg); -- else -- cInterpreter::InterpretMethod(&start_msg); -- } --#else -- // initialize dispatch table -- _active_table = _normal_table; --#endif // CC_INTERP - } - -- - void AbstractInterpreter::print() { - tty->cr(); - tty->print_cr("----------------------------------------------------------------------"); -@@ -159,312 +118,28 @@ - } - } - -- --#ifndef CC_INTERP --//------------------------------------------------------------------------------------------------------------------------ --// Implementation of EntryPoint -- --EntryPoint::EntryPoint() { -- assert(number_of_states == 9, "check the code below"); -- _entry[btos] = NULL; -- _entry[ctos] = NULL; -- _entry[stos] = NULL; -- _entry[atos] = NULL; -- _entry[itos] = NULL; -- _entry[ltos] = NULL; -- _entry[ftos] = NULL; -- _entry[dtos] = NULL; -- _entry[vtos] = NULL; --} -- -- --EntryPoint::EntryPoint(address bentry, address centry, address sentry, address aentry, address ientry, address lentry, address fentry, address dentry, address ventry) { -- assert(number_of_states == 9, "check the code below"); -- _entry[btos] = bentry; -- _entry[ctos] = centry; -- _entry[stos] = sentry; -- _entry[atos] = aentry; -- _entry[itos] = ientry; -- _entry[ltos] = lentry; -- _entry[ftos] = fentry; -- _entry[dtos] = dentry; -- _entry[vtos] = ventry; --} -- -- --void EntryPoint::set_entry(TosState state, address entry) { -- assert(0 <= state && state < number_of_states, "state out of bounds"); -- _entry[state] = entry; --} -- -- --address EntryPoint::entry(TosState state) const { -- assert(0 <= state && state < number_of_states, "state out of bounds"); -- return _entry[state]; --} -- -- --void EntryPoint::print() { -- tty->print("["); -- for (int i = 0; i < number_of_states; i++) { -- if (i > 0) tty->print(", "); -- tty->print(INTPTR_FORMAT, _entry[i]); -- } -- tty->print("]"); --} -- -- --bool EntryPoint::operator == (const EntryPoint& y) { -- int i = number_of_states; -- while (i-- > 0) { -- if (_entry[i] != y._entry[i]) return false; -- } -- return true; --} -- -- --//------------------------------------------------------------------------------------------------------------------------ --// Implementation of DispatchTable -- --EntryPoint DispatchTable::entry(int i) const { -- assert(0 <= i && i < length, "index out of bounds"); -- return -- EntryPoint( -- _table[btos][i], -- _table[ctos][i], -- _table[stos][i], -- _table[atos][i], -- _table[itos][i], -- _table[ltos][i], -- _table[ftos][i], -- _table[dtos][i], -- _table[vtos][i] -- ); --} -- -- --void DispatchTable::set_entry(int i, EntryPoint& entry) { -- assert(0 <= i && i < length, "index out of bounds"); -- assert(number_of_states == 9, "check the code below"); -- _table[btos][i] = entry.entry(btos); -- _table[ctos][i] = entry.entry(ctos); -- _table[stos][i] = entry.entry(stos); -- _table[atos][i] = entry.entry(atos); -- _table[itos][i] = entry.entry(itos); -- _table[ltos][i] = entry.entry(ltos); -- _table[ftos][i] = entry.entry(ftos); -- _table[dtos][i] = entry.entry(dtos); -- _table[vtos][i] = entry.entry(vtos); --} -- -- --bool DispatchTable::operator == (DispatchTable& y) { -- int i = length; -- while (i-- > 0) { -- EntryPoint t = y.entry(i); // for compiler compatibility (BugId 4150096) -- if (!(entry(i) == t)) return false; -- } -- return true; --} --#endif // CC_INTERP -- -- - //------------------------------------------------------------------------------------------------------------------------ - // Implementation of interpreter - - StubQueue* AbstractInterpreter::_code = NULL; - bool AbstractInterpreter::_notice_safepoints = false; -- - address AbstractInterpreter::_rethrow_exception_entry = NULL; --#ifndef CC_INTERP --address AbstractInterpreter::_remove_activation_entry = NULL; --address AbstractInterpreter::_remove_activation_preserving_args_entry = NULL; -- -- --address AbstractInterpreter::_throw_ArrayIndexOutOfBoundsException_entry = NULL; --address AbstractInterpreter::_throw_ArrayStoreException_entry = NULL; --address AbstractInterpreter::_throw_ArithmeticException_entry = NULL; --address AbstractInterpreter::_throw_ClassCastException_entry = NULL; --address AbstractInterpreter::_throw_NullPointerException_entry = NULL; --address AbstractInterpreter::_throw_StackOverflowError_entry = NULL; --address AbstractInterpreter::_throw_exception_entry = NULL; -- --#ifndef PRODUCT --EntryPoint AbstractInterpreter::_trace_code; --#endif // !PRODUCT --EntryPoint AbstractInterpreter::_return_entry[AbstractInterpreter::number_of_return_entries]; --EntryPoint AbstractInterpreter::_earlyret_entry; --EntryPoint AbstractInterpreter::_deopt_entry [AbstractInterpreter::number_of_deopt_entries ]; --EntryPoint AbstractInterpreter::_continuation_entry; --EntryPoint AbstractInterpreter::_safept_entry; -- --address AbstractInterpreter::_return_3_addrs_by_index[AbstractInterpreter::number_of_return_addrs]; --address AbstractInterpreter::_return_5_addrs_by_index[AbstractInterpreter::number_of_return_addrs]; -- --DispatchTable AbstractInterpreter::_active_table; --DispatchTable AbstractInterpreter::_normal_table; --DispatchTable AbstractInterpreter::_safept_table; --address AbstractInterpreter::_wentry_point[DispatchTable::length]; --#endif // CC_INTERP - - address AbstractInterpreter::_native_entry_begin = NULL; - address AbstractInterpreter::_native_entry_end = NULL; - address AbstractInterpreter::_slow_signature_handler; - address AbstractInterpreter::_entry_table [AbstractInterpreter::number_of_method_entries]; - address AbstractInterpreter::_native_abi_to_tosca [AbstractInterpreter::number_of_result_handlers]; --#ifdef CC_INTERP --address AbstractInterpreter::_tosca_to_stack [AbstractInterpreter::number_of_result_handlers]; --address AbstractInterpreter::_stack_to_stack [AbstractInterpreter::number_of_result_handlers]; --address AbstractInterpreter::_stack_to_native_abi [AbstractInterpreter::number_of_result_handlers]; --#endif -- -- --//------------------------------------------------------------------------------------------------------------------------ --// A CodeletMark serves as an automatic creator/initializer for Codelets --// (As a subclass of ResourceMark it automatically GC's the allocated --// code buffer and assemblers). -- --class CodeletMark: ResourceMark { -- private: -- InterpreterCodelet* _clet; -- InterpreterMacroAssembler** _masm; -- CodeBuffer _cb; -- -- int codelet_size() { -- // Request the whole code buffer (minus a little for alignment). -- // The commit call below trims it back for each codelet. -- int codelet_size = AbstractInterpreter::code()->available_space() - 2*K; -- -- // Guarantee there's a little bit of code space left. -- guarantee (codelet_size > 0 && (size_t)codelet_size > 2*K, -- "not enough space for interpreter generation"); -- -- return codelet_size; -- } -- -- public: -- CodeletMark( -- InterpreterMacroAssembler*& masm, -- const char* description, -- Bytecodes::Code bytecode = Bytecodes::_illegal): -- _clet((InterpreterCodelet*)AbstractInterpreter::code()->request(codelet_size())), -- _cb(_clet->code_begin(), _clet->code_size()) -- -- { // request all space (add some slack for Codelet data) -- assert (_clet != NULL, "we checked not enough space already"); -- -- // initialize Codelet attributes -- _clet->initialize(description, bytecode); -- // create assembler for code generation -- masm = new InterpreterMacroAssembler(&_cb); -- _masm = &masm; -- } -- -- ~CodeletMark() { -- // align so printing shows nop's instead of random code at the end (Codelets are aligned) -- (*_masm)->align(wordSize); -- // make sure all code is in code buffer -- (*_masm)->flush(); -- -- -- // commit Codelet -- AbstractInterpreter::code()->commit((*_masm)->code()->pure_code_size()); -- // make sure nobody can use _masm outside a CodeletMark lifespan -- *_masm = NULL; -- } --}; -- - - //------------------------------------------------------------------------------------------------------------------------ - // Generation of complete interpreter - - AbstractInterpreterGenerator::AbstractInterpreterGenerator(StubQueue* _code) { - _masm = NULL; --#ifndef CC_INTERP -- _unimplemented_bytecode = NULL; -- _illegal_bytecode_sequence = NULL; --#endif // CC_INTERP - } - - --void AbstractInterpreterGenerator::generate_all() { --#ifndef CC_INTERP -- { CodeletMark cm(_masm, "error exits"); -- _unimplemented_bytecode = generate_error_exit("unimplemented bytecode"); -- _illegal_bytecode_sequence = generate_error_exit("illegal bytecode sequence - method not verified"); -- } -- --#ifndef PRODUCT -- if (TraceBytecodes) { -- CodeletMark cm(_masm, "bytecode tracing support"); -- Interpreter::_trace_code = -- EntryPoint( -- generate_trace_code(btos), -- generate_trace_code(ctos), -- generate_trace_code(stos), -- generate_trace_code(atos), -- generate_trace_code(itos), -- generate_trace_code(ltos), -- generate_trace_code(ftos), -- generate_trace_code(dtos), -- generate_trace_code(vtos) -- ); -- } --#endif // !PRODUCT -- -- { CodeletMark cm(_masm, "return entry points"); -- for (int i = 0; i < Interpreter::number_of_return_entries; i++) { -- Interpreter::_return_entry[i] = -- EntryPoint( -- generate_return_entry_for(itos, i), -- generate_return_entry_for(itos, i), -- generate_return_entry_for(itos, i), -- generate_return_entry_for(atos, i), -- generate_return_entry_for(itos, i), -- generate_return_entry_for(ltos, i), -- generate_return_entry_for(ftos, i), -- generate_return_entry_for(dtos, i), -- generate_return_entry_for(vtos, i) -- ); -- } -- } -- -- { CodeletMark cm(_masm, "earlyret entry points"); -- Interpreter::_earlyret_entry = -- EntryPoint( -- generate_earlyret_entry_for(btos), -- generate_earlyret_entry_for(ctos), -- generate_earlyret_entry_for(stos), -- generate_earlyret_entry_for(atos), -- generate_earlyret_entry_for(itos), -- generate_earlyret_entry_for(ltos), -- generate_earlyret_entry_for(ftos), -- generate_earlyret_entry_for(dtos), -- generate_earlyret_entry_for(vtos) -- ); -- } -- -- { CodeletMark cm(_masm, "deoptimization entry points"); -- for (int i = 0; i < Interpreter::number_of_deopt_entries; i++) { -- Interpreter::_deopt_entry[i] = -- EntryPoint( -- generate_deopt_entry_for(itos, i), -- generate_deopt_entry_for(itos, i), -- generate_deopt_entry_for(itos, i), -- generate_deopt_entry_for(atos, i), -- generate_deopt_entry_for(itos, i), -- generate_deopt_entry_for(ltos, i), -- generate_deopt_entry_for(ftos, i), -- generate_deopt_entry_for(dtos, i), -- generate_deopt_entry_for(vtos, i) -- ); -- } -- } -- --#endif // !CC_INTERP -- -- { CodeletMark cm(_masm, "result handlers for native calls"); -- const BasicType types[Interpreter::number_of_result_handlers] = { -+static const BasicType types[Interpreter::number_of_result_handlers] = { - T_BOOLEAN, - T_CHAR , - T_BYTE , -@@ -475,297 +150,16 @@ - T_FLOAT , - T_DOUBLE , - T_OBJECT -- }; -- // The various result converter stublets. -- int is_generated[Interpreter::number_of_result_handlers]; -- memset(is_generated, 0, sizeof(is_generated)); --#ifdef CC_INTERP -- int _tosca_to_stack_is_generated[Interpreter::number_of_result_handlers]; -- int _stack_to_stack_is_generated[Interpreter::number_of_result_handlers]; -- int _stack_to_native_abi_is_generated[Interpreter::number_of_result_handlers]; -- -- memset(_tosca_to_stack_is_generated, 0, sizeof(_tosca_to_stack_is_generated)); -- memset(_stack_to_stack_is_generated, 0, sizeof(_stack_to_stack_is_generated)); -- memset(_stack_to_native_abi_is_generated, 0, sizeof(_stack_to_native_abi_is_generated)); --#endif -- for (int i = 0; i < Interpreter::number_of_result_handlers; i++) { -- BasicType type = types[i]; -- if (!is_generated[Interpreter::BasicType_as_index(type)]++) { -- Interpreter::_native_abi_to_tosca[Interpreter::BasicType_as_index(type)] = generate_result_handler_for(type); -- } --#ifdef CC_INTERP -- if (!_tosca_to_stack_is_generated[Interpreter::BasicType_as_index(type)]++) { -- Interpreter::_tosca_to_stack[Interpreter::BasicType_as_index(type)] = generate_tosca_to_stack_converter(type); -- } -- if (!_stack_to_stack_is_generated[Interpreter::BasicType_as_index(type)]++) { -- Interpreter::_stack_to_stack[Interpreter::BasicType_as_index(type)] = generate_stack_to_stack_converter(type); -- } -- if (!_stack_to_native_abi_is_generated[Interpreter::BasicType_as_index(type)]++) { -- Interpreter::_stack_to_native_abi[Interpreter::BasicType_as_index(type)] = generate_stack_to_native_abi_converter(type); -- } --#endif -- } -- } -- -- { CodeletMark cm(_masm, "slow signature handler"); -- Interpreter::_slow_signature_handler = generate_slow_signature_handler(); -- } -- --#ifndef CC_INTERP -- for (int j = 0; j < number_of_states; j++) { -- const TosState states[] = {btos, ctos, stos, itos, ltos, ftos, dtos, atos, vtos}; -- Interpreter::_return_3_addrs_by_index[Interpreter::TosState_as_index(states[j])] = Interpreter::return_entry(states[j], 3); -- Interpreter::_return_5_addrs_by_index[Interpreter::TosState_as_index(states[j])] = Interpreter::return_entry(states[j], 5); -- } -- -- { CodeletMark cm(_masm, "continuation entry points"); -- Interpreter::_continuation_entry = -- EntryPoint( -- generate_continuation_for(btos), -- generate_continuation_for(ctos), -- generate_continuation_for(stos), -- generate_continuation_for(atos), -- generate_continuation_for(itos), -- generate_continuation_for(ltos), -- generate_continuation_for(ftos), -- generate_continuation_for(dtos), -- generate_continuation_for(vtos) -- ); -- } -- -- { CodeletMark cm(_masm, "safepoint entry points"); -- Interpreter::_safept_entry = -- EntryPoint( -- generate_safept_entry_for(btos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), -- generate_safept_entry_for(ctos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), -- generate_safept_entry_for(stos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), -- generate_safept_entry_for(atos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), -- generate_safept_entry_for(itos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), -- generate_safept_entry_for(ltos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), -- generate_safept_entry_for(ftos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), -- generate_safept_entry_for(dtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), -- generate_safept_entry_for(vtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)) -- ); -- } -- -- { CodeletMark cm(_masm, "exception handling"); -- // (Note: this is not safepoint safe because thread may return to compiled code) -- generate_throw_exception(); -- } -- -- { CodeletMark cm(_masm, "throw exception entrypoints"); -- Interpreter::_throw_ArrayIndexOutOfBoundsException_entry = generate_ArrayIndexOutOfBounds_handler("java/lang/ArrayIndexOutOfBoundsException"); -- Interpreter::_throw_ArrayStoreException_entry = generate_klass_exception_handler("java/lang/ArrayStoreException" ); -- Interpreter::_throw_ArithmeticException_entry = generate_exception_handler("java/lang/ArithmeticException" , "/ by zero"); -- Interpreter::_throw_ClassCastException_entry = generate_ClassCastException_handler(); -- Interpreter::_throw_NullPointerException_entry = generate_exception_handler("java/lang/NullPointerException" , NULL ); -- Interpreter::_throw_StackOverflowError_entry = generate_StackOverflowError_handler(); -- } --#endif // !CC_INTERP -- -- --#ifdef CC_INTERP -- --#define method_entry(kind) Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind) -- -- { CodeletMark cm(_masm, "(kind = frame_manager)"); -- // all non-native method kinds -- method_entry(zerolocals); -- method_entry(zerolocals_synchronized); -- method_entry(empty); -- method_entry(accessor); -- method_entry(abstract); -- method_entry(java_lang_math_sin ); -- method_entry(java_lang_math_cos ); -- method_entry(java_lang_math_tan ); -- method_entry(java_lang_math_abs ); -- method_entry(java_lang_math_sqrt ); -- method_entry(java_lang_math_log ); -- method_entry(java_lang_math_log10 ); -- Interpreter::_native_entry_begin = Interpreter::code()->code_end(); -- method_entry(native); -- method_entry(native_synchronized); -- Interpreter::_native_entry_end = Interpreter::code()->code_end(); -- } -- --#else -- --#define method_entry(kind) \ -- { CodeletMark cm(_masm, "method entry point (kind = " #kind ")"); \ -- Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind); \ -- } -- -- // all non-native method kinds -- method_entry(zerolocals) -- method_entry(zerolocals_synchronized) -- method_entry(empty) -- method_entry(accessor) -- method_entry(abstract) -- method_entry(java_lang_math_sin ) -- method_entry(java_lang_math_cos ) -- method_entry(java_lang_math_tan ) -- method_entry(java_lang_math_abs ) -- method_entry(java_lang_math_sqrt ) -- method_entry(java_lang_math_log ) -- method_entry(java_lang_math_log10) -- -- // all native method kinds (must be one contiguous block) -- Interpreter::_native_entry_begin = Interpreter::code()->code_end(); -- method_entry(native) -- method_entry(native_synchronized) -- Interpreter::_native_entry_end = Interpreter::code()->code_end(); -- --#endif // !CC_INTERP -- --#undef method_entry -- --#ifndef CC_INTERP -- // Bytecodes -- set_entry_points_for_all_bytes(); -- set_safepoints_for_all_bytes(); --#endif // !CC_INTERP --} -- -- --//------------------------------------------------------------------------------------------------------------------------ -- --#ifndef CC_INTERP --address AbstractInterpreterGenerator::generate_error_exit(const char* msg) { -- address entry = __ pc(); -- __ stop(msg); -- return entry; --} -- -- --//------------------------------------------------------------------------------------------------------------------------ -- --void AbstractInterpreterGenerator::set_entry_points_for_all_bytes() { -- for (int i = 0; i < DispatchTable::length; i++) { -- Bytecodes::Code code = (Bytecodes::Code)i; -- if (Bytecodes::is_defined(code)) { -- set_entry_points(code); -- } else { -- set_unimplemented(i); -- } -- } --} -- -- --void AbstractInterpreterGenerator::set_safepoints_for_all_bytes() { -- for (int i = 0; i < DispatchTable::length; i++) { -- Bytecodes::Code code = (Bytecodes::Code)i; -- if (Bytecodes::is_defined(code)) Interpreter::_safept_table.set_entry(code, Interpreter::_safept_entry); -- } --} -- -- --void AbstractInterpreterGenerator::set_unimplemented(int i) { -- address e = _unimplemented_bytecode; -- EntryPoint entry(e, e, e, e, e, e, e, e, e); -- Interpreter::_normal_table.set_entry(i, entry); -- Interpreter::_wentry_point[i] = _unimplemented_bytecode; --} -- -- --void AbstractInterpreterGenerator::set_entry_points(Bytecodes::Code code) { -- CodeletMark cm(_masm, Bytecodes::name(code), code); -- // initialize entry points -- assert(_unimplemented_bytecode != NULL, "should have been generated before"); -- assert(_illegal_bytecode_sequence != NULL, "should have been generated before"); -- address bep = _illegal_bytecode_sequence; -- address cep = _illegal_bytecode_sequence; -- address sep = _illegal_bytecode_sequence; -- address aep = _illegal_bytecode_sequence; -- address iep = _illegal_bytecode_sequence; -- address lep = _illegal_bytecode_sequence; -- address fep = _illegal_bytecode_sequence; -- address dep = _illegal_bytecode_sequence; -- address vep = _unimplemented_bytecode; -- address wep = _unimplemented_bytecode; -- // code for short & wide version of bytecode -- if (Bytecodes::is_defined(code)) { -- Template* t = TemplateTable::template_for(code); -- assert(t->is_valid(), "just checking"); -- set_short_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep); -- } -- if (Bytecodes::wide_is_defined(code)) { -- Template* t = TemplateTable::template_for_wide(code); -- assert(t->is_valid(), "just checking"); -- set_wide_entry_point(t, wep); -- } -- // set entry points -- EntryPoint entry(bep, cep, sep, aep, iep, lep, fep, dep, vep); -- Interpreter::_normal_table.set_entry(code, entry); -- Interpreter::_wentry_point[code] = wep; --} -- -+}; - --void AbstractInterpreterGenerator::set_wide_entry_point(Template* t, address& wep) { -- assert(t->is_valid(), "template must exist"); -- assert(t->tos_in() == vtos, "only vtos tos_in supported for wide instructions") -- wep = __ pc(); generate_and_dispatch(t); --} -+void AbstractInterpreterGenerator::generate_all() { - - --void AbstractInterpreterGenerator::set_short_entry_points(Template* t, address& bep, address& cep, address& sep, address& aep, address& iep, address& lep, address& fep, address& dep, address& vep) { -- assert(t->is_valid(), "template must exist"); -- switch (t->tos_in()) { -- case btos: vep = __ pc(); __ pop(btos); bep = __ pc(); generate_and_dispatch(t); break; -- case ctos: vep = __ pc(); __ pop(ctos); sep = __ pc(); generate_and_dispatch(t); break; -- case stos: vep = __ pc(); __ pop(stos); sep = __ pc(); generate_and_dispatch(t); break; -- case atos: vep = __ pc(); __ pop(atos); aep = __ pc(); generate_and_dispatch(t); break; -- case itos: vep = __ pc(); __ pop(itos); iep = __ pc(); generate_and_dispatch(t); break; -- case ltos: vep = __ pc(); __ pop(ltos); lep = __ pc(); generate_and_dispatch(t); break; -- case ftos: vep = __ pc(); __ pop(ftos); fep = __ pc(); generate_and_dispatch(t); break; -- case dtos: vep = __ pc(); __ pop(dtos); dep = __ pc(); generate_and_dispatch(t); break; -- case vtos: set_vtos_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep); break; -- default : ShouldNotReachHere(); break; -+ { CodeletMark cm(_masm, "slow signature handler"); -+ Interpreter::_slow_signature_handler = generate_slow_signature_handler(); - } --} -- - --//------------------------------------------------------------------------------------------------------------------------ -- --void AbstractInterpreterGenerator::generate_and_dispatch(Template* t, TosState tos_out) { --#ifndef CC_INTERP -- if (PrintBytecodeHistogram) histogram_bytecode(t); --#ifndef PRODUCT -- // debugging code -- if (CountBytecodes || TraceBytecodes || StopInterpreterAt > 0) count_bytecode(); -- if (PrintBytecodePairHistogram) histogram_bytecode_pair(t); -- if (TraceBytecodes) trace_bytecode(t); -- if (StopInterpreterAt > 0) stop_interpreter_at(); -- __ verify_FPU(1, t->tos_in()); --#endif // !PRODUCT -- int step; -- if (!t->does_dispatch()) { -- step = t->is_wide() ? Bytecodes::wide_length_for(t->bytecode()) : Bytecodes::length_for(t->bytecode()); -- if (tos_out == ilgl) tos_out = t->tos_out(); -- // compute bytecode size -- assert(step > 0, "just checkin'"); -- // setup stuff for dispatching next bytecode -- if (ProfileInterpreter && VerifyDataPointer -- && methodDataOopDesc::bytecode_has_profile(t->bytecode())) { -- __ verify_method_data_pointer(); -- } -- __ dispatch_prolog(tos_out, step); -- } -- // generate template -- t->generate(_masm); -- // advance -- if (t->does_dispatch()) { --#ifdef ASSERT -- // make sure execution doesn't go beyond this point if code is broken -- __ should_not_reach_here(); --#endif // ASSERT -- } else { -- // dispatch to next bytecode -- __ dispatch_epilog(tos_out, step); -- } --#endif - } --#endif /* !CC_INTERP */ -- - - //------------------------------------------------------------------------------------------------------------------------ - // Entry points -@@ -867,21 +261,6 @@ - } - #endif // PRODUCT - -- --#ifndef CC_INTERP --address AbstractInterpreter::return_entry(TosState state, int length) { -- guarantee(0 <= length && length < Interpreter::number_of_return_entries, "illegal length"); -- return _return_entry[length].entry(state); --} -- -- --address AbstractInterpreter::deopt_entry(TosState state, int length) { -- guarantee(0 <= length && length < Interpreter::number_of_deopt_entries, "illegal length"); -- return _deopt_entry[length].entry(state); --} -- --#endif /* CC_INTERP */ -- - static BasicType constant_pool_type(methodOop method, int index) { - constantTag tag = method->constants()->tag_at(index); - if (tag.is_int ()) return T_INT; -@@ -959,7 +338,7 @@ - // reexecute the operation and TOS value is on stack - assert(is_top_frame, "must be top frame"); - use_next_mdp = false; -- return deopt_entry(vtos, 0); -+ return Interpreter::deopt_entry(vtos, 0); - break; - - #ifdef COMPILER1 -@@ -996,18 +375,6 @@ - type = constant_pool_type( method, Bytes::get_Java_u2(bcp+1) ); - break; - -- case Bytecodes::_return: { -- // This is used for deopt during registration of finalizers -- // during Object.. We simply need to resume execution at -- // the standard return vtos bytecode to pop the frame normally. -- // reexecuting the real bytecode would cause double registration -- // of the finalizable object. --#ifndef CC_INTERP -- assert(is_top_frame, "must be on top"); -- return _normal_table.entry(Bytecodes::_return).entry(vtos); --#endif // CC_INTERP -- } -- - default: - type = Bytecodes::result_type(code); - break; -@@ -1016,60 +383,8 @@ - // return entry point for computed continuation state & bytecode length - return - is_top_frame -- ? deopt_entry (as_TosState(type), length) -- : return_entry(as_TosState(type), length); --} -- -- --#ifndef CC_INTERP -- --//------------------------------------------------------------------------------------------------------------------------ --// Suport for invokes -- --int AbstractInterpreter::TosState_as_index(TosState state) { -- assert( state < number_of_states , "Invalid state in TosState_as_index"); -- assert(0 <= (int)state && (int)state < AbstractInterpreter::number_of_return_addrs, "index out of bounds"); -- return (int)state; --} -- --#endif // CC_INTERP -- --//------------------------------------------------------------------------------------------------------------------------ --// Safepoint suppport -- --#ifndef CC_INTERP --static inline void copy_table(address* from, address* to, int size) { -- // Copy non-overlapping tables. The copy has to occur word wise for MT safety. -- while (size-- > 0) *to++ = *from++; --} --#endif -- --void AbstractInterpreter::notice_safepoints() { -- if (!_notice_safepoints) { -- // switch to safepoint dispatch table -- _notice_safepoints = true; --#ifndef CC_INTERP -- copy_table((address*)&_safept_table, (address*)&_active_table, sizeof(_active_table) / sizeof(address)); --#endif -- } --} -- -- --// switch from the dispatch table which notices safepoints back to the --// normal dispatch table. So that we can notice single stepping points, --// keep the safepoint dispatch table if we are single stepping in JVMTI. --// Note that the should_post_single_step test is exactly as fast as the --// JvmtiExport::_enabled test and covers both cases. --void AbstractInterpreter::ignore_safepoints() { -- if (_notice_safepoints) { -- if (!JvmtiExport::should_post_single_step()) { -- // switch to normal dispatch table -- _notice_safepoints = false; --#ifndef CC_INTERP -- copy_table((address*)&_normal_table, (address*)&_active_table, sizeof(_active_table) / sizeof(address)); --#endif -- } -- } -+ ? Interpreter::deopt_entry (as_TosState(type), length) -+ : Interpreter::return_entry(as_TosState(type), length); - } - - void AbstractInterpreterGenerator::bang_stack_shadow_pages(bool native_call) { -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/interpreter.hpp openjdk/hotspot/src/share/vm/interpreter/interpreter.hpp ---- openjdk6/hotspot/src/share/vm/interpreter/interpreter.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/interpreter/interpreter.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)interpreter.hpp 1.153 07/05/17 15:54:31 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -66,397 +63,72 @@ - Bytecodes::Code bytecode() const { return _bytecode; } - }; - -- --#ifndef CC_INTERP --//------------------------------------------------------------------------------------------------------------------------ --// A little wrapper class to group tosca-specific entry points into a unit. --// (tosca = Top-Of-Stack CAche) -- --class EntryPoint VALUE_OBJ_CLASS_SPEC { -- private: -- address _entry[number_of_states]; -- -- public: -- // Construction -- EntryPoint(); -- EntryPoint(address bentry, address centry, address sentry, address aentry, address ientry, address lentry, address fentry, address dentry, address ventry); -- -- // Attributes -- address entry(TosState state) const; // return target address for a given tosca state -- void set_entry(TosState state, address entry); // set target address for a given tosca state -- void print(); -- -- // Comparison -- bool operator == (const EntryPoint& y); // for debugging only --}; -+// Define a prototype interface -+DEF_STUB_INTERFACE(InterpreterCodelet); - - - //------------------------------------------------------------------------------------------------------------------------ --// A little wrapper class to group tosca-specific dispatch tables into a unit. -- --class DispatchTable VALUE_OBJ_CLASS_SPEC { -- public: -- enum { length = 1 << BitsPerByte }; // an entry point for each byte value (also for undefined bytecodes) -+// A CodeletMark serves as an automatic creator/initializer for Codelets -+// (As a subclass of ResourceMark it automatically GC's the allocated -+// code buffer and assemblers). - -+class CodeletMark: ResourceMark { - private: -- address _table[number_of_states][length]; // dispatch tables, indexed by tosca and bytecode -+ InterpreterCodelet* _clet; -+ InterpreterMacroAssembler** _masm; -+ CodeBuffer _cb; - -- public: -- // Attributes -- EntryPoint entry(int i) const; // return entry point for a given bytecode i -- void set_entry(int i, EntryPoint& entry); // set entry point for a given bytecode i -- address* table_for(TosState state) { return _table[state]; } -- address* table_for() { return table_for((TosState)0); } -- int distance_from(address *table) { return table - table_for(); } -- int distance_from(TosState state) { return distance_from(table_for(state)); } -- -- // Comparison -- bool operator == (DispatchTable& y); // for debugging only --}; -+ int codelet_size() { -+ // Request the whole code buffer (minus a little for alignment). -+ // The commit call below trims it back for each codelet. -+ int codelet_size = AbstractInterpreter::code()->available_space() - 2*K; - --#endif // CC_INTERP -- --//------------------------------------------------------------------------------------------------------------------------ --// The C++ interface to the bytecode interpreter. -- --class AbstractInterpreter: AllStatic { -- friend class VMStructs; -- friend class Interpreter; -- public: -- enum MethodKind { -- zerolocals, // method needs locals initialization -- zerolocals_synchronized, // method needs locals initialization & is synchronized -- native, // native method -- native_synchronized, // native method & is synchronized -- empty, // empty method (code: _return) -- accessor, // accessor method (code: _aload_0, _getfield, _(a|i)return) -- abstract, // abstract method (throws an AbstractMethodException) -- java_lang_math_sin, // implementation of java.lang.Math.sin (x) -- java_lang_math_cos, // implementation of java.lang.Math.cos (x) -- java_lang_math_tan, // implementation of java.lang.Math.tan (x) -- java_lang_math_abs, // implementation of java.lang.Math.abs (x) -- java_lang_math_sqrt, // implementation of java.lang.Math.sqrt (x) -- java_lang_math_log, // implementation of java.lang.Math.log (x) -- java_lang_math_log10, // implementation of java.lang.Math.log10 (x) -- number_of_method_entries, -- invalid = -1 -- }; -- -- enum SomeConstants { --#ifndef CC_INTERP -- number_of_return_entries = 9, // number of return entry points -- number_of_deopt_entries = 9, // number of deoptimization entry points -- number_of_return_addrs = 9, // number of return addresses --#endif // CC_INTERP -- number_of_result_handlers = 10 // number of result handlers for native calls -- }; -- -- protected: -- static StubQueue* _code; // the interpreter code (codelets) -- -- static address _rethrow_exception_entry; // rethrows an activation in previous frame --#ifdef HOTSWAP -- static address _remove_activation_preserving_args_entry; // continuation address when current frame is being popped --#endif // HOTSWAP -- --#ifndef CC_INTERP -- static address _throw_ArrayIndexOutOfBoundsException_entry; -- static address _throw_ArrayStoreException_entry; -- static address _throw_ArithmeticException_entry; -- static address _throw_ClassCastException_entry; -- static address _throw_NullPointerException_entry; -- static address _throw_StackOverflowError_entry; -- static address _throw_exception_entry; -- -- static address _remove_activation_entry; // continuation address if an exception is not handled by current frame -- --#ifndef PRODUCT -- static EntryPoint _trace_code; --#endif // !PRODUCT -- static EntryPoint _return_entry[number_of_return_entries]; // entry points to return to from a call -- static EntryPoint _earlyret_entry; // entry point to return early from a call -- static EntryPoint _deopt_entry[number_of_deopt_entries]; // entry points to return to from a deoptimization -- static EntryPoint _continuation_entry; -- static EntryPoint _safept_entry; -- -- static address _return_3_addrs_by_index[number_of_return_addrs]; // for invokevirtual return entries -- static address _return_5_addrs_by_index[number_of_return_addrs]; // for invokeinterface return entries -- -- static DispatchTable _active_table; // the active dispatch table (used by the interpreter for dispatch) -- static DispatchTable _normal_table; // the normal dispatch table (used to set the active table in normal mode) -- static DispatchTable _safept_table; // the safepoint dispatch table (used to set the active table for safepoints) -- static address _wentry_point[DispatchTable::length]; // wide instructions only (vtos tosca always) -- --#endif // CC_INTERP -- static bool _notice_safepoints; // true if safepoints are activated -- -- static address _native_entry_begin; // Region for native entry code -- static address _native_entry_end; -- -- // method entry points -- static address _entry_table[number_of_method_entries]; // entry points for a given method -- static address _native_abi_to_tosca[number_of_result_handlers]; // for native method result handlers --#ifdef CC_INTERP -- // tosca result -> stack result -- static address _tosca_to_stack[number_of_result_handlers]; // converts tosca to C++ interpreter stack result -- // stack result -> stack result -- static address _stack_to_stack[number_of_result_handlers]; // pass result between C++ interpreter calls -- // stack result -> native abi result -- static address _stack_to_native_abi[number_of_result_handlers]; // converts C++ interpreter results to native abi --#endif -- static address _slow_signature_handler; // the native method generic (slow) signature handler -- -- -- -- friend class TemplateTable; -- friend class AbstractInterpreterGenerator; -- friend class InterpreterGenerator; -- friend class InterpreterMacroAssembler; -+ // Guarantee there's a little bit of code space left. -+ guarantee (codelet_size > 0 && (size_t)codelet_size > 2*K, -+ "not enough space for interpreter generation"); - -- public: -- // Initialization/debugging -- static void initialize(); -- static StubQueue* code() { return _code; } -- // this only returns whether a pc is within generated code for the interpreter. --#ifdef CC_INTERP -- private: -- // for the c++ based interpreter this misses much code. make sure it doesn't get called. --#endif // CC_INTERP -- static bool contains(address pc) { return _code->contains(pc); } -+ return codelet_size; -+ } - - public: -+ CodeletMark( -+ InterpreterMacroAssembler*& masm, -+ const char* description, -+ Bytecodes::Code bytecode = Bytecodes::_illegal): -+ _clet((InterpreterCodelet*)AbstractInterpreter::code()->request(codelet_size())), -+ _cb(_clet->code_begin(), _clet->code_size()) - -- // Method activation -- static MethodKind method_kind(methodHandle m); -- static address entry_for_kind(MethodKind k) { assert(0 <= k && k < number_of_method_entries, "illegal kind"); return _entry_table[k]; } -- static address entry_for_method(methodHandle m) { return _entry_table[method_kind(m)]; } -- -- static void print_method_kind(MethodKind kind) PRODUCT_RETURN; -- -- // Runtime support -- -- static address rethrow_exception_entry() { return _rethrow_exception_entry; } -- -- static address return_entry (TosState state, int length); // length = invoke bytecode length (to advance to next bytecode) -- static address deopt_entry (TosState state, int length); // length = invoke bytecode length (to advance to next bytecode) -- --#ifdef HOTSWAP -- static address remove_activation_preserving_args_entry() { return _remove_activation_preserving_args_entry; } --#endif // HOTSWAP -- --#ifndef CC_INTERP -- static address remove_activation_early_entry(TosState state) { return _earlyret_entry.entry(state); } -- static address remove_activation_entry() { return _remove_activation_entry; } -- static address throw_exception_entry() { return _throw_exception_entry; } -- static address throw_ArithmeticException_entry() { return _throw_ArithmeticException_entry; } -- static address throw_NullPointerException_entry() { return _throw_NullPointerException_entry; } -- static address throw_StackOverflowError_entry() { return _throw_StackOverflowError_entry; } -- -- // Code generation --#ifndef PRODUCT -- static address trace_code (TosState state) { return _trace_code.entry(state); } --#endif // !PRODUCT -- static address continuation (TosState state) { return _continuation_entry.entry(state); } -- static address* dispatch_table(TosState state) { return _active_table.table_for(state); } -- static address* dispatch_table() { return _active_table.table_for(); } -- static int distance_from_dispatch_table(TosState state){ return _active_table.distance_from(state); } -- static address* normal_table(TosState state) { return _normal_table.table_for(state); } -- static address* normal_table() { return _normal_table.table_for(); } -- -- // Support for invokes -- static address* return_3_addrs_by_index_table() { return _return_3_addrs_by_index; } -- static address* return_5_addrs_by_index_table() { return _return_5_addrs_by_index; } -- static int TosState_as_index(TosState state); // computes index into return_3_entry_by_index table --#endif // CC_INTERP -- -- -- // Activation size in words for a method that is just being called. -- // Parameters haven't been pushed so count them too. -- static int size_top_interpreter_activation(methodOop method); -- -- // Deoptimization support -- static address continuation_for(methodOop method, -- address bcp, -- int callee_parameters, -- bool is_top_frame, -- bool& use_next_mdp); -- -- // share implementation of size_activation and layout_activation: -- static int size_activation(methodOop method, -- int temps, -- int popframe_args, -- int monitors, -- int callee_params, -- int callee_locals, -- bool is_top_frame); -- -- static int layout_activation(methodOop method, -- int temps, -- int popframe_args, -- int monitors, -- int callee_params, -- int callee_locals, -- frame* caller, -- frame* interpreter_frame, -- bool is_top_frame); -- -- // Runtime support -- static bool is_not_reached( methodHandle method, int bci); -- // Safepoint support -- static void notice_safepoints(); // stops the thread when reaching a safepoint -- static void ignore_safepoints(); // ignores safepoints -- -- // Support for native calls -- static address slow_signature_handler() { return _slow_signature_handler; } -- static address result_handler(BasicType type) { return _native_abi_to_tosca[BasicType_as_index(type)]; } -- static int BasicType_as_index(BasicType type); // computes index into result_handler_by_index table -- static bool in_native_entry(address pc) { return _native_entry_begin <= pc && pc < _native_entry_end; } -- // Debugging/printing -- static InterpreterCodelet* codelet_containing(address pc) { return (InterpreterCodelet*)_code->stub_containing(pc); } -- static void print(); // prints the interpreter code --#ifdef CC_INTERP -- static address native_result_to_tosca() { return (address)_native_abi_to_tosca; } // aka result handler -- static address tosca_result_to_stack() { return (address)_tosca_to_stack; } -- static address stack_result_to_stack() { return (address)_stack_to_stack; } -- static address stack_result_to_native() { return (address)_stack_to_native_abi; } -- -- static address native_result_to_tosca(int index) { return _native_abi_to_tosca[index]; } // aka result handler -- static address tosca_result_to_stack(int index) { return _tosca_to_stack[index]; } -- static address stack_result_to_stack(int index) { return _stack_to_stack[index]; } -- static address stack_result_to_native(int index) { return _stack_to_native_abi[index]; } --#endif /* CC_INTERP */ -- -- // Support for Tagged Stacks -- // -- // Tags are stored on the Java Expression stack above the value: -- // -- // tag -- // value -- // -- // For double values: -- // -- // tag2 -- // high word -- // tag1 -- // low word -- -- public: -- static int stackElementWords() { return TaggedStackInterpreter ? 2 : 1; } -- static int stackElementSize() { return stackElementWords()*wordSize; } -- static int logStackElementSize() { return -- TaggedStackInterpreter? LogBytesPerWord+1 : LogBytesPerWord; } -- -- // Tag is at pointer, value is one below for a stack growing down -- // (or above for stack growing up) -- static int value_offset_in_bytes() { -- return TaggedStackInterpreter ? -- frame::interpreter_frame_expression_stack_direction() * wordSize : 0; -- } -- static int tag_offset_in_bytes() { -- assert(TaggedStackInterpreter, "should not call this"); -- return 0; -- } -+ { // request all space (add some slack for Codelet data) -+ assert (_clet != NULL, "we checked not enough space already"); - -- // Tagged Locals -- // Locals are stored relative to Llocals: -- // -- // tag <- Llocals[n] -- // value -- // -- // Category 2 types are indexed as: -- // -- // tag <- Llocals[-n] -- // high word -- // tag <- Llocals[-n+1] -- // low word -- // -- -- // Local values relative to locals[n] -- static int local_offset_in_bytes(int n) { -- return ((frame::interpreter_frame_expression_stack_direction() * n) * -- stackElementSize()) + value_offset_in_bytes(); -- } -- static int local_tag_offset_in_bytes(int n) { -- assert(TaggedStackInterpreter, "should not call this"); -- return ((frame::interpreter_frame_expression_stack_direction() * n) * -- stackElementSize()) + tag_offset_in_bytes(); -+ // initialize Codelet attributes -+ _clet->initialize(description, bytecode); -+ // create assembler for code generation -+ masm = new InterpreterMacroAssembler(&_cb); -+ _masm = &masm; - } - --}; -+ ~CodeletMark() { -+ // align so printing shows nop's instead of random code at the end (Codelets are aligned) -+ (*_masm)->align(wordSize); -+ // make sure all code is in code buffer -+ (*_masm)->flush(); - - --//------------------------------------------------------------------------------------------------------------------------ --// The interpreter generator. -- --class Template; --class AbstractInterpreterGenerator: public StackObj { -- protected: -- InterpreterMacroAssembler* _masm; -- --#ifndef CC_INTERP -- // entry points for shared code sequence -- address _unimplemented_bytecode; -- address _illegal_bytecode_sequence; --#endif -- -- // shared code sequences -- // Converter for native abi result to tosca result -- address generate_result_handler_for(BasicType type); --#ifdef CC_INTERP -- address generate_tosca_to_stack_converter(BasicType type); -- address generate_stack_to_stack_converter(BasicType type); -- address generate_stack_to_native_abi_converter(BasicType type); --#endif -- address generate_slow_signature_handler(); --#ifndef CC_INTERP -- address generate_error_exit(const char* msg); -- address generate_StackOverflowError_handler(); -- address generate_exception_handler(const char* name, const char* message) { -- return generate_exception_handler_common(name, message, false); -+ // commit Codelet -+ AbstractInterpreter::code()->commit((*_masm)->code()->pure_code_size()); -+ // make sure nobody can use _masm outside a CodeletMark lifespan -+ *_masm = NULL; - } -- address generate_klass_exception_handler(const char* name) { -- return generate_exception_handler_common(name, NULL, true); -- } -- address generate_exception_handler_common(const char* name, const char* message, bool pass_oop); -- address generate_ClassCastException_handler(); -- address generate_ArrayIndexOutOfBounds_handler(const char* name); -- address generate_continuation_for(TosState state); -- address generate_return_entry_for(TosState state, int step); -- address generate_earlyret_entry_for(TosState state); -- address generate_deopt_entry_for(TosState state, int step); -- address generate_safept_entry_for(TosState state, address runtime_entry); -- void generate_throw_exception(); --#endif // CC_INTERP -- -- // entry point generator -- address generate_method_entry(AbstractInterpreter::MethodKind kind); -- void generate_fast_accessor_code(); // implements UseFastAccessorMethods -- --#ifndef CC_INTERP -- // Instruction generation -- void generate_and_dispatch (Template* t, TosState tos_out = ilgl); -- void set_vtos_entry_points (Template* t, address& bep, address& cep, address& sep, address& aep, address& iep, address& lep, address& fep, address& dep, address& vep); -- void set_short_entry_points(Template* t, address& bep, address& cep, address& sep, address& aep, address& iep, address& lep, address& fep, address& dep, address& vep); -- void set_wide_entry_point (Template* t, address& wep); -- -- void set_entry_points(Bytecodes::Code code); -- void set_unimplemented(int i); -- void set_entry_points_for_all_bytes(); -- void set_safepoints_for_all_bytes(); -- -- // Helpers for generate_and_dispatch -- address generate_trace_code(TosState state) PRODUCT_RETURN0; -- void count_bytecode() PRODUCT_RETURN; -- void histogram_bytecode(Template* t) PRODUCT_RETURN; -- void histogram_bytecode_pair(Template* t) PRODUCT_RETURN; -- void trace_bytecode(Template* t) PRODUCT_RETURN; -- void stop_interpreter_at() PRODUCT_RETURN; --#endif // CC_INTERP -+}; - -- void bang_stack_shadow_pages(bool native_call); -+// Wrapper classes to produce Interpreter/InterpreterGenerator from either -+// the c++ interpreter or the template interpreter. - -- void generate_all(); -+class Interpreter: public CC_INTERP_ONLY(CppInterpreter) NOT_CC_INTERP(TemplateInterpreter) { - - public: -- AbstractInterpreterGenerator(StubQueue* _code); -+ // Debugging/printing -+ static InterpreterCodelet* codelet_containing(address pc) { return (InterpreterCodelet*)_code->stub_containing(pc); } -+#include "incls/_interpreter_pd.hpp.incl" - }; -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/interpreterGenerator.hpp openjdk/hotspot/src/share/vm/interpreter/interpreterGenerator.hpp ---- openjdk6/hotspot/src/share/vm/interpreter/interpreterGenerator.hpp 1970-01-01 01:00:00.000000000 +0100 -+++ openjdk/hotspot/src/share/vm/interpreter/interpreterGenerator.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -0,0 +1,38 @@ -+/* -+ * Copyright 1997-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, -+ * CA 95054 USA or visit www.sun.com if you need additional information or -+ * have any questions. -+ * -+ */ -+ -+// This file contains the platform-independant parts -+// of the interpreter generator. -+ -+ -+class InterpreterGenerator: public CC_INTERP_ONLY(CppInterpreterGenerator) -+ NOT_CC_INTERP(TemplateInterpreterGenerator) { -+ -+public: -+ -+InterpreterGenerator(StubQueue* _code); -+ -+#include "incls/_interpreterGenerator_pd.hpp.incl" -+ -+}; -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp openjdk/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp ---- openjdk6/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)interpreterRuntime.cpp 1.487 07/05/05 17:05:38 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -1077,7 +1074,7 @@ - Disassembler::decode(handler, handler + buffer.code_size()); - #ifndef PRODUCT - tty->print_cr(" --- associated result handler ---"); -- address rh_begin = AbstractInterpreter::result_handler(method()->result_type()); -+ address rh_begin = Interpreter::result_handler(method()->result_type()); - address rh_end = rh_begin; - while (*(int*)rh_end != 0) { - rh_end += sizeof(int); -@@ -1098,13 +1095,13 @@ - } - if (handler_index < 0) { - // use generic signature handler -- method->set_signature_handler(AbstractInterpreter::slow_signature_handler()); -+ method->set_signature_handler(Interpreter::slow_signature_handler()); - } else { - // set handler - method->set_signature_handler(_handlers->at(handler_index)); - } - } -- assert(method->signature_handler() == AbstractInterpreter::slow_signature_handler() || -+ assert(method->signature_handler() == Interpreter::slow_signature_handler() || - _handlers->find(method->signature_handler()) == _fingerprints->find(Fingerprinter(method).fingerprint()), - "sanity check"); - } -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp openjdk/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp ---- openjdk6/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)interpreterRuntime.hpp 1.143 07/05/05 17:05:38 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/invocationCounter.cpp openjdk/hotspot/src/share/vm/interpreter/invocationCounter.cpp ---- openjdk6/hotspot/src/share/vm/interpreter/invocationCounter.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/interpreter/invocationCounter.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)invocationCounter.cpp 1.60 07/05/05 17:05:38 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -171,4 +168,3 @@ - void invocationCounter_init() { - InvocationCounter::reinitialize(DelayCompilationDuringStartup); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/invocationCounter.hpp openjdk/hotspot/src/share/vm/interpreter/invocationCounter.hpp ---- openjdk6/hotspot/src/share/vm/interpreter/invocationCounter.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/interpreter/invocationCounter.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)invocationCounter.hpp 1.49 07/05/05 17:05:39 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -89,7 +86,6 @@ - int limit() const { return CompileThreshold; } - Action action() const { return _action[state()]; } - int count() const { return _counter >> number_of_noncount_bits; } -- bool has_overflowed() const { return count() >= limit(); } - - int get_InvocationLimit() const { return InterpreterInvocationLimit >> number_of_noncount_bits; } - int get_BackwardBranchLimit() const { return InterpreterBackwardBranchLimit >> number_of_noncount_bits; } -@@ -139,5 +135,3 @@ - if (c > 0 && new_count == 0) new_count = 1; - set(state(), new_count); - } -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/linkResolver.cpp openjdk/hotspot/src/share/vm/interpreter/linkResolver.cpp ---- openjdk6/hotspot/src/share/vm/interpreter/linkResolver.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/interpreter/linkResolver.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)linkResolver.cpp 1.174 07/05/05 17:05:40 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -1001,4 +998,3 @@ - } - - #endif -- -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/linkResolver.hpp openjdk/hotspot/src/share/vm/interpreter/linkResolver.hpp ---- openjdk6/hotspot/src/share/vm/interpreter/linkResolver.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/interpreter/linkResolver.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)linkResolver.hpp 1.74 07/05/05 17:05:39 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -172,4 +169,3 @@ - - static void resolve_invoke (CallInfo& result, Handle recv, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/oopMapCache.cpp openjdk/hotspot/src/share/vm/interpreter/oopMapCache.cpp ---- openjdk6/hotspot/src/share/vm/interpreter/oopMapCache.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/interpreter/oopMapCache.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)oopMapCache.cpp 1.85 08/06/19 12:45:42 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -535,10 +532,6 @@ - if (!_array[i].is_empty() && _array[i].method()->is_old()) { - // Cache entry is occupied by an old redefined method and we don't want - // to pin it down so flush the entry. -- RC_TRACE(0x08000000, ("flush: %s(%s): cached entry @%d", -- _array[i].method()->name()->as_C_string(), -- _array[i].method()->signature()->as_C_string(), i)); -- - _array[i].flush(); - } - } -@@ -584,15 +577,6 @@ - // Entry is not in hashtable. - // Compute entry and return it - -- if (method->should_not_be_cached()) { -- // It is either not safe or not a good idea to cache this methodOop -- // at this time. We give the caller of lookup() a copy of the -- // interesting info via parameter entry_for, but we don't add it to -- // the cache. See the gory details in methodOop.cpp. -- compute_one_oop_map(method, bci, entry_for); -- return; -- } -- - // First search for an empty slot - for(i = 0; i < _probe_depth; i++) { - entry = entry_at(probe + i); -@@ -600,6 +584,12 @@ - entry->fill(method, bci); - entry_for->resource_copy(entry); - assert(!entry_for->is_empty(), "A non-empty oop map should be returned"); -+ if (method->is_old()) { -+ // The caller of lookup() will receive a copy of the interesting -+ // info via entry_for, but we don't keep an old redefined method in -+ // the cache to avoid pinning down the method. -+ entry->flush(); -+ } - return; - } - } -@@ -633,6 +623,13 @@ - } - assert(!entry_for->is_empty(), "A non-empty oop map should be returned"); - -+ if (method->is_old()) { -+ // The caller of lookup() will receive a copy of the interesting -+ // info via entry_for, but we don't keep an old redefined method in -+ // the cache to avoid pinning down the method. -+ entry->flush(); -+ } -+ - return; - } - -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/oopMapCache.hpp openjdk/hotspot/src/share/vm/interpreter/oopMapCache.hpp ---- openjdk6/hotspot/src/share/vm/interpreter/oopMapCache.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/interpreter/oopMapCache.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)oopMapCache.hpp 1.57 07/05/05 17:05:39 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -191,4 +188,3 @@ - // Returns total no. of bytes allocated as part of OopMapCache's - static long memory_usage() PRODUCT_RETURN0; - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/rewriter.cpp openjdk/hotspot/src/share/vm/interpreter/rewriter.cpp ---- openjdk6/hotspot/src/share/vm/interpreter/rewriter.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/interpreter/rewriter.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)rewriter.cpp 1.45 07/05/05 17:05:40 JVM" --#endif - /* - * Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -189,7 +186,7 @@ - // will manifest itself in an easy recognizable form. - address bcp = original_method->bcp_from(0); - *bcp = (u1)Bytecodes::_shouldnotreachhere; -- int kind = AbstractInterpreter::method_kind(original_method); -+ int kind = Interpreter::method_kind(original_method); - original_method->set_interpreter_kind(kind); - } - -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/rewriter.hpp openjdk/hotspot/src/share/vm/interpreter/rewriter.hpp ---- openjdk6/hotspot/src/share/vm/interpreter/rewriter.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/interpreter/rewriter.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)rewriter.hpp 1.20 07/05/05 17:05:40 JVM" --#endif - /* - * Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -38,4 +35,3 @@ - public: - static void rewrite(instanceKlassHandle klass, TRAPS); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/templateInterpreter.cpp openjdk/hotspot/src/share/vm/interpreter/templateInterpreter.cpp ---- openjdk6/hotspot/src/share/vm/interpreter/templateInterpreter.cpp 1970-01-01 01:00:00.000000000 +0100 -+++ openjdk/hotspot/src/share/vm/interpreter/templateInterpreter.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -0,0 +1,597 @@ -+/* -+ * Copyright 1997-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, -+ * CA 95054 USA or visit www.sun.com if you need additional information or -+ * have any questions. -+ * -+ */ -+ -+#include "incls/_precompiled.incl" -+#include "incls/_templateInterpreter.cpp.incl" -+ -+#ifndef CC_INTERP -+ -+# define __ _masm-> -+ -+void TemplateInterpreter::initialize() { -+ if (_code != NULL) return; -+ // assertions -+ assert((int)Bytecodes::number_of_codes <= (int)DispatchTable::length, -+ "dispatch table too small"); -+ -+ AbstractInterpreter::initialize(); -+ -+ TemplateTable::initialize(); -+ -+ // generate interpreter -+ { ResourceMark rm; -+ TraceTime timer("Interpreter generation", TraceStartupTime); -+ int code_size = InterpreterCodeSize; -+ NOT_PRODUCT(code_size *= 4;) // debug uses extra interpreter code space -+ _code = new StubQueue(new InterpreterCodeletInterface, code_size, NULL, -+ "Interpreter"); -+ InterpreterGenerator g(_code); -+ if (PrintInterpreter) print(); -+ } -+ -+ // initialize dispatch table -+ _active_table = _normal_table; -+} -+ -+//------------------------------------------------------------------------------------------------------------------------ -+// Implementation of EntryPoint -+ -+EntryPoint::EntryPoint() { -+ assert(number_of_states == 9, "check the code below"); -+ _entry[btos] = NULL; -+ _entry[ctos] = NULL; -+ _entry[stos] = NULL; -+ _entry[atos] = NULL; -+ _entry[itos] = NULL; -+ _entry[ltos] = NULL; -+ _entry[ftos] = NULL; -+ _entry[dtos] = NULL; -+ _entry[vtos] = NULL; -+} -+ -+ -+EntryPoint::EntryPoint(address bentry, address centry, address sentry, address aentry, address ientry, address lentry, address fentry, address dentry, address ventry) { -+ assert(number_of_states == 9, "check the code below"); -+ _entry[btos] = bentry; -+ _entry[ctos] = centry; -+ _entry[stos] = sentry; -+ _entry[atos] = aentry; -+ _entry[itos] = ientry; -+ _entry[ltos] = lentry; -+ _entry[ftos] = fentry; -+ _entry[dtos] = dentry; -+ _entry[vtos] = ventry; -+} -+ -+ -+void EntryPoint::set_entry(TosState state, address entry) { -+ assert(0 <= state && state < number_of_states, "state out of bounds"); -+ _entry[state] = entry; -+} -+ -+ -+address EntryPoint::entry(TosState state) const { -+ assert(0 <= state && state < number_of_states, "state out of bounds"); -+ return _entry[state]; -+} -+ -+ -+void EntryPoint::print() { -+ tty->print("["); -+ for (int i = 0; i < number_of_states; i++) { -+ if (i > 0) tty->print(", "); -+ tty->print(INTPTR_FORMAT, _entry[i]); -+ } -+ tty->print("]"); -+} -+ -+ -+bool EntryPoint::operator == (const EntryPoint& y) { -+ int i = number_of_states; -+ while (i-- > 0) { -+ if (_entry[i] != y._entry[i]) return false; -+ } -+ return true; -+} -+ -+ -+//------------------------------------------------------------------------------------------------------------------------ -+// Implementation of DispatchTable -+ -+EntryPoint DispatchTable::entry(int i) const { -+ assert(0 <= i && i < length, "index out of bounds"); -+ return -+ EntryPoint( -+ _table[btos][i], -+ _table[ctos][i], -+ _table[stos][i], -+ _table[atos][i], -+ _table[itos][i], -+ _table[ltos][i], -+ _table[ftos][i], -+ _table[dtos][i], -+ _table[vtos][i] -+ ); -+} -+ -+ -+void DispatchTable::set_entry(int i, EntryPoint& entry) { -+ assert(0 <= i && i < length, "index out of bounds"); -+ assert(number_of_states == 9, "check the code below"); -+ _table[btos][i] = entry.entry(btos); -+ _table[ctos][i] = entry.entry(ctos); -+ _table[stos][i] = entry.entry(stos); -+ _table[atos][i] = entry.entry(atos); -+ _table[itos][i] = entry.entry(itos); -+ _table[ltos][i] = entry.entry(ltos); -+ _table[ftos][i] = entry.entry(ftos); -+ _table[dtos][i] = entry.entry(dtos); -+ _table[vtos][i] = entry.entry(vtos); -+} -+ -+ -+bool DispatchTable::operator == (DispatchTable& y) { -+ int i = length; -+ while (i-- > 0) { -+ EntryPoint t = y.entry(i); // for compiler compatibility (BugId 4150096) -+ if (!(entry(i) == t)) return false; -+ } -+ return true; -+} -+ -+address TemplateInterpreter::_remove_activation_entry = NULL; -+address TemplateInterpreter::_remove_activation_preserving_args_entry = NULL; -+ -+ -+address TemplateInterpreter::_throw_ArrayIndexOutOfBoundsException_entry = NULL; -+address TemplateInterpreter::_throw_ArrayStoreException_entry = NULL; -+address TemplateInterpreter::_throw_ArithmeticException_entry = NULL; -+address TemplateInterpreter::_throw_ClassCastException_entry = NULL; -+address TemplateInterpreter::_throw_NullPointerException_entry = NULL; -+address TemplateInterpreter::_throw_StackOverflowError_entry = NULL; -+address TemplateInterpreter::_throw_exception_entry = NULL; -+ -+#ifndef PRODUCT -+EntryPoint TemplateInterpreter::_trace_code; -+#endif // !PRODUCT -+EntryPoint TemplateInterpreter::_return_entry[TemplateInterpreter::number_of_return_entries]; -+EntryPoint TemplateInterpreter::_earlyret_entry; -+EntryPoint TemplateInterpreter::_deopt_entry [TemplateInterpreter::number_of_deopt_entries ]; -+EntryPoint TemplateInterpreter::_continuation_entry; -+EntryPoint TemplateInterpreter::_safept_entry; -+ -+address TemplateInterpreter::_return_3_addrs_by_index[TemplateInterpreter::number_of_return_addrs]; -+address TemplateInterpreter::_return_5_addrs_by_index[TemplateInterpreter::number_of_return_addrs]; -+ -+DispatchTable TemplateInterpreter::_active_table; -+DispatchTable TemplateInterpreter::_normal_table; -+DispatchTable TemplateInterpreter::_safept_table; -+address TemplateInterpreter::_wentry_point[DispatchTable::length]; -+ -+TemplateInterpreterGenerator::TemplateInterpreterGenerator(StubQueue* _code): AbstractInterpreterGenerator(_code) { -+ _unimplemented_bytecode = NULL; -+ _illegal_bytecode_sequence = NULL; -+} -+ -+static const BasicType types[Interpreter::number_of_result_handlers] = { -+ T_BOOLEAN, -+ T_CHAR , -+ T_BYTE , -+ T_SHORT , -+ T_INT , -+ T_LONG , -+ T_VOID , -+ T_FLOAT , -+ T_DOUBLE , -+ T_OBJECT -+}; -+ -+void TemplateInterpreterGenerator::generate_all() { -+ AbstractInterpreterGenerator::generate_all(); -+ -+ { CodeletMark cm(_masm, "error exits"); -+ _unimplemented_bytecode = generate_error_exit("unimplemented bytecode"); -+ _illegal_bytecode_sequence = generate_error_exit("illegal bytecode sequence - method not verified"); -+ } -+ -+#ifndef PRODUCT -+ if (TraceBytecodes) { -+ CodeletMark cm(_masm, "bytecode tracing support"); -+ Interpreter::_trace_code = -+ EntryPoint( -+ generate_trace_code(btos), -+ generate_trace_code(ctos), -+ generate_trace_code(stos), -+ generate_trace_code(atos), -+ generate_trace_code(itos), -+ generate_trace_code(ltos), -+ generate_trace_code(ftos), -+ generate_trace_code(dtos), -+ generate_trace_code(vtos) -+ ); -+ } -+#endif // !PRODUCT -+ -+ { CodeletMark cm(_masm, "return entry points"); -+ for (int i = 0; i < Interpreter::number_of_return_entries; i++) { -+ Interpreter::_return_entry[i] = -+ EntryPoint( -+ generate_return_entry_for(itos, i), -+ generate_return_entry_for(itos, i), -+ generate_return_entry_for(itos, i), -+ generate_return_entry_for(atos, i), -+ generate_return_entry_for(itos, i), -+ generate_return_entry_for(ltos, i), -+ generate_return_entry_for(ftos, i), -+ generate_return_entry_for(dtos, i), -+ generate_return_entry_for(vtos, i) -+ ); -+ } -+ } -+ -+ { CodeletMark cm(_masm, "earlyret entry points"); -+ Interpreter::_earlyret_entry = -+ EntryPoint( -+ generate_earlyret_entry_for(btos), -+ generate_earlyret_entry_for(ctos), -+ generate_earlyret_entry_for(stos), -+ generate_earlyret_entry_for(atos), -+ generate_earlyret_entry_for(itos), -+ generate_earlyret_entry_for(ltos), -+ generate_earlyret_entry_for(ftos), -+ generate_earlyret_entry_for(dtos), -+ generate_earlyret_entry_for(vtos) -+ ); -+ } -+ -+ { CodeletMark cm(_masm, "deoptimization entry points"); -+ for (int i = 0; i < Interpreter::number_of_deopt_entries; i++) { -+ Interpreter::_deopt_entry[i] = -+ EntryPoint( -+ generate_deopt_entry_for(itos, i), -+ generate_deopt_entry_for(itos, i), -+ generate_deopt_entry_for(itos, i), -+ generate_deopt_entry_for(atos, i), -+ generate_deopt_entry_for(itos, i), -+ generate_deopt_entry_for(ltos, i), -+ generate_deopt_entry_for(ftos, i), -+ generate_deopt_entry_for(dtos, i), -+ generate_deopt_entry_for(vtos, i) -+ ); -+ } -+ } -+ -+ { CodeletMark cm(_masm, "result handlers for native calls"); -+ // The various result converter stublets. -+ int is_generated[Interpreter::number_of_result_handlers]; -+ memset(is_generated, 0, sizeof(is_generated)); -+ -+ for (int i = 0; i < Interpreter::number_of_result_handlers; i++) { -+ BasicType type = types[i]; -+ if (!is_generated[Interpreter::BasicType_as_index(type)]++) { -+ Interpreter::_native_abi_to_tosca[Interpreter::BasicType_as_index(type)] = generate_result_handler_for(type); -+ } -+ } -+ } -+ -+ for (int j = 0; j < number_of_states; j++) { -+ const TosState states[] = {btos, ctos, stos, itos, ltos, ftos, dtos, atos, vtos}; -+ Interpreter::_return_3_addrs_by_index[Interpreter::TosState_as_index(states[j])] = Interpreter::return_entry(states[j], 3); -+ Interpreter::_return_5_addrs_by_index[Interpreter::TosState_as_index(states[j])] = Interpreter::return_entry(states[j], 5); -+ } -+ -+ { CodeletMark cm(_masm, "continuation entry points"); -+ Interpreter::_continuation_entry = -+ EntryPoint( -+ generate_continuation_for(btos), -+ generate_continuation_for(ctos), -+ generate_continuation_for(stos), -+ generate_continuation_for(atos), -+ generate_continuation_for(itos), -+ generate_continuation_for(ltos), -+ generate_continuation_for(ftos), -+ generate_continuation_for(dtos), -+ generate_continuation_for(vtos) -+ ); -+ } -+ -+ { CodeletMark cm(_masm, "safepoint entry points"); -+ Interpreter::_safept_entry = -+ EntryPoint( -+ generate_safept_entry_for(btos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), -+ generate_safept_entry_for(ctos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), -+ generate_safept_entry_for(stos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), -+ generate_safept_entry_for(atos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), -+ generate_safept_entry_for(itos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), -+ generate_safept_entry_for(ltos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), -+ generate_safept_entry_for(ftos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), -+ generate_safept_entry_for(dtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)), -+ generate_safept_entry_for(vtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)) -+ ); -+ } -+ -+ { CodeletMark cm(_masm, "exception handling"); -+ // (Note: this is not safepoint safe because thread may return to compiled code) -+ generate_throw_exception(); -+ } -+ -+ { CodeletMark cm(_masm, "throw exception entrypoints"); -+ Interpreter::_throw_ArrayIndexOutOfBoundsException_entry = generate_ArrayIndexOutOfBounds_handler("java/lang/ArrayIndexOutOfBoundsException"); -+ Interpreter::_throw_ArrayStoreException_entry = generate_klass_exception_handler("java/lang/ArrayStoreException" ); -+ Interpreter::_throw_ArithmeticException_entry = generate_exception_handler("java/lang/ArithmeticException" , "/ by zero"); -+ Interpreter::_throw_ClassCastException_entry = generate_ClassCastException_handler(); -+ Interpreter::_throw_NullPointerException_entry = generate_exception_handler("java/lang/NullPointerException" , NULL ); -+ Interpreter::_throw_StackOverflowError_entry = generate_StackOverflowError_handler(); -+ } -+ -+ -+ -+#define method_entry(kind) \ -+ { CodeletMark cm(_masm, "method entry point (kind = " #kind ")"); \ -+ Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind); \ -+ } -+ -+ // all non-native method kinds -+ method_entry(zerolocals) -+ method_entry(zerolocals_synchronized) -+ method_entry(empty) -+ method_entry(accessor) -+ method_entry(abstract) -+ method_entry(java_lang_math_sin ) -+ method_entry(java_lang_math_cos ) -+ method_entry(java_lang_math_tan ) -+ method_entry(java_lang_math_abs ) -+ method_entry(java_lang_math_sqrt ) -+ method_entry(java_lang_math_log ) -+ method_entry(java_lang_math_log10) -+ -+ // all native method kinds (must be one contiguous block) -+ Interpreter::_native_entry_begin = Interpreter::code()->code_end(); -+ method_entry(native) -+ method_entry(native_synchronized) -+ Interpreter::_native_entry_end = Interpreter::code()->code_end(); -+ -+#undef method_entry -+ -+ // Bytecodes -+ set_entry_points_for_all_bytes(); -+ set_safepoints_for_all_bytes(); -+} -+ -+//------------------------------------------------------------------------------------------------------------------------ -+ -+address TemplateInterpreterGenerator::generate_error_exit(const char* msg) { -+ address entry = __ pc(); -+ __ stop(msg); -+ return entry; -+} -+ -+ -+//------------------------------------------------------------------------------------------------------------------------ -+ -+void TemplateInterpreterGenerator::set_entry_points_for_all_bytes() { -+ for (int i = 0; i < DispatchTable::length; i++) { -+ Bytecodes::Code code = (Bytecodes::Code)i; -+ if (Bytecodes::is_defined(code)) { -+ set_entry_points(code); -+ } else { -+ set_unimplemented(i); -+ } -+ } -+} -+ -+ -+void TemplateInterpreterGenerator::set_safepoints_for_all_bytes() { -+ for (int i = 0; i < DispatchTable::length; i++) { -+ Bytecodes::Code code = (Bytecodes::Code)i; -+ if (Bytecodes::is_defined(code)) Interpreter::_safept_table.set_entry(code, Interpreter::_safept_entry); -+ } -+} -+ -+ -+void TemplateInterpreterGenerator::set_unimplemented(int i) { -+ address e = _unimplemented_bytecode; -+ EntryPoint entry(e, e, e, e, e, e, e, e, e); -+ Interpreter::_normal_table.set_entry(i, entry); -+ Interpreter::_wentry_point[i] = _unimplemented_bytecode; -+} -+ -+ -+void TemplateInterpreterGenerator::set_entry_points(Bytecodes::Code code) { -+ CodeletMark cm(_masm, Bytecodes::name(code), code); -+ // initialize entry points -+ assert(_unimplemented_bytecode != NULL, "should have been generated before"); -+ assert(_illegal_bytecode_sequence != NULL, "should have been generated before"); -+ address bep = _illegal_bytecode_sequence; -+ address cep = _illegal_bytecode_sequence; -+ address sep = _illegal_bytecode_sequence; -+ address aep = _illegal_bytecode_sequence; -+ address iep = _illegal_bytecode_sequence; -+ address lep = _illegal_bytecode_sequence; -+ address fep = _illegal_bytecode_sequence; -+ address dep = _illegal_bytecode_sequence; -+ address vep = _unimplemented_bytecode; -+ address wep = _unimplemented_bytecode; -+ // code for short & wide version of bytecode -+ if (Bytecodes::is_defined(code)) { -+ Template* t = TemplateTable::template_for(code); -+ assert(t->is_valid(), "just checking"); -+ set_short_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep); -+ } -+ if (Bytecodes::wide_is_defined(code)) { -+ Template* t = TemplateTable::template_for_wide(code); -+ assert(t->is_valid(), "just checking"); -+ set_wide_entry_point(t, wep); -+ } -+ // set entry points -+ EntryPoint entry(bep, cep, sep, aep, iep, lep, fep, dep, vep); -+ Interpreter::_normal_table.set_entry(code, entry); -+ Interpreter::_wentry_point[code] = wep; -+} -+ -+ -+void TemplateInterpreterGenerator::set_wide_entry_point(Template* t, address& wep) { -+ assert(t->is_valid(), "template must exist"); -+ assert(t->tos_in() == vtos, "only vtos tos_in supported for wide instructions") -+ wep = __ pc(); generate_and_dispatch(t); -+} -+ -+ -+void TemplateInterpreterGenerator::set_short_entry_points(Template* t, address& bep, address& cep, address& sep, address& aep, address& iep, address& lep, address& fep, address& dep, address& vep) { -+ assert(t->is_valid(), "template must exist"); -+ switch (t->tos_in()) { -+ case btos: vep = __ pc(); __ pop(btos); bep = __ pc(); generate_and_dispatch(t); break; -+ case ctos: vep = __ pc(); __ pop(ctos); sep = __ pc(); generate_and_dispatch(t); break; -+ case stos: vep = __ pc(); __ pop(stos); sep = __ pc(); generate_and_dispatch(t); break; -+ case atos: vep = __ pc(); __ pop(atos); aep = __ pc(); generate_and_dispatch(t); break; -+ case itos: vep = __ pc(); __ pop(itos); iep = __ pc(); generate_and_dispatch(t); break; -+ case ltos: vep = __ pc(); __ pop(ltos); lep = __ pc(); generate_and_dispatch(t); break; -+ case ftos: vep = __ pc(); __ pop(ftos); fep = __ pc(); generate_and_dispatch(t); break; -+ case dtos: vep = __ pc(); __ pop(dtos); dep = __ pc(); generate_and_dispatch(t); break; -+ case vtos: set_vtos_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep); break; -+ default : ShouldNotReachHere(); break; -+ } -+} -+ -+ -+//------------------------------------------------------------------------------------------------------------------------ -+ -+void TemplateInterpreterGenerator::generate_and_dispatch(Template* t, TosState tos_out) { -+ if (PrintBytecodeHistogram) histogram_bytecode(t); -+#ifndef PRODUCT -+ // debugging code -+ if (CountBytecodes || TraceBytecodes || StopInterpreterAt > 0) count_bytecode(); -+ if (PrintBytecodePairHistogram) histogram_bytecode_pair(t); -+ if (TraceBytecodes) trace_bytecode(t); -+ if (StopInterpreterAt > 0) stop_interpreter_at(); -+ __ verify_FPU(1, t->tos_in()); -+#endif // !PRODUCT -+ int step; -+ if (!t->does_dispatch()) { -+ step = t->is_wide() ? Bytecodes::wide_length_for(t->bytecode()) : Bytecodes::length_for(t->bytecode()); -+ if (tos_out == ilgl) tos_out = t->tos_out(); -+ // compute bytecode size -+ assert(step > 0, "just checkin'"); -+ // setup stuff for dispatching next bytecode -+ if (ProfileInterpreter && VerifyDataPointer -+ && methodDataOopDesc::bytecode_has_profile(t->bytecode())) { -+ __ verify_method_data_pointer(); -+ } -+ __ dispatch_prolog(tos_out, step); -+ } -+ // generate template -+ t->generate(_masm); -+ // advance -+ if (t->does_dispatch()) { -+#ifdef ASSERT -+ // make sure execution doesn't go beyond this point if code is broken -+ __ should_not_reach_here(); -+#endif // ASSERT -+ } else { -+ // dispatch to next bytecode -+ __ dispatch_epilog(tos_out, step); -+ } -+} -+ -+//------------------------------------------------------------------------------------------------------------------------ -+// Entry points -+ -+address TemplateInterpreter::return_entry(TosState state, int length) { -+ guarantee(0 <= length && length < Interpreter::number_of_return_entries, "illegal length"); -+ return _return_entry[length].entry(state); -+} -+ -+ -+address TemplateInterpreter::deopt_entry(TosState state, int length) { -+ guarantee(0 <= length && length < Interpreter::number_of_deopt_entries, "illegal length"); -+ return _deopt_entry[length].entry(state); -+} -+ -+//------------------------------------------------------------------------------------------------------------------------ -+// Suport for invokes -+ -+int TemplateInterpreter::TosState_as_index(TosState state) { -+ assert( state < number_of_states , "Invalid state in TosState_as_index"); -+ assert(0 <= (int)state && (int)state < TemplateInterpreter::number_of_return_addrs, "index out of bounds"); -+ return (int)state; -+} -+ -+ -+//------------------------------------------------------------------------------------------------------------------------ -+// Safepoint suppport -+ -+static inline void copy_table(address* from, address* to, int size) { -+ // Copy non-overlapping tables. The copy has to occur word wise for MT safety. -+ while (size-- > 0) *to++ = *from++; -+} -+ -+void TemplateInterpreter::notice_safepoints() { -+ if (!_notice_safepoints) { -+ // switch to safepoint dispatch table -+ _notice_safepoints = true; -+ copy_table((address*)&_safept_table, (address*)&_active_table, sizeof(_active_table) / sizeof(address)); -+ } -+} -+ -+// switch from the dispatch table which notices safepoints back to the -+// normal dispatch table. So that we can notice single stepping points, -+// keep the safepoint dispatch table if we are single stepping in JVMTI. -+// Note that the should_post_single_step test is exactly as fast as the -+// JvmtiExport::_enabled test and covers both cases. -+void TemplateInterpreter::ignore_safepoints() { -+ if (_notice_safepoints) { -+ if (!JvmtiExport::should_post_single_step()) { -+ // switch to normal dispatch table -+ _notice_safepoints = false; -+ copy_table((address*)&_normal_table, (address*)&_active_table, sizeof(_active_table) / sizeof(address)); -+ } -+ } -+} -+ -+// If deoptimization happens, this method returns the point where to continue in -+// interpreter. For calls (invokexxxx, newxxxx) the continuation is at next -+// bci and the top of stack is in eax/edx/FPU tos. -+// For putfield/getfield, put/getstatic, the continuation is at the same -+// bci and the TOS is on stack. -+ -+// Note: deopt_entry(type, 0) means reexecute bytecode -+// deopt_entry(type, length) means continue at next bytecode -+ -+address TemplateInterpreter::continuation_for(methodOop method, address bcp, int callee_parameters, bool is_top_frame, bool& use_next_mdp) { -+ assert(method->contains(bcp), "just checkin'"); -+ Bytecodes::Code code = Bytecodes::java_code_at(bcp); -+ if (code == Bytecodes::_return) { -+ // This is used for deopt during registration of finalizers -+ // during Object.. We simply need to resume execution at -+ // the standard return vtos bytecode to pop the frame normally. -+ // reexecuting the real bytecode would cause double registration -+ // of the finalizable object. -+ assert(is_top_frame, "must be on top"); -+ return _normal_table.entry(Bytecodes::_return).entry(vtos); -+ } else { -+ return AbstractInterpreter::continuation_for(method, bcp, callee_parameters, is_top_frame, use_next_mdp); -+ } -+} -+ -+#endif // !CC_INTERP -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/templateInterpreter.hpp openjdk/hotspot/src/share/vm/interpreter/templateInterpreter.hpp ---- openjdk6/hotspot/src/share/vm/interpreter/templateInterpreter.hpp 1970-01-01 01:00:00.000000000 +0100 -+++ openjdk/hotspot/src/share/vm/interpreter/templateInterpreter.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -0,0 +1,177 @@ -+/* -+ * Copyright 1997-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, -+ * CA 95054 USA or visit www.sun.com if you need additional information or -+ * have any questions. -+ * -+ */ -+ -+// This file contains the platform-independant parts -+// of the template interpreter and the template interpreter generator. -+ -+#ifndef CC_INTERP -+ -+//------------------------------------------------------------------------------------------------------------------------ -+// A little wrapper class to group tosca-specific entry points into a unit. -+// (tosca = Top-Of-Stack CAche) -+ -+class EntryPoint VALUE_OBJ_CLASS_SPEC { -+ private: -+ address _entry[number_of_states]; -+ -+ public: -+ // Construction -+ EntryPoint(); -+ EntryPoint(address bentry, address centry, address sentry, address aentry, address ientry, address lentry, address fentry, address dentry, address ventry); -+ -+ // Attributes -+ address entry(TosState state) const; // return target address for a given tosca state -+ void set_entry(TosState state, address entry); // set target address for a given tosca state -+ void print(); -+ -+ // Comparison -+ bool operator == (const EntryPoint& y); // for debugging only -+}; -+ -+ -+//------------------------------------------------------------------------------------------------------------------------ -+// A little wrapper class to group tosca-specific dispatch tables into a unit. -+ -+class DispatchTable VALUE_OBJ_CLASS_SPEC { -+ public: -+ enum { length = 1 << BitsPerByte }; // an entry point for each byte value (also for undefined bytecodes) -+ -+ private: -+ address _table[number_of_states][length]; // dispatch tables, indexed by tosca and bytecode -+ -+ public: -+ // Attributes -+ EntryPoint entry(int i) const; // return entry point for a given bytecode i -+ void set_entry(int i, EntryPoint& entry); // set entry point for a given bytecode i -+ address* table_for(TosState state) { return _table[state]; } -+ address* table_for() { return table_for((TosState)0); } -+ int distance_from(address *table) { return table - table_for(); } -+ int distance_from(TosState state) { return distance_from(table_for(state)); } -+ -+ // Comparison -+ bool operator == (DispatchTable& y); // for debugging only -+}; -+ -+class TemplateInterpreter: public AbstractInterpreter { -+ friend class VMStructs; -+ friend class InterpreterMacroAssembler; -+ friend class TemplateInterpreterGenerator; -+ friend class TemplateTable; -+ // friend class Interpreter; -+ public: -+ -+ enum MoreConstants { -+ number_of_return_entries = 9, // number of return entry points -+ number_of_deopt_entries = 9, // number of deoptimization entry points -+ number_of_return_addrs = 9 // number of return addresses -+ }; -+ -+ protected: -+ -+ static address _throw_ArrayIndexOutOfBoundsException_entry; -+ static address _throw_ArrayStoreException_entry; -+ static address _throw_ArithmeticException_entry; -+ static address _throw_ClassCastException_entry; -+ static address _throw_NullPointerException_entry; -+ static address _throw_exception_entry; -+ -+ static address _throw_StackOverflowError_entry; -+ -+ static address _remove_activation_entry; // continuation address if an exception is not handled by current frame -+#ifdef HOTSWAP -+ static address _remove_activation_preserving_args_entry; // continuation address when current frame is being popped -+#endif // HOTSWAP -+ -+#ifndef PRODUCT -+ static EntryPoint _trace_code; -+#endif // !PRODUCT -+ static EntryPoint _return_entry[number_of_return_entries]; // entry points to return to from a call -+ static EntryPoint _earlyret_entry; // entry point to return early from a call -+ static EntryPoint _deopt_entry[number_of_deopt_entries]; // entry points to return to from a deoptimization -+ static EntryPoint _continuation_entry; -+ static EntryPoint _safept_entry; -+ -+ static address _return_3_addrs_by_index[number_of_return_addrs]; // for invokevirtual return entries -+ static address _return_5_addrs_by_index[number_of_return_addrs]; // for invokeinterface return entries -+ -+ static DispatchTable _active_table; // the active dispatch table (used by the interpreter for dispatch) -+ static DispatchTable _normal_table; // the normal dispatch table (used to set the active table in normal mode) -+ static DispatchTable _safept_table; // the safepoint dispatch table (used to set the active table for safepoints) -+ static address _wentry_point[DispatchTable::length]; // wide instructions only (vtos tosca always) -+ -+ -+ public: -+ // Initialization/debugging -+ static void initialize(); -+ // this only returns whether a pc is within generated code for the interpreter. -+ static bool contains(address pc) { return _code != NULL && _code->contains(pc); } -+ -+ public: -+ -+ static address remove_activation_early_entry(TosState state) { return _earlyret_entry.entry(state); } -+#ifdef HOTSWAP -+ static address remove_activation_preserving_args_entry() { return _remove_activation_preserving_args_entry; } -+#endif // HOTSWAP -+ -+ static address remove_activation_entry() { return _remove_activation_entry; } -+ static address throw_exception_entry() { return _throw_exception_entry; } -+ static address throw_ArithmeticException_entry() { return _throw_ArithmeticException_entry; } -+ static address throw_NullPointerException_entry() { return _throw_NullPointerException_entry; } -+ static address throw_StackOverflowError_entry() { return _throw_StackOverflowError_entry; } -+ -+ // Code generation -+#ifndef PRODUCT -+ static address trace_code (TosState state) { return _trace_code.entry(state); } -+#endif // !PRODUCT -+ static address continuation (TosState state) { return _continuation_entry.entry(state); } -+ static address* dispatch_table(TosState state) { return _active_table.table_for(state); } -+ static address* dispatch_table() { return _active_table.table_for(); } -+ static int distance_from_dispatch_table(TosState state){ return _active_table.distance_from(state); } -+ static address* normal_table(TosState state) { return _normal_table.table_for(state); } -+ static address* normal_table() { return _normal_table.table_for(); } -+ -+ // Support for invokes -+ static address* return_3_addrs_by_index_table() { return _return_3_addrs_by_index; } -+ static address* return_5_addrs_by_index_table() { return _return_5_addrs_by_index; } -+ static int TosState_as_index(TosState state); // computes index into return_3_entry_by_index table -+ -+ static address return_entry (TosState state, int length); -+ static address deopt_entry (TosState state, int length); -+ -+ // Safepoint support -+ static void notice_safepoints(); // stops the thread when reaching a safepoint -+ static void ignore_safepoints(); // ignores safepoints -+ -+ // Deoptimization support -+ static address continuation_for(methodOop method, -+ address bcp, -+ int callee_parameters, -+ bool is_top_frame, -+ bool& use_next_mdp); -+ -+#include "incls/_templateInterpreter_pd.hpp.incl" -+ -+}; -+ -+#endif // !CC_INTERP -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/templateInterpreterGenerator.hpp openjdk/hotspot/src/share/vm/interpreter/templateInterpreterGenerator.hpp ---- openjdk6/hotspot/src/share/vm/interpreter/templateInterpreterGenerator.hpp 1970-01-01 01:00:00.000000000 +0100 -+++ openjdk/hotspot/src/share/vm/interpreter/templateInterpreterGenerator.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -0,0 +1,90 @@ -+/* -+ * Copyright 1997-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, -+ * CA 95054 USA or visit www.sun.com if you need additional information or -+ * have any questions. -+ * -+ */ -+ -+// This file contains the platform-independant parts -+// of the template interpreter generator. -+ -+#ifndef CC_INTERP -+ -+class TemplateInterpreterGenerator: public AbstractInterpreterGenerator { -+ protected: -+ -+ // entry points for shared code sequence -+ address _unimplemented_bytecode; -+ address _illegal_bytecode_sequence; -+ -+ // shared code sequences -+ // Converter for native abi result to tosca result -+ address generate_result_handler_for(BasicType type); -+ address generate_slow_signature_handler(); -+ address generate_error_exit(const char* msg); -+ address generate_StackOverflowError_handler(); -+ address generate_exception_handler(const char* name, const char* message) { -+ return generate_exception_handler_common(name, message, false); -+ } -+ address generate_klass_exception_handler(const char* name) { -+ return generate_exception_handler_common(name, NULL, true); -+ } -+ address generate_exception_handler_common(const char* name, const char* message, bool pass_oop); -+ address generate_ClassCastException_handler(); -+ address generate_ArrayIndexOutOfBounds_handler(const char* name); -+ address generate_continuation_for(TosState state); -+ address generate_return_entry_for(TosState state, int step); -+ address generate_earlyret_entry_for(TosState state); -+ address generate_deopt_entry_for(TosState state, int step); -+ address generate_safept_entry_for(TosState state, address runtime_entry); -+ void generate_throw_exception(); -+ -+ // entry point generator -+// address generate_method_entry(AbstractInterpreter::MethodKind kind); -+ -+ // Instruction generation -+ void generate_and_dispatch (Template* t, TosState tos_out = ilgl); -+ void set_vtos_entry_points (Template* t, address& bep, address& cep, address& sep, address& aep, address& iep, address& lep, address& fep, address& dep, address& vep); -+ void set_short_entry_points(Template* t, address& bep, address& cep, address& sep, address& aep, address& iep, address& lep, address& fep, address& dep, address& vep); -+ void set_wide_entry_point (Template* t, address& wep); -+ -+ void set_entry_points(Bytecodes::Code code); -+ void set_unimplemented(int i); -+ void set_entry_points_for_all_bytes(); -+ void set_safepoints_for_all_bytes(); -+ -+ // Helpers for generate_and_dispatch -+ address generate_trace_code(TosState state) PRODUCT_RETURN0; -+ void count_bytecode() PRODUCT_RETURN; -+ void histogram_bytecode(Template* t) PRODUCT_RETURN; -+ void histogram_bytecode_pair(Template* t) PRODUCT_RETURN; -+ void trace_bytecode(Template* t) PRODUCT_RETURN; -+ void stop_interpreter_at() PRODUCT_RETURN; -+ -+ void generate_all(); -+ -+ public: -+ TemplateInterpreterGenerator(StubQueue* _code); -+ -+ #include "incls/_templateInterpreterGenerator_pd.hpp.incl" -+ -+}; -+ -+#endif // !CC_INTERP -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/templateTable.cpp openjdk/hotspot/src/share/vm/interpreter/templateTable.cpp ---- openjdk6/hotspot/src/share/vm/interpreter/templateTable.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/interpreter/templateTable.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)templateTable.cpp 1.108 07/05/05 17:05:37 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/interpreter/templateTable.hpp openjdk/hotspot/src/share/vm/interpreter/templateTable.hpp ---- openjdk6/hotspot/src/share/vm/interpreter/templateTable.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/interpreter/templateTable.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)templateTable.hpp 1.91 07/05/05 17:05:39 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/libadt/dict.cpp openjdk/hotspot/src/share/vm/libadt/dict.cpp ---- openjdk6/hotspot/src/share/vm/libadt/dict.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/libadt/dict.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)dict.cpp 1.35 07/05/05 17:05:41 JVM" --#endif - /* - * Copyright 1997-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -384,4 +381,3 @@ - } - _key = _value = NULL; - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/libadt/dict.hpp openjdk/hotspot/src/share/vm/libadt/dict.hpp ---- openjdk6/hotspot/src/share/vm/libadt/dict.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/libadt/dict.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)dict.hpp 1.24 07/05/05 17:05:40 JVM" --#endif - /* - * Copyright 1997-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -118,4 +115,3 @@ - }; - - #endif // _DICT_ -- -diff -ruNb openjdk6/hotspot/src/share/vm/libadt/port.cpp openjdk/hotspot/src/share/vm/libadt/port.cpp ---- openjdk6/hotspot/src/share/vm/libadt/port.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/libadt/port.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)port.cpp 1.21 07/05/05 17:05:41 JVM" --#endif - /* - * Copyright 1997-1998 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/libadt/port.hpp openjdk/hotspot/src/share/vm/libadt/port.hpp ---- openjdk6/hotspot/src/share/vm/libadt/port.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/libadt/port.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)port.hpp 1.44 07/05/05 17:05:41 JVM" --#endif - /* - * Copyright 1997-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/libadt/set.cpp openjdk/hotspot/src/share/vm/libadt/set.cpp ---- openjdk6/hotspot/src/share/vm/libadt/set.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/libadt/set.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)set.cpp 1.26 07/05/05 17:05:41 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/libadt/set.hpp openjdk/hotspot/src/share/vm/libadt/set.hpp ---- openjdk6/hotspot/src/share/vm/libadt/set.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/libadt/set.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)set.hpp 1.23 07/05/05 17:05:41 JVM" --#endif - /* - * Copyright 1997 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -252,4 +249,3 @@ - }; - - #endif // _SET_ -- -diff -ruNb openjdk6/hotspot/src/share/vm/libadt/vectset.cpp openjdk/hotspot/src/share/vm/libadt/vectset.cpp ---- openjdk6/hotspot/src/share/vm/libadt/vectset.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/libadt/vectset.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)vectset.cpp 1.25 07/05/05 17:05:41 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -391,5 +388,3 @@ - } while( isize ); - return max_juint; // No element, iterated them all - } -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/libadt/vectset.hpp openjdk/hotspot/src/share/vm/libadt/vectset.hpp ---- openjdk6/hotspot/src/share/vm/libadt/vectset.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/libadt/vectset.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)vectset.hpp 1.22 07/05/05 17:05:41 JVM" --#endif - /* - * Copyright 1997 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -177,4 +174,3 @@ - }; - - #endif // _VECTOR_SET_ -- -diff -ruNb openjdk6/hotspot/src/share/vm/memory/allocation.cpp openjdk/hotspot/src/share/vm/memory/allocation.cpp ---- openjdk6/hotspot/src/share/vm/memory/allocation.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/allocation.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)allocation.cpp 1.72 07/05/05 17:05:42 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -540,4 +537,3 @@ - } - - #endif // Non-product -- -diff -ruNb openjdk6/hotspot/src/share/vm/memory/allocation.hpp openjdk/hotspot/src/share/vm/memory/allocation.hpp ---- openjdk6/hotspot/src/share/vm/memory/allocation.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/allocation.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)allocation.hpp 1.77 07/05/05 17:05:42 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -410,4 +407,3 @@ - ReallocMark() PRODUCT_RETURN; - void check() PRODUCT_RETURN; - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/memory/allocation.inline.hpp openjdk/hotspot/src/share/vm/memory/allocation.inline.hpp ---- openjdk6/hotspot/src/share/vm/memory/allocation.inline.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/allocation.inline.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)allocation.inline.hpp 1.22 07/05/05 17:05:42 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/allocationStats.cpp openjdk/hotspot/src/share/vm/memory/allocationStats.cpp ---- openjdk6/hotspot/src/share/vm/memory/allocationStats.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/allocationStats.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)allocationStats.cpp 1.6 07/05/05 17:05:42 JVM" --#endif - /* - * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -31,4 +28,3 @@ - // Technically this should be derived from machine speed, and - // ideally it would be dynamically adjusted. - float AllocationStats::_threshold = ((float)CMS_SweepTimerThresholdMillis)/1000; -- -diff -ruNb openjdk6/hotspot/src/share/vm/memory/allocationStats.hpp openjdk/hotspot/src/share/vm/memory/allocationStats.hpp ---- openjdk6/hotspot/src/share/vm/memory/allocationStats.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/allocationStats.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)allocationStats.hpp 1.19 07/05/05 17:05:41 JVM" --#endif - /* - * Copyright 2001-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/barrierSet.hpp openjdk/hotspot/src/share/vm/memory/barrierSet.hpp ---- openjdk6/hotspot/src/share/vm/memory/barrierSet.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/barrierSet.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)barrierSet.hpp 1.18 07/05/05 17:05:43 JVM" --#endif - /* - * Copyright 2000-2002 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/barrierSet.inline.hpp openjdk/hotspot/src/share/vm/memory/barrierSet.inline.hpp ---- openjdk6/hotspot/src/share/vm/memory/barrierSet.inline.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/barrierSet.inline.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)barrierSet.inline.hpp 1.12 07/05/05 17:05:43 JVM" --#endif - /* - * Copyright 2001-2002 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/blockOffsetTable.cpp openjdk/hotspot/src/share/vm/memory/blockOffsetTable.cpp ---- openjdk6/hotspot/src/share/vm/memory/blockOffsetTable.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/blockOffsetTable.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)blockOffsetTable.cpp 1.82 07/05/05 17:05:42 JVM" --#endif - /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/blockOffsetTable.hpp openjdk/hotspot/src/share/vm/memory/blockOffsetTable.hpp ---- openjdk6/hotspot/src/share/vm/memory/blockOffsetTable.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/blockOffsetTable.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)blockOffsetTable.hpp 1.57 07/05/05 17:05:43 JVM" --#endif - /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/blockOffsetTable.inline.hpp openjdk/hotspot/src/share/vm/memory/blockOffsetTable.inline.hpp ---- openjdk6/hotspot/src/share/vm/memory/blockOffsetTable.inline.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/blockOffsetTable.inline.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)blockOffsetTable.inline.hpp 1.20 07/05/05 17:05:43 JVM" --#endif - /* - * Copyright 2000-2002 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/cardTableModRefBS.cpp openjdk/hotspot/src/share/vm/memory/cardTableModRefBS.cpp ---- openjdk6/hotspot/src/share/vm/memory/cardTableModRefBS.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/cardTableModRefBS.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)cardTableModRefBS.cpp 1.58 07/05/29 09:44:14 JVM" --#endif - /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -32,9 +29,30 @@ - # include "incls/_precompiled.incl" - # include "incls/_cardTableModRefBS.cpp.incl" - -+size_t CardTableModRefBS::cards_required(size_t covered_words) -+{ -+ // Add one for a guard card, used to detect errors. -+ const size_t words = align_size_up(covered_words, card_size_in_words); -+ return words / card_size_in_words + 1; -+} -+ -+size_t CardTableModRefBS::compute_byte_map_size() -+{ -+ assert(_guard_index == cards_required(_whole_heap.word_size()) - 1, -+ "unitialized, check declaration order"); -+ assert(_page_size != 0, "unitialized, check declaration order"); -+ const size_t granularity = os::vm_allocation_granularity(); -+ return align_size_up(_guard_index + 1, MAX2(_page_size, granularity)); -+} -+ - CardTableModRefBS::CardTableModRefBS(MemRegion whole_heap, -- int max_covered_regions) : -- ModRefBarrierSet(max_covered_regions), _whole_heap(whole_heap) -+ int max_covered_regions): -+ ModRefBarrierSet(max_covered_regions), -+ _whole_heap(whole_heap), -+ _guard_index(cards_required(whole_heap.word_size()) - 1), -+ _last_valid_index(_guard_index - 1), -+ _page_size(os::page_size_for_region(_guard_index + 1, _guard_index + 1, 1)), -+ _byte_map_size(compute_byte_map_size()) - { - _kind = BarrierSet::CardTableModRef; - -@@ -43,14 +61,7 @@ - assert((uintptr_t(low_bound) & (card_size - 1)) == 0, "heap must start at card boundary"); - assert((uintptr_t(high_bound) & (card_size - 1)) == 0, "heap must end at card boundary"); - -- assert(card_size <= 512, "card_size must be less than 512"); -- size_t heap_size_in_words = _whole_heap.word_size(); -- // Add one for the last_card, treated as a guard card -- _byte_map_size = ReservedSpace::allocation_align_size_up((heap_size_in_words / -- card_size_in_words) + 1); -- // A couple of useful indicies -- _guard_index = _byte_map_size - 1; -- _last_valid_index = _byte_map_size - 2; -+ assert(card_size <= 512, "card_size must be less than 512"); // why? - - _covered = new MemRegion[max_covered_regions]; - _committed = new MemRegion[max_covered_regions]; -@@ -63,10 +74,16 @@ - } - _cur_covered_regions = 0; - -- ReservedSpace heap_rs(_byte_map_size); -+ const size_t rs_align = _page_size == (size_t) os::vm_page_size() ? 0 : -+ MAX2(_page_size, (size_t) os::vm_allocation_granularity()); -+ ReservedSpace heap_rs(_byte_map_size, rs_align, false); -+ os::trace_page_sizes("card table", _guard_index + 1, _guard_index + 1, -+ _page_size, heap_rs.base(), heap_rs.size()); - if (!heap_rs.is_reserved()) { -- vm_exit_during_initialization("Could not reserve enough space for card marking array"); -+ vm_exit_during_initialization("Could not reserve enough space for the " -+ "card marking array"); - } -+ - // The assember store_check code will do an unsigned shift of the oop, - // then add it to byte_map_base, i.e. - // -@@ -77,11 +94,11 @@ - assert(byte_for(high_bound-1) <= &_byte_map[_last_valid_index], "Checking end of map"); - - jbyte* guard_card = &_byte_map[_guard_index]; -- uintptr_t guard_page = align_size_down((uintptr_t)guard_card, os::vm_page_size()); -- _guard_region = MemRegion((HeapWord*)guard_page, os::vm_page_size()); -- if (!os::commit_memory((char*)guard_page, os::vm_page_size())) { -+ uintptr_t guard_page = align_size_down((uintptr_t)guard_card, _page_size); -+ _guard_region = MemRegion((HeapWord*)guard_page, _page_size); -+ if (!os::commit_memory((char*)guard_page, _page_size, _page_size)) { - // Do better than this for Merlin -- vm_exit_out_of_memory(os::vm_page_size(), "card table last card"); -+ vm_exit_out_of_memory(_page_size, "card table last card"); - } - *guard_card = last_card; - -@@ -136,8 +153,7 @@ - _covered[res].set_start(base); - _covered[res].set_word_size(0); - jbyte* ct_start = byte_for(base); -- uintptr_t ct_start_aligned = -- align_size_down((uintptr_t)ct_start, os::vm_page_size()); -+ uintptr_t ct_start_aligned = align_size_down((uintptr_t)ct_start, _page_size); - _committed[res].set_start((HeapWord*)ct_start_aligned); - _committed[res].set_word_size(0); - return res; -@@ -196,7 +212,7 @@ - // Align the end up to a page size (starts are already aligned). - jbyte* new_end = byte_after(new_region.last()); - HeapWord* new_end_aligned = -- (HeapWord*)align_size_up((uintptr_t)new_end, os::vm_page_size()); -+ (HeapWord*)align_size_up((uintptr_t)new_end, _page_size); - assert(new_end_aligned >= (HeapWord*) new_end, - "align up, but less"); - // The guard page is always committed and should not be committed over. -@@ -208,7 +224,7 @@ - - assert(!new_committed.is_empty(), "Region should not be empty here"); - if (!os::commit_memory((char*)new_committed.start(), -- new_committed.byte_size())) { -+ new_committed.byte_size(), _page_size)) { - // Do better than this for Merlin - vm_exit_out_of_memory(new_committed.byte_size(), - "card table expansion"); -diff -ruNb openjdk6/hotspot/src/share/vm/memory/cardTableModRefBS.hpp openjdk/hotspot/src/share/vm/memory/cardTableModRefBS.hpp ---- openjdk6/hotspot/src/share/vm/memory/cardTableModRefBS.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/cardTableModRefBS.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)cardTableModRefBS.hpp 1.51 07/05/29 09:44:14 JVM" --#endif - /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -43,9 +40,7 @@ - - class CardTableModRefBS: public ModRefBarrierSet { - // Some classes get to look at some private stuff. --#ifdef CC_INTERP -- friend class cInterpreter; --#endif -+ friend class BytecodeInterpreter; - friend class VMStructs; - friend class CardTableRS; - friend class CheckForUnmarkedOops; // Needs access to raw card bytes. -@@ -81,16 +76,16 @@ - return card_is_dirty_wrt_gen_iter(cv); - } - -- // The region that the card table can cover. -- MemRegion _whole_heap; -- -+ // The declaration order of these const fields is important; see the -+ // constructor before changing. -+ const MemRegion _whole_heap; // the region covered by the card table -+ const size_t _guard_index; // index of very last element in the card -+ // table; it is set to a guard value -+ // (last_card) and should never be modified -+ const size_t _last_valid_index; // index of the last valid element -+ const size_t _page_size; // page size used when mapping _byte_map -+ const size_t _byte_map_size; // in bytes - jbyte* _byte_map; // the card marking array -- size_t _byte_map_size; // In bytes. -- -- size_t _last_valid_index; // index of last valid element in card table -- size_t _guard_index; // index of very last element in card table; -- // it is set to a guard value "last_card" and -- // should never be modified - - int _cur_covered_regions; - // The covered regions should be in address order. -@@ -108,6 +103,12 @@ - // uncommit the MemRegion for that page. - MemRegion _guard_region; - -+ protected: -+ // Initialization utilities; covered_words is the size of the covered region -+ // in, um, words. -+ inline size_t cards_required(size_t covered_words); -+ inline size_t compute_byte_map_size(); -+ - // Finds and return the index of the region, if any, to which the given - // region would be contiguous. If none exists, assign a new region and - // returns its index. Requires that no more than the maximum number of -diff -ruNb openjdk6/hotspot/src/share/vm/memory/cardTableRS.cpp openjdk/hotspot/src/share/vm/memory/cardTableRS.cpp ---- openjdk6/hotspot/src/share/vm/memory/cardTableRS.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/cardTableRS.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)cardTableRS.cpp 1.45 07/05/25 12:54:50 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/cardTableRS.hpp openjdk/hotspot/src/share/vm/memory/cardTableRS.hpp ---- openjdk6/hotspot/src/share/vm/memory/cardTableRS.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/cardTableRS.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)cardTableRS.hpp 1.29 07/05/05 17:05:44 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/classify.cpp openjdk/hotspot/src/share/vm/memory/classify.cpp ---- openjdk6/hotspot/src/share/vm/memory/classify.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/classify.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)classify.cpp 1.9 07/05/05 17:05:44 JVM" --#endif - /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/classify.hpp openjdk/hotspot/src/share/vm/memory/classify.hpp ---- openjdk6/hotspot/src/share/vm/memory/classify.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/classify.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)classify.hpp 1.10 07/05/05 17:05:42 JVM" --#endif - /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/collectorPolicy.cpp openjdk/hotspot/src/share/vm/memory/collectorPolicy.cpp ---- openjdk6/hotspot/src/share/vm/memory/collectorPolicy.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/collectorPolicy.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)collectorPolicy.cpp 1.89 07/06/12 09:41:19 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -149,7 +146,12 @@ - // byte entry and the os page size is 4096, the maximum heap size should - // be 512*4096 = 2MB aligned. - size_t alignment = GenRemSet::max_alignment_constraint(rem_set_name()); -- if (UseLargePages) { -+ -+ // Parallel GC does its own alignment of the generations to avoid requiring a -+ // large page (256M on some platforms) for the permanent generation. The -+ // other collectors should also be updated to do their own alignment and then -+ // this use of lcm() should be removed. -+ if (UseLargePages && !UseParallelGC) { - // in presence of large pages we have to make sure that our - // alignment is large page aware - alignment = lcm(os::large_page_size(), alignment); -diff -ruNb openjdk6/hotspot/src/share/vm/memory/collectorPolicy.hpp openjdk/hotspot/src/share/vm/memory/collectorPolicy.hpp ---- openjdk6/hotspot/src/share/vm/memory/collectorPolicy.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/collectorPolicy.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)collectorPolicy.hpp 1.41 07/05/29 09:44:14 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -262,4 +259,3 @@ - - void initialize_gc_policy_counters(); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/memory/compactPermGen.hpp openjdk/hotspot/src/share/vm/memory/compactPermGen.hpp ---- openjdk6/hotspot/src/share/vm/memory/compactPermGen.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/compactPermGen.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)compactPermGen.hpp 1.17 07/05/05 17:05:45 JVM" --#endif - /* - * Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/compactingPermGenGen.cpp openjdk/hotspot/src/share/vm/memory/compactingPermGenGen.cpp ---- openjdk6/hotspot/src/share/vm/memory/compactingPermGenGen.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/compactingPermGenGen.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)compactingPermGenGen.cpp 1.21 08/06/19 10:32:37 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -29,27 +26,9 @@ - #include "incls/_compactingPermGenGen.cpp.incl" - - --// An ObjectClosure helper: Recursively adjust all pointers in an object --// and all objects by referenced it. Clear marks on objects in order to --// prevent visiting any object twice. This helper is used when the --// RedefineClasses() API has been called. -- --class AdjustSharedObjectClosure : public ObjectClosure { --public: -- void do_object(oop obj) { -- if (obj->is_shared_readwrite()) { -- if (obj->mark()->is_marked()) { -- obj->init_mark(); // Don't revisit this object. -- obj->adjust_pointers(); // Adjust this object's references. -- } -- } -- } --}; -- -- --// An OopClosure helper: Recursively adjust all pointers in an object --// and all objects by referenced it. Clear marks on objects in order --// to prevent visiting any object twice. -+// Recursively adjust all pointers in an object and all objects by -+// referenced it. Clear marks on objects in order to prevent visiting -+// any object twice. - - class RecursiveAdjustSharedObjectClosure : public OopClosure { - public: -@@ -295,27 +274,9 @@ - // objects in the space will page in more objects than we need. - // Instead, use the system dictionary as strong roots into the read - // write space. --// --// If a RedefineClasses() call has been made, then we have to iterate --// over the entire shared read-write space in order to find all the --// objects that need to be forwarded. For example, it is possible for --// an nmethod to be found and marked in GC phase-1 only for the nmethod --// to be freed by the time we reach GC phase-3. The underlying method --// is still marked, but we can't (easily) find it in GC phase-3 so we --// blow up in GC phase-4. With RedefineClasses() we want replaced code --// (EMCP or obsolete) to go away (i.e., be collectible) once it is no --// longer being executed by any thread so we keep minimal attachments --// to the replaced code. However, we can't guarantee when those EMCP --// or obsolete methods will be collected so they may still be out there --// even after we've severed our minimal attachments. - - void CompactingPermGenGen::pre_adjust_pointers() { - if (spec()->enable_shared_spaces()) { -- if (JvmtiExport::has_redefined_a_class()) { -- // RedefineClasses() requires a brute force approach -- AdjustSharedObjectClosure blk; -- rw_space()->object_iterate(&blk); -- } else { - RecursiveAdjustSharedObjectClosure blk; - Universe::oops_do(&blk); - StringTable::oops_do(&blk); -@@ -323,7 +284,6 @@ - TraversePlaceholdersClosure tpc; - SystemDictionary::placeholders_do(&tpc); - } -- } - } - - -diff -ruNb openjdk6/hotspot/src/share/vm/memory/compactingPermGenGen.hpp openjdk/hotspot/src/share/vm/memory/compactingPermGenGen.hpp ---- openjdk6/hotspot/src/share/vm/memory/compactingPermGenGen.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/compactingPermGenGen.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)compactingPermGenGen.hpp 1.20 07/05/05 17:05:45 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -172,8 +169,7 @@ - } - - inline bool is_in(const void* p) const { -- if (!is_in_unshared(p) && !is_in_shared(p)) return false; -- return true; -+ return is_in_unshared(p) || is_in_shared(p); - } - - inline PermanentGenerationSpec* spec() const { return _spec; } -@@ -237,7 +233,7 @@ - void verify(bool allow_dirty); - - // Serialization -- static void initialize_oops(); -+ static void initialize_oops() KERNEL_RETURN; - static void serialize_oops(SerializeOopClosure* soc); - void serialize_bts(SerializeOopClosure* soc); - -diff -ruNb openjdk6/hotspot/src/share/vm/memory/defNewGeneration.cpp openjdk/hotspot/src/share/vm/memory/defNewGeneration.cpp ---- openjdk6/hotspot/src/share/vm/memory/defNewGeneration.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/defNewGeneration.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)defNewGeneration.cpp 1.73 07/05/22 17:24:57 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/defNewGeneration.hpp openjdk/hotspot/src/share/vm/memory/defNewGeneration.hpp ---- openjdk6/hotspot/src/share/vm/memory/defNewGeneration.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/defNewGeneration.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)defNewGeneration.hpp 1.40 07/05/17 15:54:44 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/defNewGeneration.inline.hpp openjdk/hotspot/src/share/vm/memory/defNewGeneration.inline.hpp ---- openjdk6/hotspot/src/share/vm/memory/defNewGeneration.inline.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/defNewGeneration.inline.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)defNewGeneration.inline.hpp 1.18 07/05/05 17:05:46 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/dump.cpp openjdk/hotspot/src/share/vm/memory/dump.cpp ---- openjdk6/hotspot/src/share/vm/memory/dump.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/dump.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)dump.cpp 1.33 07/05/23 10:53:38 JVM" --#endif - /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/filemap.cpp openjdk/hotspot/src/share/vm/memory/filemap.cpp ---- openjdk6/hotspot/src/share/vm/memory/filemap.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/filemap.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)filemap.cpp 1.25 07/05/05 17:05:41 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/filemap.hpp openjdk/hotspot/src/share/vm/memory/filemap.hpp ---- openjdk6/hotspot/src/share/vm/memory/filemap.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/filemap.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)filemap.hpp 1.16 07/05/05 17:05:47 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/gcLocker.cpp openjdk/hotspot/src/share/vm/memory/gcLocker.cpp ---- openjdk6/hotspot/src/share/vm/memory/gcLocker.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/gcLocker.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)gcLocker.cpp 1.52 07/05/17 15:54:45 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/gcLocker.hpp openjdk/hotspot/src/share/vm/memory/gcLocker.hpp ---- openjdk6/hotspot/src/share/vm/memory/gcLocker.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/gcLocker.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)gcLocker.hpp 1.60 07/05/17 15:54:47 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -286,4 +283,3 @@ - ~No_Alloc_Verifier() {} - #endif - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/memory/gcLocker.inline.hpp openjdk/hotspot/src/share/vm/memory/gcLocker.inline.hpp ---- openjdk6/hotspot/src/share/vm/memory/gcLocker.inline.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/gcLocker.inline.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)gcLocker.inline.hpp 1.21 07/05/05 17:05:49 JVM" --#endif - /* - * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -73,4 +70,3 @@ - } - } - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/memory/genCollectedHeap.cpp openjdk/hotspot/src/share/vm/memory/genCollectedHeap.cpp ---- openjdk6/hotspot/src/share/vm/memory/genCollectedHeap.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/genCollectedHeap.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)genCollectedHeap.cpp 1.189 07/06/12 09:41:51 JVM" --#endif - /* - * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -565,11 +562,16 @@ - } - } - -+ // Update "complete" boolean wrt what actually transpired -- -+ // for instance, a promotion failure could have led to -+ // a whole heap collection. -+ complete = complete || (max_level_collected == n_gens() - 1); -+ - if (PrintGCDetails) { - print_heap_change(gch_prev_used); - - // Print perm gen info for full GC with PrintGCDetails flag. -- if (full && max_level == n_gens() - 1) { -+ if (complete) { - print_perm_heap_change(perm_prev_used); - } - } -@@ -578,6 +580,7 @@ - // Adjust generation sizes. - _gens[j]->compute_new_size(); - } -+ - if (complete) { - // Ask the permanent generation to adjust size for full collections - perm()->compute_new_size(); -diff -ruNb openjdk6/hotspot/src/share/vm/memory/genCollectedHeap.hpp openjdk/hotspot/src/share/vm/memory/genCollectedHeap.hpp ---- openjdk6/hotspot/src/share/vm/memory/genCollectedHeap.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/genCollectedHeap.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)genCollectedHeap.hpp 1.104 07/05/29 09:44:15 JVM" --#endif - /* - * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -41,6 +38,7 @@ - friend class VM_GenCollectFull; - friend class VM_GenCollectFullConcurrent; - friend class VM_GC_HeapInspection; -+ friend class VM_HeapDumper; - friend class HeapInspection; - friend class GCCauseSetter; - friend class VMStructs; -@@ -489,5 +487,5 @@ - virtual void gc_epilogue(bool full); - - public: -- virtual void preload_and_dump(TRAPS); -+ virtual void preload_and_dump(TRAPS) KERNEL_RETURN; - }; -diff -ruNb openjdk6/hotspot/src/share/vm/memory/genMarkSweep.cpp openjdk/hotspot/src/share/vm/memory/genMarkSweep.cpp ---- openjdk6/hotspot/src/share/vm/memory/genMarkSweep.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/genMarkSweep.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)genMarkSweep.cpp 1.40 07/05/17 15:54:55 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/genMarkSweep.hpp openjdk/hotspot/src/share/vm/memory/genMarkSweep.hpp ---- openjdk6/hotspot/src/share/vm/memory/genMarkSweep.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/genMarkSweep.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)genMarkSweep.hpp 1.11 07/05/05 17:05:49 JVM" --#endif - /* - * Copyright 2001-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/genOopClosures.hpp openjdk/hotspot/src/share/vm/memory/genOopClosures.hpp ---- openjdk6/hotspot/src/share/vm/memory/genOopClosures.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/genOopClosures.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)genOopClosures.hpp 1.64 07/05/29 09:44:15 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/genOopClosures.inline.hpp openjdk/hotspot/src/share/vm/memory/genOopClosures.inline.hpp ---- openjdk6/hotspot/src/share/vm/memory/genOopClosures.inline.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/genOopClosures.inline.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)genOopClosures.inline.hpp 1.40 07/05/29 09:44:15 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/genRemSet.cpp openjdk/hotspot/src/share/vm/memory/genRemSet.cpp ---- openjdk6/hotspot/src/share/vm/memory/genRemSet.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/genRemSet.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)genRemSet.cpp 1.11 07/05/05 17:05:50 JVM" --#endif - /* - * Copyright 2001-2002 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/genRemSet.hpp openjdk/hotspot/src/share/vm/memory/genRemSet.hpp ---- openjdk6/hotspot/src/share/vm/memory/genRemSet.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/genRemSet.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)genRemSet.hpp 1.23 07/05/05 17:05:50 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/genRemSet.inline.hpp openjdk/hotspot/src/share/vm/memory/genRemSet.inline.hpp ---- openjdk6/hotspot/src/share/vm/memory/genRemSet.inline.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/genRemSet.inline.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)genRemSet.inline.hpp 1.10 07/05/05 17:05:50 JVM" --#endif - /* - * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/generation.cpp openjdk/hotspot/src/share/vm/memory/generation.cpp ---- openjdk6/hotspot/src/share/vm/memory/generation.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/generation.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)generation.cpp 1.245 07/05/05 17:05:51 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/generation.hpp openjdk/hotspot/src/share/vm/memory/generation.hpp ---- openjdk6/hotspot/src/share/vm/memory/generation.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/generation.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)generation.hpp 1.195 07/05/17 15:55:02 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/generation.inline.hpp openjdk/hotspot/src/share/vm/memory/generation.inline.hpp ---- openjdk6/hotspot/src/share/vm/memory/generation.inline.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/generation.inline.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)generation.inline.hpp 1.38 07/05/05 17:05:50 JVM" --#endif - /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/generationSpec.cpp openjdk/hotspot/src/share/vm/memory/generationSpec.cpp ---- openjdk6/hotspot/src/share/vm/memory/generationSpec.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/generationSpec.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)generationSpec.cpp 1.29 07/05/29 09:44:15 JVM" --#endif - /* - * Copyright 2001-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/generationSpec.hpp openjdk/hotspot/src/share/vm/memory/generationSpec.hpp ---- openjdk6/hotspot/src/share/vm/memory/generationSpec.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/generationSpec.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)generationSpec.hpp 1.17 07/05/05 17:05:50 JVM" --#endif - /* - * Copyright 2001-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/heap.cpp openjdk/hotspot/src/share/vm/memory/heap.cpp ---- openjdk6/hotspot/src/share/vm/memory/heap.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/heap.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)heap.cpp 1.54 07/05/05 17:05:46 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -95,27 +92,37 @@ - } - - --bool CodeHeap::reserve(size_t reserved_size, size_t committed_size, size_t segment_size) { -+bool CodeHeap::reserve(size_t reserved_size, size_t committed_size, -+ size_t segment_size) { -+ assert(reserved_size >= committed_size, "reserved < committed"); - assert(segment_size >= sizeof(FreeBlock), "segment size is too small"); - assert(is_power_of_2(segment_size), "segment_size must be a power of 2"); -+ - _segment_size = segment_size; - _log2_segment_size = exact_log2(segment_size); -- // reserve space for _memory -- assert(reserved_size >= committed_size, "reserved size must be >= committed size"); -- if (!_memory.initialize( -- ReservedSpace(align_to_allocation_size(reserved_size), -- // On Solaris using MPSS only, try for large -- // page allocation of the code cache -- SOLARIS_ONLY(UseMPSS ? os::large_page_size() : 0) NOT_SOLARIS(0), -- SOLARIS_ONLY(UseMPSS) NOT_SOLARIS(false), -- NULL), -- align_to_allocation_size(committed_size))) { -+ -+ // Reserve and initialize space for _memory. -+ const size_t page_size = os::page_size_for_region(committed_size, -+ reserved_size, 8); -+ const size_t granularity = os::vm_allocation_granularity(); -+ const size_t r_align = MAX2(page_size, granularity); -+ const size_t r_size = align_size_up(reserved_size, r_align); -+ const size_t c_size = align_size_up(committed_size, page_size); -+ -+ const size_t rs_align = page_size == (size_t) os::vm_page_size() ? 0 : -+ MAX2(page_size, granularity); -+ ReservedSpace rs(r_size, rs_align, false); -+ os::trace_page_sizes("code heap", committed_size, reserved_size, page_size, -+ rs.base(), rs.size()); -+ if (!_memory.initialize(rs, c_size)) { - return false; - } -+ - on_code_mapping(_memory.low(), _memory.committed_size()); - _number_of_committed_segments = number_of_segments(_memory.committed_size()); - _number_of_reserved_segments = number_of_segments(_memory.reserved_size()); - assert(_number_of_reserved_segments >= _number_of_committed_segments, "just checking"); -+ - // reserve space for _segmap - if (!_segmap.initialize(align_to_page_size(_number_of_reserved_segments), align_to_page_size(_number_of_committed_segments))) { - return false; -@@ -123,6 +130,7 @@ - assert(_segmap.committed_size() >= (size_t) _number_of_committed_segments, "could not commit enough space for segment map"); - assert(_segmap.reserved_size() >= (size_t) _number_of_reserved_segments , "could not reserve enough space for segment map"); - assert(_segmap.reserved_size() >= _segmap.committed_size() , "just checking"); -+ - // initialize remaining instance variables - clear(); - return true; -@@ -472,4 +480,3 @@ - } - guarantee(count == 0, "missing free blocks"); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/memory/heap.hpp openjdk/hotspot/src/share/vm/memory/heap.hpp ---- openjdk6/hotspot/src/share/vm/memory/heap.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/heap.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)heap.hpp 1.43 07/05/05 17:05:47 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/heapInspection.cpp openjdk/hotspot/src/share/vm/memory/heapInspection.cpp ---- openjdk6/hotspot/src/share/vm/memory/heapInspection.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/heapInspection.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)heapInspection.cpp 1.21 07/05/29 09:44:16 JVM" --#endif - /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/heapInspection.hpp openjdk/hotspot/src/share/vm/memory/heapInspection.hpp ---- openjdk6/hotspot/src/share/vm/memory/heapInspection.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/heapInspection.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)heapInspection.hpp 1.15 07/05/05 17:05:51 JVM" --#endif - /* - * Copyright 2002-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -25,6 +22,9 @@ - * - */ - -+#ifndef SERVICES_KERNEL -+ -+ - // HeapInspection - - // KlassInfoTable is a bucket hash table that -@@ -122,8 +122,10 @@ - void sort(); - }; - -+#endif // SERVICES_KERNEL -+ - class HeapInspection : public AllStatic { - public: -- static void heap_inspection(outputStream* st); -- static void find_instances_at_safepoint(klassOop k, GrowableArray* result); -+ static void heap_inspection(outputStream* st) KERNEL_RETURN; -+ static void find_instances_at_safepoint(klassOop k, GrowableArray* result) KERNEL_RETURN; - }; -diff -ruNb openjdk6/hotspot/src/share/vm/memory/iterator.cpp openjdk/hotspot/src/share/vm/memory/iterator.cpp ---- openjdk6/hotspot/src/share/vm/memory/iterator.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/iterator.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)iterator.cpp 1.18 07/05/05 17:05:50 JVM" --#endif - /* - * Copyright 1997-2001 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -35,4 +32,3 @@ - void VoidClosure::do_void() { - ShouldNotCallThis(); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/memory/iterator.hpp openjdk/hotspot/src/share/vm/memory/iterator.hpp ---- openjdk6/hotspot/src/share/vm/memory/iterator.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/iterator.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)iterator.hpp 1.38 07/05/05 17:05:52 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/memRegion.cpp openjdk/hotspot/src/share/vm/memory/memRegion.cpp ---- openjdk6/hotspot/src/share/vm/memory/memRegion.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/memRegion.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)memRegion.cpp 1.23 07/05/05 17:05:52 JVM" --#endif - /* - * Copyright 2000-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/memRegion.hpp openjdk/hotspot/src/share/vm/memory/memRegion.hpp ---- openjdk6/hotspot/src/share/vm/memory/memRegion.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/memRegion.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)memRegion.hpp 1.27 07/05/05 17:05:53 JVM" --#endif - /* - * Copyright 2000-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/modRefBarrierSet.hpp openjdk/hotspot/src/share/vm/memory/modRefBarrierSet.hpp ---- openjdk6/hotspot/src/share/vm/memory/modRefBarrierSet.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/modRefBarrierSet.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)modRefBarrierSet.hpp 1.16 07/05/05 17:05:53 JVM" --#endif - /* - * Copyright 2000-2002 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/oopFactory.cpp openjdk/hotspot/src/share/vm/memory/oopFactory.cpp ---- openjdk6/hotspot/src/share/vm/memory/oopFactory.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/oopFactory.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)oopFactory.cpp 1.83 07/05/05 17:05:53 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -146,4 +143,3 @@ - c->set_holder_klass(klass()); - return c; - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/memory/oopFactory.hpp openjdk/hotspot/src/share/vm/memory/oopFactory.hpp ---- openjdk6/hotspot/src/share/vm/memory/oopFactory.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/oopFactory.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)oopFactory.hpp 1.61 07/05/05 17:05:53 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/permGen.cpp openjdk/hotspot/src/share/vm/memory/permGen.cpp ---- openjdk6/hotspot/src/share/vm/memory/permGen.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/permGen.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)permGen.cpp 1.54 07/05/29 09:44:16 JVM" --#endif - /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/permGen.hpp openjdk/hotspot/src/share/vm/memory/permGen.hpp ---- openjdk6/hotspot/src/share/vm/memory/permGen.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/permGen.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)permGen.hpp 1.38 07/05/29 09:44:16 JVM" --#endif - /* - * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -74,4 +71,3 @@ - g->update_counters(); - } - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/memory/referencePolicy.cpp openjdk/hotspot/src/share/vm/memory/referencePolicy.cpp ---- openjdk6/hotspot/src/share/vm/memory/referencePolicy.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/referencePolicy.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)referencePolicy.cpp 1.12 07/05/05 17:05:54 JVM" --#endif - /* - * Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -71,4 +68,3 @@ - - return true; - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/memory/referencePolicy.hpp openjdk/hotspot/src/share/vm/memory/referencePolicy.hpp ---- openjdk6/hotspot/src/share/vm/memory/referencePolicy.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/referencePolicy.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)referencePolicy.hpp 1.11 07/05/05 17:05:54 JVM" --#endif - /* - * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/referenceProcessor.cpp openjdk/hotspot/src/share/vm/memory/referenceProcessor.cpp ---- openjdk6/hotspot/src/share/vm/memory/referenceProcessor.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/referenceProcessor.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)referenceProcessor.cpp 1.55 07/05/17 15:55:08 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -404,7 +401,11 @@ - inline bool is_referent_alive() const; - - // Loads data for the current reference. -- inline void load_ptrs(); -+ // The "allow_null_referent" argument tells us to allow for the possibility -+ // of a NULL referent in the discovered Reference object. This typically -+ // happens in the case of concurrent collectors that may have done the -+ // discovery concurrently or interleaved with mutator execution. -+ inline void load_ptrs(DEBUG_ONLY(bool allow_null_referent)); - - // Move to the next discovered reference. - inline void next(); -@@ -475,7 +476,7 @@ - return _is_alive->do_object_b(_referent); - } - --inline void DiscoveredListIterator::load_ptrs() -+inline void DiscoveredListIterator::load_ptrs(DEBUG_ONLY(bool allow_null_referent)) - { - _discovered_addr = java_lang_ref_Reference::discovered_addr(_ref); - assert(_discovered_addr && (*_discovered_addr)->is_oop_or_null(), -@@ -485,7 +486,10 @@ - _referent = *_referent_addr; - assert(Universe::heap()->is_in_reserved_or_null(_referent), - "Wrong oop found in java.lang.Reference object"); -- assert(_referent->is_oop(), "bad referent"); -+ assert(allow_null_referent ? -+ _referent->is_oop_or_null() -+ : _referent->is_oop(), -+ "bad referent"); - } - - inline void DiscoveredListIterator::next() -@@ -536,8 +540,8 @@ - DiscoveredListIterator iter(refs_list_addr, keep_alive, is_alive); - // Decide which softly reachable refs should be kept alive. - while (iter.has_next()) { -- iter.load_ptrs(); -- bool referent_is_dead = !iter.is_referent_alive(); -+ iter.load_ptrs(DEBUG_ONLY(!discovery_is_atomic() /* allow_null_referent */)); -+ bool referent_is_dead = (iter.referent() != NULL) && !iter.is_referent_alive(); - if (referent_is_dead && !policy->should_clear_reference(iter.obj())) { - if (TraceReferenceGC) { - gclog_or_tty->print_cr("Dropping reference (" INTPTR_FORMAT ": %s" ") by policy", -@@ -573,7 +577,7 @@ - assert(discovery_is_atomic(), "Error"); - DiscoveredListIterator iter(refs_list_addr, keep_alive, is_alive); - while (iter.has_next()) { -- iter.load_ptrs(); -+ iter.load_ptrs(DEBUG_ONLY(false /* allow_null_referent */)); - DEBUG_ONLY(oop* next_addr = java_lang_ref_Reference::next_addr(iter.obj());) - assert(*next_addr == NULL, "Should not discover inactive Reference"); - if (iter.is_referent_alive()) { -@@ -610,7 +614,7 @@ - assert(!discovery_is_atomic(), "Error"); - DiscoveredListIterator iter(refs_list_addr, keep_alive, is_alive); - while (iter.has_next()) { -- iter.load_ptrs(); -+ iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */)); - oop* next_addr = java_lang_ref_Reference::next_addr(iter.obj()); - if ((iter.referent() == NULL || iter.is_referent_alive() || - *next_addr != NULL)) { -@@ -646,7 +650,7 @@ - DiscoveredListIterator iter(refs_list_addr, keep_alive, is_alive); - while (iter.has_next()) { - iter.update_discovered(); -- iter.load_ptrs(); -+ iter.load_ptrs(DEBUG_ONLY(false /* allow_null_referent */)); - if (clear_referent) { - // NULL out referent pointer - iter.clear_referent(); -@@ -870,7 +874,7 @@ - DiscoveredListIterator iter(refs_list, NULL, NULL); - size_t length = refs_list.length(); - while (iter.has_next()) { -- iter.load_ptrs(); -+ iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */)); - oop* next_addr = java_lang_ref_Reference::next_addr(iter.obj()); - assert((*next_addr)->is_oop_or_null(), "bad next field"); - // If referent has been cleared or Reference is not active, -@@ -1184,7 +1188,7 @@ - DiscoveredListIterator iter(refs_list, keep_alive, is_alive); - size_t length = refs_list.length(); - while (iter.has_next()) { -- iter.load_ptrs(); -+ iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */)); - oop* next_addr = java_lang_ref_Reference::next_addr(iter.obj()); - if (iter.referent() == NULL || iter.is_referent_alive() || - *next_addr != NULL) { -diff -ruNb openjdk6/hotspot/src/share/vm/memory/referenceProcessor.hpp openjdk/hotspot/src/share/vm/memory/referenceProcessor.hpp ---- openjdk6/hotspot/src/share/vm/memory/referenceProcessor.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/referenceProcessor.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)referenceProcessor.hpp 1.43 07/05/05 17:05:54 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -500,4 +497,3 @@ - oop _sentinel_ref; - int _n_queues; - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/memory/resourceArea.cpp openjdk/hotspot/src/share/vm/memory/resourceArea.cpp ---- openjdk6/hotspot/src/share/vm/memory/resourceArea.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/resourceArea.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)resourceArea.cpp 1.57 07/05/05 17:05:55 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/resourceArea.hpp openjdk/hotspot/src/share/vm/memory/resourceArea.hpp ---- openjdk6/hotspot/src/share/vm/memory/resourceArea.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/resourceArea.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)resourceArea.hpp 1.45 07/05/05 17:05:55 JVM" --#endif - /* - * Copyright 1997-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/restore.cpp openjdk/hotspot/src/share/vm/memory/restore.cpp ---- openjdk6/hotspot/src/share/vm/memory/restore.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/restore.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)restore.cpp 1.14 07/05/05 17:05:44 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/serialize.cpp openjdk/hotspot/src/share/vm/memory/serialize.cpp ---- openjdk6/hotspot/src/share/vm/memory/serialize.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/serialize.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)serialize.cpp 1.9 07/05/05 17:05:55 JVM" --#endif - /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/sharedHeap.cpp openjdk/hotspot/src/share/vm/memory/sharedHeap.cpp ---- openjdk6/hotspot/src/share/vm/memory/sharedHeap.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/sharedHeap.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)sharedHeap.cpp 1.59 07/05/17 15:55:10 JVM" --#endif - /* - * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/sharedHeap.hpp openjdk/hotspot/src/share/vm/memory/sharedHeap.hpp ---- openjdk6/hotspot/src/share/vm/memory/sharedHeap.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/sharedHeap.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)sharedHeap.hpp 1.56 07/05/05 17:05:55 JVM" --#endif - /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -273,5 +270,3 @@ - size_t bytes_after, - size_t capacity); - }; -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/memory/space.cpp openjdk/hotspot/src/share/vm/memory/space.cpp ---- openjdk6/hotspot/src/share/vm/memory/space.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/space.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)space.cpp 1.217 07/05/29 09:44:13 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/space.hpp openjdk/hotspot/src/share/vm/memory/space.hpp ---- openjdk6/hotspot/src/share/vm/memory/space.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/space.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)space.hpp 1.149 07/05/29 09:44:14 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/space.inline.hpp openjdk/hotspot/src/share/vm/memory/space.inline.hpp ---- openjdk6/hotspot/src/share/vm/memory/space.inline.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/space.inline.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)space.inline.hpp 1.17 07/05/05 17:05:54 JVM" --#endif - /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/specialized_oop_closures.cpp openjdk/hotspot/src/share/vm/memory/specialized_oop_closures.cpp ---- openjdk6/hotspot/src/share/vm/memory/specialized_oop_closures.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/specialized_oop_closures.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)specialized_oop_closures.cpp 1.14 07/05/05 17:05:56 JVM" --#endif - /* - * Copyright 2001-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/specialized_oop_closures.hpp openjdk/hotspot/src/share/vm/memory/specialized_oop_closures.hpp ---- openjdk6/hotspot/src/share/vm/memory/specialized_oop_closures.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/specialized_oop_closures.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)specialized_oop_closures.hpp 1.30 07/05/29 09:44:17 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/tenuredGeneration.cpp openjdk/hotspot/src/share/vm/memory/tenuredGeneration.cpp ---- openjdk6/hotspot/src/share/vm/memory/tenuredGeneration.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/tenuredGeneration.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)tenuredGeneration.cpp 1.47 07/05/29 09:44:17 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/tenuredGeneration.hpp openjdk/hotspot/src/share/vm/memory/tenuredGeneration.hpp ---- openjdk6/hotspot/src/share/vm/memory/tenuredGeneration.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/tenuredGeneration.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)tenuredGeneration.hpp 1.27 07/05/29 09:44:17 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/threadLocalAllocBuffer.cpp openjdk/hotspot/src/share/vm/memory/threadLocalAllocBuffer.cpp ---- openjdk6/hotspot/src/share/vm/memory/threadLocalAllocBuffer.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/threadLocalAllocBuffer.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)threadLocalAllocBuffer.cpp 1.55 07/07/05 17:12:38 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/threadLocalAllocBuffer.hpp openjdk/hotspot/src/share/vm/memory/threadLocalAllocBuffer.hpp ---- openjdk6/hotspot/src/share/vm/memory/threadLocalAllocBuffer.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/threadLocalAllocBuffer.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)threadLocalAllocBuffer.hpp 1.35 07/07/05 17:12:36 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/threadLocalAllocBuffer.inline.hpp openjdk/hotspot/src/share/vm/memory/threadLocalAllocBuffer.inline.hpp ---- openjdk6/hotspot/src/share/vm/memory/threadLocalAllocBuffer.inline.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/threadLocalAllocBuffer.inline.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)threadLocalAllocBuffer.inline.hpp 1.29 07/05/05 17:05:56 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/memory/universe.cpp openjdk/hotspot/src/share/vm/memory/universe.cpp ---- openjdk6/hotspot/src/share/vm/memory/universe.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/universe.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)universe.cpp 1.359 07/05/29 09:44:16 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -52,6 +49,16 @@ - klassOop Universe::_constantPoolCacheKlassObj = NULL; - klassOop Universe::_compiledICHolderKlassObj = NULL; - klassOop Universe::_systemObjArrayKlassObj = NULL; -+oop Universe::_int_mirror = NULL; -+oop Universe::_float_mirror = NULL; -+oop Universe::_double_mirror = NULL; -+oop Universe::_byte_mirror = NULL; -+oop Universe::_bool_mirror = NULL; -+oop Universe::_char_mirror = NULL; -+oop Universe::_long_mirror = NULL; -+oop Universe::_short_mirror = NULL; -+oop Universe::_void_mirror = NULL; -+oop Universe::_mirrors[T_VOID+1] = { NULL /*, NULL...*/ }; - oop Universe::_main_thread_group = NULL; - oop Universe::_system_thread_group = NULL; - typeArrayOop Universe::_the_empty_byte_array = NULL; -@@ -121,11 +128,24 @@ - } - - void Universe::oops_do(OopClosure* f, bool do_all) { -- // Although most of the SystemDictionary oops are klasses, -- // a few non-klass objects are defined over there. -- // They must be treated in all ways like the random objects in Universe. -- // So adopt them into Universe, by the following cross-module call: -- SystemDictionary::shared_oops_do(f); -+ -+ f->do_oop((oop*) &_int_mirror); -+ f->do_oop((oop*) &_float_mirror); -+ f->do_oop((oop*) &_double_mirror); -+ f->do_oop((oop*) &_byte_mirror); -+ f->do_oop((oop*) &_bool_mirror); -+ f->do_oop((oop*) &_char_mirror); -+ f->do_oop((oop*) &_long_mirror); -+ f->do_oop((oop*) &_short_mirror); -+ f->do_oop((oop*) &_void_mirror); -+ -+ // It's important to iterate over these guys even if they are null, -+ // since that's how shared heaps are restored. -+ for (int i = T_BOOLEAN; i < T_VOID+1; i++) { -+ f->do_oop((oop*) &_mirrors[i]); -+ } -+ assert(_mirrors[0] == NULL && _mirrors[T_BOOLEAN - 1] == NULL, "checking"); -+ - // %%% Consider moving those "shared oops" over here with the others. - f->do_oop((oop*)&_boolArrayKlassObj); - f->do_oop((oop*)&_byteArrayKlassObj); -@@ -462,6 +482,45 @@ - } - }; - -+void Universe::initialize_basic_type_mirrors(TRAPS) { -+ if (UseSharedSpaces) { -+ assert(_int_mirror != NULL, "already loaded"); -+ assert(_void_mirror == _mirrors[T_VOID], "consistently loaded"); -+ } else { -+ -+ assert(_int_mirror==NULL, "basic type mirrors already initialized"); -+ _int_mirror = -+ java_lang_Class::create_basic_type_mirror("int", T_INT, CHECK); -+ _float_mirror = -+ java_lang_Class::create_basic_type_mirror("float", T_FLOAT, CHECK); -+ _double_mirror = -+ java_lang_Class::create_basic_type_mirror("double", T_DOUBLE, CHECK); -+ _byte_mirror = -+ java_lang_Class::create_basic_type_mirror("byte", T_BYTE, CHECK); -+ _bool_mirror = -+ java_lang_Class::create_basic_type_mirror("boolean",T_BOOLEAN, CHECK); -+ _char_mirror = -+ java_lang_Class::create_basic_type_mirror("char", T_CHAR, CHECK); -+ _long_mirror = -+ java_lang_Class::create_basic_type_mirror("long", T_LONG, CHECK); -+ _short_mirror = -+ java_lang_Class::create_basic_type_mirror("short", T_SHORT, CHECK); -+ _void_mirror = -+ java_lang_Class::create_basic_type_mirror("void", T_VOID, CHECK); -+ -+ _mirrors[T_INT] = _int_mirror; -+ _mirrors[T_FLOAT] = _float_mirror; -+ _mirrors[T_DOUBLE] = _double_mirror; -+ _mirrors[T_BYTE] = _byte_mirror; -+ _mirrors[T_BOOLEAN] = _bool_mirror; -+ _mirrors[T_CHAR] = _char_mirror; -+ _mirrors[T_LONG] = _long_mirror; -+ _mirrors[T_SHORT] = _short_mirror; -+ _mirrors[T_VOID] = _void_mirror; -+ //_mirrors[T_OBJECT] = instanceKlass::cast(_object_klass)->java_mirror(); -+ //_mirrors[T_ARRAY] = instanceKlass::cast(_object_klass)->java_mirror(); -+ } -+} - - void Universe::fixup_mirrors(TRAPS) { - // Bootstrap problem: all classes gets a mirror (java.lang.Class instance) assigned eagerly, -@@ -881,44 +940,26 @@ - } - - -+// %%% The Universe::flush_foo methods belong in CodeCache. -+ - // Flushes compiled methods dependent on dependee. - void Universe::flush_dependents_on(instanceKlassHandle dependee) { - assert_lock_strong(Compile_lock); -+ - if (CodeCache::number_of_nmethods_with_dependencies() == 0) return; - - // CodeCache can only be updated by a thread_in_VM and they will all be - // stopped dring the safepoint so CodeCache will be safe to update without - // holding the CodeCache_lock. - -- // Mark all dependee and all its superclasses -- for (klassOop d = dependee(); d != NULL; d = instanceKlass::cast(d)->super()) { -- assert(!instanceKlass::cast(d)->is_marked_dependent(), "checking"); -- instanceKlass::cast(d)->set_is_marked_dependent(true); -- } -- // Mark transitive interfaces -- int i; -- for (i = 0; i < dependee->transitive_interfaces()->length(); i++) { -- instanceKlass* klass = instanceKlass::cast((klassOop)dependee->transitive_interfaces()->obj_at(i)); -- assert(!klass->is_marked_dependent(), "checking"); -- klass->set_is_marked_dependent(true); -- } -+ DepChange changes(dependee); - - // Compute the dependent nmethods -- if (CodeCache::mark_for_deoptimization(dependee()) > 0) { -+ if (CodeCache::mark_for_deoptimization(changes) > 0) { - // At least one nmethod has been marked for deoptimization - VM_Deoptimize op; - VMThread::execute(&op); - } -- -- // Unmark all dependee and all its superclasses -- for (klassOop e = dependee(); e != NULL; e = instanceKlass::cast(e)->super()) { -- instanceKlass::cast(e)->set_is_marked_dependent(false); -- } -- // Unmark transitive interfaces -- for (i = 0; i < dependee->transitive_interfaces()->length(); i++) { -- instanceKlass* klass = instanceKlass::cast((klassOop)dependee->transitive_interfaces()->obj_at(i)); -- klass->set_is_marked_dependent(false); -- } - } - - #ifdef HOTSWAP -diff -ruNb openjdk6/hotspot/src/share/vm/memory/universe.hpp openjdk/hotspot/src/share/vm/memory/universe.hpp ---- openjdk6/hotspot/src/share/vm/memory/universe.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/universe.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)universe.hpp 1.182 07/05/17 15:55:24 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -137,6 +134,18 @@ - static klassOop _systemObjArrayKlassObj; - - // Known objects in the VM -+ -+ // Primitive objects -+ static oop _int_mirror; -+ static oop _float_mirror; -+ static oop _double_mirror; -+ static oop _byte_mirror; -+ static oop _bool_mirror; -+ static oop _char_mirror; -+ static oop _long_mirror; -+ static oop _short_mirror; -+ static oop _void_mirror; -+ - static oop _main_thread_group; // Reference to the main thread group object - static oop _system_thread_group; // Reference to the system thread group object - -@@ -196,6 +205,7 @@ - static size_t _heap_used_at_last_gc; - - static jint initialize_heap(); -+ static void initialize_basic_type_mirrors(TRAPS); - static void fixup_mirrors(TRAPS); - - static void reinitialize_vtable_of(KlassHandle h_k, TRAPS); -@@ -204,6 +214,12 @@ - - static void genesis(TRAPS); // Create the initial world - -+ // Mirrors for primitive classes (created eagerly) -+ static oop check_mirror(oop m) { -+ assert(m != NULL, "mirror not initialized"); -+ return m; -+ } -+ - // Debugging - static int _verify_count; // number of verifies done - // True during call to verify(). Should only be set/cleared in verify(). -@@ -247,6 +263,24 @@ - static klassOop systemObjArrayKlassObj() { return _systemObjArrayKlassObj; } - - // Known objects in tbe VM -+ static oop int_mirror() { return check_mirror(_int_mirror); -+} -+ static oop float_mirror() { return check_mirror(_float_mirror); } -+ static oop double_mirror() { return check_mirror(_double_mirror); } -+ static oop byte_mirror() { return check_mirror(_byte_mirror); } -+ static oop bool_mirror() { return check_mirror(_bool_mirror); } -+ static oop char_mirror() { return check_mirror(_char_mirror); } -+ static oop long_mirror() { return check_mirror(_long_mirror); } -+ static oop short_mirror() { return check_mirror(_short_mirror); } -+ static oop void_mirror() { return check_mirror(_void_mirror); } -+ -+ // table of same -+ static oop _mirrors[T_VOID+1]; -+ -+ static oop java_mirror(BasicType t) { -+ assert((uint)t < T_VOID+1, "range check"); -+ return check_mirror(_mirrors[t]); -+ } - static oop main_thread_group() { return _main_thread_group; } - static void set_main_thread_group(oop group) { _main_thread_group = group;} - -diff -ruNb openjdk6/hotspot/src/share/vm/memory/universe.inline.hpp openjdk/hotspot/src/share/vm/memory/universe.inline.hpp ---- openjdk6/hotspot/src/share/vm/memory/universe.inline.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/universe.inline.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)universe.inline.hpp 1.47 07/05/05 17:05:57 JVM" --#endif - /* - * Copyright 1997-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -38,6 +35,3 @@ - inline bool Universe::field_type_should_be_aligned(BasicType type) { - return type == T_DOUBLE || type == T_LONG; - } -- -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/memory/watermark.hpp openjdk/hotspot/src/share/vm/memory/watermark.hpp ---- openjdk6/hotspot/src/share/vm/memory/watermark.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/memory/watermark.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)watermark.hpp 1.14 07/05/05 17:05:56 JVM" --#endif - /* - * Copyright 2000-2001 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -54,4 +51,3 @@ - inline bool operator!=(const WaterMark& x, const WaterMark& y) { - return !(x == y); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/arrayKlass.cpp openjdk/hotspot/src/share/vm/oops/arrayKlass.cpp ---- openjdk6/hotspot/src/share/vm/oops/arrayKlass.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/arrayKlass.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)arrayKlass.cpp 1.95 07/05/05 17:05:59 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/oops/arrayKlass.hpp openjdk/hotspot/src/share/vm/oops/arrayKlass.hpp ---- openjdk6/hotspot/src/share/vm/oops/arrayKlass.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/arrayKlass.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)arrayKlass.hpp 1.66 07/05/05 17:05:58 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -135,4 +132,3 @@ - // Verification - void oop_verify_on(oop obj, outputStream* st); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/arrayKlassKlass.cpp openjdk/hotspot/src/share/vm/oops/arrayKlassKlass.cpp ---- openjdk6/hotspot/src/share/vm/oops/arrayKlassKlass.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/arrayKlassKlass.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)arrayKlassKlass.cpp 1.56 07/05/29 09:44:17 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/oops/arrayKlassKlass.hpp openjdk/hotspot/src/share/vm/oops/arrayKlassKlass.hpp ---- openjdk6/hotspot/src/share/vm/oops/arrayKlassKlass.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/arrayKlassKlass.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)arrayKlassKlass.hpp 1.39 07/05/29 09:44:18 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -70,4 +67,3 @@ - const char* internal_name() const; - void oop_verify_on(oop obj, outputStream* st); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/arrayOop.cpp openjdk/hotspot/src/share/vm/oops/arrayOop.cpp ---- openjdk6/hotspot/src/share/vm/oops/arrayOop.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/arrayOop.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)arrayOop.cpp 1.18 07/05/05 17:05:58 JVM" --#endif - /* - * Copyright 1997 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -29,4 +26,3 @@ - # include "incls/_arrayOop.cpp.incl" - - // <> -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/arrayOop.hpp openjdk/hotspot/src/share/vm/oops/arrayOop.hpp ---- openjdk6/hotspot/src/share/vm/oops/arrayOop.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/arrayOop.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)arrayOop.hpp 1.35 07/05/05 17:06:00 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/oops/compiledICHolderKlass.cpp openjdk/hotspot/src/share/vm/oops/compiledICHolderKlass.cpp ---- openjdk6/hotspot/src/share/vm/oops/compiledICHolderKlass.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/compiledICHolderKlass.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)compiledICHolderKlass.cpp 1.41 07/05/29 09:44:18 JVM" --#endif - /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/oops/compiledICHolderKlass.hpp openjdk/hotspot/src/share/vm/oops/compiledICHolderKlass.hpp ---- openjdk6/hotspot/src/share/vm/oops/compiledICHolderKlass.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/compiledICHolderKlass.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)compiledICHolderKlass.hpp 1.32 07/05/29 09:44:18 JVM" --#endif - /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -84,4 +81,3 @@ - void oop_verify_on(oop obj, outputStream* st); - - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/compiledICHolderOop.cpp openjdk/hotspot/src/share/vm/oops/compiledICHolderOop.cpp ---- openjdk6/hotspot/src/share/vm/oops/compiledICHolderOop.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/compiledICHolderOop.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)compiledICHolderOop.cpp 1.12 07/05/05 17:05:59 JVM" --#endif - /* - * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -29,4 +26,3 @@ - # include "incls/_compiledICHolderOop.cpp.incl" - - // <> -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/compiledICHolderOop.hpp openjdk/hotspot/src/share/vm/oops/compiledICHolderOop.hpp ---- openjdk6/hotspot/src/share/vm/oops/compiledICHolderOop.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/compiledICHolderOop.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)compiledICHolderOop.hpp 1.20 07/05/05 17:05:59 JVM" --#endif - /* - * Copyright 1998-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/oops/constMethodKlass.cpp openjdk/hotspot/src/share/vm/oops/constMethodKlass.cpp ---- openjdk6/hotspot/src/share/vm/oops/constMethodKlass.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/constMethodKlass.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)constMethodKlass.cpp 1.24 07/05/29 09:44:18 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -67,7 +64,7 @@ - CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL); - assert(!cm->is_parsable(), "Not yet safely parsable"); - No_Safepoint_Verifier no_safepoint; -- cm->set_interpreter_kind(AbstractInterpreter::invalid); -+ cm->set_interpreter_kind(Interpreter::invalid); - cm->init_fingerprint(); - cm->set_method(NULL); - cm->set_stackmap_data(NULL); -@@ -302,4 +299,3 @@ - // Temporarily set exception_table to point to self - m->set_exception_table((typeArrayOop)obj); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/constMethodKlass.hpp openjdk/hotspot/src/share/vm/oops/constMethodKlass.hpp ---- openjdk6/hotspot/src/share/vm/oops/constMethodKlass.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/constMethodKlass.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)constMethodKlass.hpp 1.15 07/05/29 09:44:18 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -91,4 +88,3 @@ - bool oop_partially_loaded(oop obj) const; - void oop_set_partially_loaded(oop obj); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/constMethodOop.cpp openjdk/hotspot/src/share/vm/oops/constMethodOop.cpp ---- openjdk6/hotspot/src/share/vm/oops/constMethodOop.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/constMethodOop.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)constMethodOop.cpp 1.11 07/05/05 17:06:00 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/oops/constMethodOop.hpp openjdk/hotspot/src/share/vm/oops/constMethodOop.hpp ---- openjdk6/hotspot/src/share/vm/oops/constMethodOop.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/constMethodOop.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)constMethodOop.hpp 1.24 07/05/05 17:05:59 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/oops/constantPoolKlass.cpp openjdk/hotspot/src/share/vm/oops/constantPoolKlass.cpp ---- openjdk6/hotspot/src/share/vm/oops/constantPoolKlass.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/constantPoolKlass.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)constantPoolKlass.cpp 1.105 07/05/29 09:44:18 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/oops/constantPoolKlass.hpp openjdk/hotspot/src/share/vm/oops/constantPoolKlass.hpp ---- openjdk6/hotspot/src/share/vm/oops/constantPoolKlass.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/constantPoolKlass.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)constantPoolKlass.hpp 1.51 07/05/29 09:44:18 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -78,4 +75,3 @@ - static void preload_and_initialize_all_classes(oop constant_pool, TRAPS); - #endif - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/constantPoolOop.cpp openjdk/hotspot/src/share/vm/oops/constantPoolOop.cpp ---- openjdk6/hotspot/src/share/vm/oops/constantPoolOop.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/constantPoolOop.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)constantPoolOop.cpp 1.104 07/05/05 17:06:01 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/oops/constantPoolOop.hpp openjdk/hotspot/src/share/vm/oops/constantPoolOop.hpp ---- openjdk6/hotspot/src/share/vm/oops/constantPoolOop.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/constantPoolOop.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)constantPoolOop.hpp 1.104 07/05/17 15:55:26 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -35,17 +32,11 @@ - // the entry in the constant pool is a klass or String object and - // not a symbolOop. - --#ifdef CC_INTERP --class cInterpreter; --#endif /* CC_INTERP */ -- - class SymbolHashMap; - - class constantPoolOopDesc : public arrayOopDesc { - friend class VMStructs; --#ifdef CC_INTERP -- friend class cInterpreter; // Directly extracts an oop in the pool for fast instanceof/checkcast --#endif /* CC_INTERP */ -+ friend class BytecodeInterpreter; // Directly extracts an oop in the pool for fast instanceof/checkcast - private: - typeArrayOop _tags; // the tag array describing the constant pool's contents - constantPoolCacheOop _cache; // the cache holding interpreter runtime information -diff -ruNb openjdk6/hotspot/src/share/vm/oops/cpCacheKlass.cpp openjdk/hotspot/src/share/vm/oops/cpCacheKlass.cpp ---- openjdk6/hotspot/src/share/vm/oops/cpCacheKlass.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/cpCacheKlass.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)cpCacheKlass.cpp 1.46 07/05/29 09:44:18 JVM" --#endif - /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -206,4 +203,3 @@ - const char* constantPoolCacheKlass::internal_name() const { - return "{constant pool cache}"; - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/cpCacheKlass.hpp openjdk/hotspot/src/share/vm/oops/cpCacheKlass.hpp ---- openjdk6/hotspot/src/share/vm/oops/cpCacheKlass.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/cpCacheKlass.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)cpCacheKlass.hpp 1.33 07/05/29 09:44:19 JVM" --#endif - /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -69,4 +66,3 @@ - const char* internal_name() const; - void oop_verify_on(oop obj, outputStream* st); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/cpCacheOop.cpp openjdk/hotspot/src/share/vm/oops/cpCacheOop.cpp ---- openjdk6/hotspot/src/share/vm/oops/cpCacheOop.cpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/cpCacheOop.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)cpCacheOop.cpp 1.79 07/05/29 09:44:19 JVM" --#endif - /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/oops/cpCacheOop.hpp openjdk/hotspot/src/share/vm/oops/cpCacheOop.hpp ---- openjdk6/hotspot/src/share/vm/oops/cpCacheOop.hpp 2008-07-10 22:04:32.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/cpCacheOop.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)cpCacheOop.hpp 1.74 07/05/29 09:44:19 JVM" --#endif - /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -326,4 +323,3 @@ - void adjust_method_entries(methodOop* old_methods, methodOop* new_methods, - int methods_length, bool * trace_name_printed); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/generateOopMap.cpp openjdk/hotspot/src/share/vm/oops/generateOopMap.cpp ---- openjdk6/hotspot/src/share/vm/oops/generateOopMap.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/generateOopMap.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)generateOopMap.cpp 1.141 07/05/05 17:06:03 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -2537,4 +2534,3 @@ - #endif - return methodHandle(THREAD, method()); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/generateOopMap.hpp openjdk/hotspot/src/share/vm/oops/generateOopMap.hpp ---- openjdk6/hotspot/src/share/vm/oops/generateOopMap.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/generateOopMap.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)generateOopMap.hpp 1.65 07/05/05 17:06:01 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -554,6 +551,3 @@ - - // Call compute_map(CHECK) to generate info. - }; -- -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/instanceKlass.cpp openjdk/hotspot/src/share/vm/oops/instanceKlass.cpp ---- openjdk6/hotspot/src/share/vm/oops/instanceKlass.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/instanceKlass.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)instanceKlass.cpp 1.323 08/06/19 10:32:38 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -768,13 +765,12 @@ - } - } - -- --void instanceKlass::do_local_static_fields(void f(fieldDescriptor*, oop), oop obj) { -+void instanceKlass::do_local_static_fields(FieldClosure* cl) { - fieldDescriptor fd; - int length = fields()->length(); - for (int i = 0; i < length; i += next_offset) { - fd.initialize(as_klassOop(), i); -- if (fd.is_static()) f(&fd, obj); -+ if (fd.is_static()) cl->do_field(&fd); - } - } - -@@ -795,16 +791,16 @@ - } - - --void instanceKlass::do_nonstatic_fields(void f(fieldDescriptor*, oop), oop obj) { -+void instanceKlass::do_nonstatic_fields(FieldClosure* cl) { - fieldDescriptor fd; - instanceKlass* super = superklass(); - if (super != NULL) { -- super->do_nonstatic_fields(f, obj); -+ super->do_nonstatic_fields(cl); - } - int length = fields()->length(); - for (int i = 0; i < length; i += next_offset) { - fd.initialize(as_klassOop(), i); -- if (!(fd.is_static())) f(&fd, obj); -+ if (!(fd.is_static())) cl->do_field(&fd); - } - } - -@@ -1101,6 +1097,7 @@ - _next = next; - _count = 1; - } -+ int count() { return _count; } - int increment() { _count += 1; return _count; } - int decrement() { _count -= 1; assert(_count >= 0, "don't underflow"); return _count; } - nmethodBucket* next() { return _next; } -@@ -1114,7 +1111,7 @@ - // are dependent on the klassOop that was passed in and mark them for - // deoptimization. Returns the number of nmethods found. - // --int instanceKlass::mark_dependent_nmethods(klassOop dependee) { -+int instanceKlass::mark_dependent_nmethods(DepChange& changes) { - assert_locked_or_safepoint(CodeCache_lock); - int found = 0; - nmethodBucket* b = _dependencies; -@@ -1122,11 +1119,12 @@ - nmethod* nm = b->get_nmethod(); - // since dependencies aren't removed until an nmethod becomes a zombie, - // the dependency list may contain nmethods which aren't alive. -- if (nm->is_alive() && !nm->is_marked_for_deoptimization() && nm->is_dependent_on(dependee)) { -+ if (nm->is_alive() && !nm->is_marked_for_deoptimization() && nm->check_dependency_on(changes)) { - if (TraceDependencies) { - ResourceMark rm; - tty->print_cr("Marked for deoptimization"); -- tty->print_cr(" dependee = %s", this->external_name()); -+ tty->print_cr(" context = %s", this->external_name()); -+ changes.print(); - nm->print(); - nm->print_dependencies(); - } -@@ -1193,6 +1191,39 @@ - } - - -+#ifndef PRODUCT -+void instanceKlass::print_dependent_nmethods(bool verbose) { -+ nmethodBucket* b = _dependencies; -+ int idx = 0; -+ while (b != NULL) { -+ nmethod* nm = b->get_nmethod(); -+ tty->print("[%d] count=%d { ", idx++, b->count()); -+ if (!verbose) { -+ nm->print_on(tty, "nmethod"); -+ tty->print_cr(" } "); -+ } else { -+ nm->print(); -+ nm->print_dependencies(); -+ tty->print_cr("--- } "); -+ } -+ b = b->next(); -+ } -+} -+ -+ -+bool instanceKlass::is_dependent_nmethod(nmethod* nm) { -+ nmethodBucket* b = _dependencies; -+ while (b != NULL) { -+ if (nm == b->get_nmethod()) { -+ return true; -+ } -+ b = b->next(); -+ } -+ return false; -+} -+#endif //PRODUCT -+ -+ - void instanceKlass::follow_static_fields() { - oop* start = start_of_static_fields(); - oop* end = start + static_oop_field_size(); -@@ -1924,25 +1955,18 @@ - } - - // ----------------------------------------------------------------------------------------------------- -- - #ifndef PRODUCT - - // Printing - --static void print_nonstatic_fields(outputStream* st, instanceKlass* ik, oop obj) { -- fieldDescriptor fd; -- instanceKlass* super = ik->superklass(); -- if (super != NULL) { -- print_nonstatic_fields(st, super, obj); -- } -- int length = ik->fields()->length(); -- for (int i = 0; i < length; i += instanceKlass::next_offset) { -- fd.initialize(ik->as_klassOop(), i); -- if (!(fd.is_static())) { -- st->print(" - "); -- fd.print_on_for(st, obj); -- st->cr(); -- } -+void FieldPrinter::do_field(fieldDescriptor* fd) { -+ if (fd->is_static() == (_obj == NULL)) { -+ _st->print(" - "); -+ fd->print_on(_st); -+ _st->cr(); -+ } else { -+ fd->print_on_for(_st, _obj); -+ _st->cr(); - } - } - -@@ -1967,7 +1991,8 @@ - } - - st->print_cr("fields:"); -- print_nonstatic_fields(st, this, obj); -+ FieldPrinter print_nonstatic_field(st, obj); -+ do_nonstatic_fields(&print_nonstatic_field); - - if (as_klassOop() == SystemDictionary::class_klass()) { - klassOop mirrored_klass = java_lang_Class::as_klassOop(obj); -@@ -2140,20 +2165,12 @@ - RC_TRACE(0x00000100, ("adding previous version ref for %s @%d, EMCP_cnt=%d", - ikh->external_name(), _previous_versions->length(), emcp_method_count)); - constantPoolHandle cp_h(ikh->constants()); -- jobject cp_ref; -- if (cp_h->is_shared()) { -- // a shared ConstantPool requires a regular reference; a weak -- // reference would be collectible -- cp_ref = JNIHandles::make_global(cp_h); -- } else { -- cp_ref = JNIHandles::make_weak_global(cp_h); -- } -+ jweak cp_ref = JNIHandles::make_weak_global(cp_h); - PreviousVersionNode * pv_node = NULL; - objArrayOop old_methods = ikh->methods(); - - if (emcp_method_count == 0) { -- // non-shared ConstantPool gets a weak reference -- pv_node = new PreviousVersionNode(cp_ref, !cp_h->is_shared(), NULL); -+ pv_node = new PreviousVersionNode(cp_ref, NULL); - RC_TRACE(0x00000400, - ("add: all methods are obsolete; flushing any EMCP weak refs")); - } else { -@@ -2173,8 +2190,7 @@ - } - } - } -- // non-shared ConstantPool gets a weak reference -- pv_node = new PreviousVersionNode(cp_ref, !cp_h->is_shared(), method_refs); -+ pv_node = new PreviousVersionNode(cp_ref, method_refs); - } - - _previous_versions->append(pv_node); -@@ -2192,7 +2208,7 @@ - // check the previous versions array for a GC'ed weak refs - pv_node = _previous_versions->at(i); - cp_ref = pv_node->prev_constant_pool(); -- assert(cp_ref != NULL, "cp ref was unexpectedly cleared"); -+ assert(cp_ref != NULL, "weak cp ref was unexpectedly cleared"); - if (cp_ref == NULL) { - delete pv_node; - _previous_versions->remove_at(i); -@@ -2265,7 +2281,7 @@ - // check the previous versions array for a GC'ed weak refs - pv_node = _previous_versions->at(j); - cp_ref = pv_node->prev_constant_pool(); -- assert(cp_ref != NULL, "cp ref was unexpectedly cleared"); -+ assert(cp_ref != NULL, "weak cp ref was unexpectedly cleared"); - if (cp_ref == NULL) { - delete pv_node; - _previous_versions->remove_at(j); -@@ -2363,8 +2379,8 @@ - // been GC'ed - PreviousVersionNode * pv_node = _previous_versions->at(i); - -- jobject cp_ref = pv_node->prev_constant_pool(); -- assert(cp_ref != NULL, "cp reference was unexpectedly cleared"); -+ jweak cp_ref = pv_node->prev_constant_pool(); -+ assert(cp_ref != NULL, "weak reference was unexpectedly cleared"); - if (cp_ref == NULL) { - continue; // robustness - } -@@ -2424,11 +2440,10 @@ - - // Construct a PreviousVersionNode entry for the array hung off - // the instanceKlass. --PreviousVersionNode::PreviousVersionNode(jobject prev_constant_pool, -- bool prev_cp_is_weak, GrowableArray* prev_EMCP_methods) { -+PreviousVersionNode::PreviousVersionNode(jweak prev_constant_pool, -+ GrowableArray* prev_EMCP_methods) { - - _prev_constant_pool = prev_constant_pool; -- _prev_cp_is_weak = prev_cp_is_weak; - _prev_EMCP_methods = prev_EMCP_methods; - } - -@@ -2436,11 +2451,7 @@ - // Destroy a PreviousVersionNode - PreviousVersionNode::~PreviousVersionNode() { - if (_prev_constant_pool != NULL) { -- if (_prev_cp_is_weak) { - JNIHandles::destroy_weak_global(_prev_constant_pool); -- } else { -- JNIHandles::destroy_global(_prev_constant_pool); -- } - } - - if (_prev_EMCP_methods != NULL) { -@@ -2460,8 +2471,8 @@ - _prev_constant_pool_handle = constantPoolHandle(); // NULL handle - _prev_EMCP_method_handles = NULL; - -- jobject cp_ref = pv_node->prev_constant_pool(); -- assert(cp_ref != NULL, "constant pool ref was unexpectedly cleared"); -+ jweak cp_ref = pv_node->prev_constant_pool(); -+ assert(cp_ref != NULL, "weak constant pool ref was unexpectedly cleared"); - if (cp_ref == NULL) { - return; // robustness - } -diff -ruNb openjdk6/hotspot/src/share/vm/oops/instanceKlass.hpp openjdk/hotspot/src/share/vm/oops/instanceKlass.hpp ---- openjdk6/hotspot/src/share/vm/oops/instanceKlass.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/instanceKlass.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)instanceKlass.hpp 1.200 08/06/19 10:32:39 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -79,10 +76,29 @@ - class jniIdMapBase; - class BreakpointInfo; - class fieldDescriptor; -+class DepChange; - class nmethodBucket; - class PreviousVersionNode; - class JvmtiCachedClassFieldMap; - -+// This is used in iterators below. -+class FieldClosure: public StackObj { -+public: -+ virtual void do_field(fieldDescriptor* fd) = 0; -+}; -+ -+#ifndef PRODUCT -+// Print fields. -+// If "obj" argument to constructor is NULL, prints static fields, otherwise prints non-static fields. -+class FieldPrinter: public FieldClosure { -+ oop _obj; -+ outputStream* _st; -+ public: -+ FieldPrinter(outputStream* st, oop obj = NULL) : _obj(obj), _st(st) {} -+ void do_field(fieldDescriptor* fd); -+}; -+#endif // !PRODUCT -+ - class instanceKlass: public Klass { - friend class VMStructs; - public: -@@ -478,7 +494,7 @@ - JNIid* jni_id_for(int offset); - - // maintenance of deoptimization dependencies -- int mark_dependent_nmethods(klassOop dependee); -+ int mark_dependent_nmethods(DepChange& changes); - void add_dependent_nmethod(nmethod* nm); - void remove_dependent_nmethod(nmethod* nm); - -@@ -525,9 +541,10 @@ - bool oop_is_instance_slow() const { return true; } - - // Iterators -- void do_local_static_fields(void f(fieldDescriptor*, oop), oop obj); -+ void do_local_static_fields(FieldClosure* cl); -+ void do_nonstatic_fields(FieldClosure* cl); // including inherited fields - void do_local_static_fields(void f(fieldDescriptor*, TRAPS), TRAPS); -- void do_nonstatic_fields(void f(fieldDescriptor*, oop), oop obj); // including inherited fields -+ - void methods_do(void f(methodOop method)); - void array_klasses_do(void f(klassOop k)); - void with_array_klasses_do(void f(klassOop k)); -@@ -718,6 +735,9 @@ - // Printing - void oop_print_on (oop obj, outputStream* st); - void oop_print_value_on(oop obj, outputStream* st); -+ -+ void print_dependent_nmethods(bool verbose = false); -+ bool is_dependent_nmethod(nmethod* nm); - #endif - - public: -@@ -818,20 +838,11 @@ - // A collection point for interesting information about the previous - // version(s) of an instanceKlass. This class uses weak references to - // the information so that the information may be collected as needed --// by the system. If the information is shared, then a regular --// reference must be used because a weak reference would be seen as --// collectible. A GrowableArray of PreviousVersionNodes is attached -+// by the system. A GrowableArray of PreviousVersionNodes is attached - // to the instanceKlass as needed. See PreviousVersionWalker below. - class PreviousVersionNode : public CHeapObj { - private: -- // A shared ConstantPool is never collected so we'll always have -- // a reference to it so we can update items in the cache. We'll -- // have a weak reference to a non-shared ConstantPool until all -- // of the methods (EMCP or obsolete) have been collected; the -- // non-shared ConstantPool becomes collectible at that point. -- jobject _prev_constant_pool; // regular or weak reference -- bool _prev_cp_is_weak; // true if not a shared ConstantPool -- -+ jweak _prev_constant_pool; - // If the previous version of the instanceKlass doesn't have any - // EMCP methods, then _prev_EMCP_methods will be NULL. If all the - // EMCP methods have been collected, then _prev_EMCP_methods can -@@ -839,10 +850,10 @@ - GrowableArray* _prev_EMCP_methods; - - public: -- PreviousVersionNode(jobject prev_constant_pool, bool prev_cp_is_weak, -+ PreviousVersionNode(jweak prev_constant_pool, - GrowableArray* prev_EMCP_methods); - ~PreviousVersionNode(); -- jobject prev_constant_pool() const { -+ jweak prev_constant_pool() const { - return _prev_constant_pool; - } - GrowableArray* prev_EMCP_methods() const { -diff -ruNb openjdk6/hotspot/src/share/vm/oops/instanceKlassKlass.cpp openjdk/hotspot/src/share/vm/oops/instanceKlassKlass.cpp ---- openjdk6/hotspot/src/share/vm/oops/instanceKlassKlass.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/instanceKlassKlass.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)instanceKlassKlass.cpp 1.156 07/05/29 09:44:20 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -473,23 +470,6 @@ - - // Printing - --static outputStream* printing_stream = NULL; -- --static void print_nonstatic_field(fieldDescriptor* fd, oop obj) { -- assert(printing_stream != NULL, "Invalid printing stream"); -- printing_stream->print(" - "); -- fd->print_on(printing_stream); -- printing_stream->cr(); --} -- --static void print_static_field(fieldDescriptor* fd, oop obj) { -- assert(printing_stream != NULL, "Invalid printing stream"); -- printing_stream->print(" - "); -- fd->print_on_for(printing_stream, obj); -- printing_stream->cr(); --} -- -- - static const char* state_names[] = { - "unparseable_by_gc", "allocated", "loaded", "linked", "being_initialized", "fully_initialized", "initialization_error" - }; -@@ -584,11 +564,11 @@ - st->print(" - vtable length %d (start addr: " INTPTR_FORMAT ")", ik->vtable_length(), ik->start_of_vtable()); st->cr(); - st->print(" - itable length %d (start addr: " INTPTR_FORMAT ")", ik->itable_length(), ik->start_of_itable()); st->cr(); - st->print_cr(" - static fields:"); -- printing_stream = st; -- ik->do_local_static_fields(print_static_field, obj); -+ FieldPrinter print_static_field(st); -+ ik->do_local_static_fields(&print_static_field); - st->print_cr(" - non-static fields:"); -- ik->do_nonstatic_fields(print_nonstatic_field, NULL); -- printing_stream = NULL; -+ FieldPrinter print_nonstatic_field(st, obj); -+ ik->do_nonstatic_fields(&print_nonstatic_field); - - st->print(" - static oop maps: "); - if (ik->static_oop_field_size() > 0) { -@@ -827,4 +807,3 @@ - assert(ik->transitive_interfaces() == NULL, "just checking"); - ik->set_transitive_interfaces((objArrayOop) obj); // Temporarily set transitive_interfaces to point to self - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/instanceKlassKlass.hpp openjdk/hotspot/src/share/vm/oops/instanceKlassKlass.hpp ---- openjdk6/hotspot/src/share/vm/oops/instanceKlassKlass.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/instanceKlassKlass.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)instanceKlassKlass.hpp 1.54 07/05/29 09:44:21 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -87,4 +84,3 @@ - bool oop_partially_loaded(oop obj) const; - void oop_set_partially_loaded(oop obj); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/instanceOop.cpp openjdk/hotspot/src/share/vm/oops/instanceOop.cpp ---- openjdk6/hotspot/src/share/vm/oops/instanceOop.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/instanceOop.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)instanceOop.cpp 1.14 07/05/05 17:06:03 JVM" --#endif - /* - * Copyright 1997 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -29,4 +26,3 @@ - # include "incls/_instanceOop.cpp.incl" - - // <> -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/instanceOop.hpp openjdk/hotspot/src/share/vm/oops/instanceOop.hpp ---- openjdk6/hotspot/src/share/vm/oops/instanceOop.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/instanceOop.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)instanceOop.hpp 1.15 07/05/05 17:06:04 JVM" --#endif - /* - * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -32,5 +29,3 @@ - public: - static int header_size() { return sizeof(instanceOopDesc)/HeapWordSize; } - }; -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/instanceRefKlass.cpp openjdk/hotspot/src/share/vm/oops/instanceRefKlass.cpp ---- openjdk6/hotspot/src/share/vm/oops/instanceRefKlass.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/instanceRefKlass.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)instanceRefKlass.cpp 1.90 07/05/29 09:44:20 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/oops/instanceRefKlass.hpp openjdk/hotspot/src/share/vm/oops/instanceRefKlass.hpp ---- openjdk6/hotspot/src/share/vm/oops/instanceRefKlass.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/instanceRefKlass.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)instanceRefKlass.hpp 1.62 07/05/29 09:44:21 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/oops/klass.cpp openjdk/hotspot/src/share/vm/oops/klass.cpp ---- openjdk6/hotspot/src/share/vm/oops/klass.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/klass.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)klass.cpp 1.119 07/05/05 17:06:00 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/oops/klass.hpp openjdk/hotspot/src/share/vm/oops/klass.hpp ---- openjdk6/hotspot/src/share/vm/oops/klass.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/klass.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)klass.hpp 1.142 07/05/29 09:44:17 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -768,4 +765,3 @@ - void verify_vtable_index(int index); - #endif - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/klass.inline.hpp openjdk/hotspot/src/share/vm/oops/klass.inline.hpp ---- openjdk6/hotspot/src/share/vm/oops/klass.inline.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/klass.inline.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)klass.inline.hpp 1.5 07/05/05 17:06:04 JVM" --#endif - /* - * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/oops/klassKlass.cpp openjdk/hotspot/src/share/vm/oops/klassKlass.cpp ---- openjdk6/hotspot/src/share/vm/oops/klassKlass.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/klassKlass.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)klassKlass.cpp 1.69 07/05/29 09:44:21 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -97,8 +94,8 @@ - // The following are in the perm gen and are treated - // specially in a later phase of a perm gen collection; ... - assert(oop(k)->is_perm(), "should be in perm"); -- assert(oop(k->adr_subklass())->is_perm(), "should be in perm"); -- assert(oop(k->adr_next_sibling())->is_perm(), "should be in perm"); -+ assert(oop(k->subklass())->is_perm_or_null(), "should be in perm"); -+ assert(oop(k->next_sibling())->is_perm_or_null(), "should be in perm"); - // ... don't scan them normally, but remember this klassKlass - // for later (see, for instance, oop_follow_contents above - // for what MarkSweep does with it. -diff -ruNb openjdk6/hotspot/src/share/vm/oops/klassKlass.hpp openjdk/hotspot/src/share/vm/oops/klassKlass.hpp ---- openjdk6/hotspot/src/share/vm/oops/klassKlass.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/klassKlass.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)klassKlass.hpp 1.44 07/05/29 09:44:21 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -82,4 +79,3 @@ - const char* internal_name() const; - void oop_verify_on(oop obj, outputStream* st); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/klassOop.cpp openjdk/hotspot/src/share/vm/oops/klassOop.cpp ---- openjdk6/hotspot/src/share/vm/oops/klassOop.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/klassOop.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)klassOop.cpp 1.14 07/05/05 17:06:04 JVM" --#endif - /* - * Copyright 1997 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -27,4 +24,3 @@ - - # include "incls/_precompiled.incl" - # include "incls/_klassOop.cpp.incl" -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/klassOop.hpp openjdk/hotspot/src/share/vm/oops/klassOop.hpp ---- openjdk6/hotspot/src/share/vm/oops/klassOop.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/klassOop.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)klassOop.hpp 1.19 07/05/05 17:06:04 JVM" --#endif - /* - * Copyright 1997-2002 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -45,6 +42,3 @@ - // returns the Klass part containing dispatching behavior - Klass* klass_part() { return (Klass*)((address)this + klass_part_offset_in_bytes()); } - }; -- -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/klassPS.hpp openjdk/hotspot/src/share/vm/oops/klassPS.hpp ---- openjdk6/hotspot/src/share/vm/oops/klassPS.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/klassPS.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)klassPS.hpp 1.1 07/05/14 06:13:07 JVM" --#endif - /* - * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/oops/klassVtable.cpp openjdk/hotspot/src/share/vm/oops/klassVtable.cpp ---- openjdk6/hotspot/src/share/vm/oops/klassVtable.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/klassVtable.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)klassVtable.cpp 1.146 07/07/19 12:19:09 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -738,7 +735,7 @@ - } - } - -- // The length of the itable was either zero, or it has not yet been initialized. -+ // This lenght of the itable was either zero, or it has not yet been initialized. - _table_offset = 0; - _size_offset_table = 0; - _size_method_table = 0; -@@ -873,19 +870,16 @@ - - // Initialization - void klassItable::initialize_itable(bool checkconstraints, TRAPS) { -- // Cannot be setup doing bootstrapping, interfaces don't have -- // itables, and klass with only ones entry have empty itables -- if (Universe::is_bootstrapping() || -- _klass->is_interface() || -- _klass->itable_length() == itableOffsetEntry::size()) return; -- -- // There's alway an extra itable entry so we can null-terminate it. -- guarantee(size_offset_table() >= 1, "too small"); -- int num_interfaces = size_offset_table() - 1; -+ // Cannot be setup doing bootstrapping -+ if (Universe::is_bootstrapping()) return; -+ -+ int num_interfaces = nof_interfaces(); - if (num_interfaces > 0) { -- if (TraceItables) tty->print_cr("%3d: Initializing itables for %s", ++initialize_count, -- _klass->name()->as_C_string()); -+ if (TraceItables) tty->print_cr("%3d: Initializing itables for %s", ++initialize_count, _klass->name()->as_C_string()); - -+ // In debug mode, we got an extra NULL/NULL entry -+ debug_only(num_interfaces--); -+ assert(num_interfaces > 0, "to few interfaces in offset itable"); - - // Interate through all interfaces - int i; -@@ -896,10 +890,12 @@ - initialize_itable_for_interface(ioe->offset(), interf_h, checkconstraints, CHECK); - } - -- } -+#ifdef ASSERT - // Check that the last entry is empty -- itableOffsetEntry* ioe = offset_entry(size_offset_table() - 1); -- guarantee(ioe->interface_klass() == NULL && ioe->offset() == 0, "terminator entry missing"); -+ itableOffsetEntry* ioe = offset_entry(i); -+ assert(ioe->interface_klass() == NULL && ioe->offset() == 0, "terminator entry missing"); -+#endif -+ } - } - - -@@ -976,7 +972,7 @@ - } - } - --// Update entry for specific methodOop -+// Update entry for specic methodOop - void klassItable::initialize_with_method(methodOop m) { - itableMethodEntry* ime = method_entry(0); - for(int i = 0; i < _size_method_table; i++) { -@@ -1089,8 +1085,12 @@ - CountInterfacesClosure cic; - visit_all_interfaces(transitive_interfaces(), &cic); - -- // There's alway an extra itable entry so we can null-terminate it. -- int itable_size = calc_itable_size(cic.nof_interfaces() + 1, cic.nof_methods()); -+ // Add one extra entry in debug mode, so we can null-terminate the table -+ int nof_methods = cic.nof_methods(); -+ int nof_interfaces = cic.nof_interfaces(); -+ debug_only(if (nof_interfaces > 0) nof_interfaces++); -+ -+ int itable_size = calc_itable_size(nof_interfaces, nof_methods); - - // Statistics - update_stats(itable_size * HeapWordSize); -@@ -1110,8 +1110,8 @@ - int nof_methods = cic.nof_methods(); - int nof_interfaces = cic.nof_interfaces(); - -- // Add one extra entry so we can null-terminate the table -- nof_interfaces++; -+ // Add one extra entry in debug mode, so we can null-terminate the table -+ debug_only(if (nof_interfaces > 0) nof_interfaces++); - - assert(compute_itable_size(objArrayHandle(klass->transitive_interfaces())) == - calc_itable_size(nof_interfaces, nof_methods), -@@ -1320,5 +1320,3 @@ - } - - #endif // PRODUCT -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/klassVtable.hpp openjdk/hotspot/src/share/vm/oops/klassVtable.hpp ---- openjdk6/hotspot/src/share/vm/oops/klassVtable.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/klassVtable.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)klassVtable.hpp 1.62 07/07/19 12:19:09 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -262,7 +259,7 @@ - itableMethodEntry* method_entry(int i) { assert(0 <= i && i <= _size_method_table, "index out of bounds"); - return &((itableMethodEntry*)method_start())[i]; } - -- int size_offset_table() { return _size_offset_table; } -+ int nof_interfaces() { return _size_offset_table; } - - // Initialization - void initialize_itable(bool checkconstraints, TRAPS); -diff -ruNb openjdk6/hotspot/src/share/vm/oops/markOop.cpp openjdk/hotspot/src/share/vm/oops/markOop.cpp ---- openjdk6/hotspot/src/share/vm/oops/markOop.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/markOop.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)markOop.cpp 1.29 08/06/19 12:45:44 JVM" --#endif - /* - * Copyright 1997-1999 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -40,32 +37,3 @@ - st->print("age %d)", age()); - } - } -- -- --// Give advice about whether the oop that contains this markOop --// should be cached or not. --bool markOopDesc::should_not_be_cached() const { -- // the cast is because decode_pointer() isn't marked const -- if (is_marked() && ((markOopDesc *)this)->decode_pointer() != NULL) { -- // If the oop containing this markOop is being forwarded, then -- // we are in the middle of GC and we do not want the containing -- // oop to be added to a cache. We have no way of knowing whether -- // the cache has already been visited by the current GC phase so -- // we don't know whether the forwarded oop will be properly -- // processed in this phase. If the forwarded oop is not properly -- // processed, then we'll see strange crashes or asserts during -- // the next GC run because the markOop will contain an unexpected -- // value. -- // -- // This situation has been seen when we are GC'ing a methodOop -- // because we use the methodOop while we're GC'ing it. Scary -- // stuff. Some of the uses the methodOop cause the methodOop to -- // be added to the OopMapCache in the instanceKlass as a side -- // effect. This check lets the cache maintainer know when a -- // cache addition would not be safe. -- return true; -- } -- -- // caching the containing oop should be just fine -- return false; --} -diff -ruNb openjdk6/hotspot/src/share/vm/oops/markOop.hpp openjdk/hotspot/src/share/vm/oops/markOop.hpp ---- openjdk6/hotspot/src/share/vm/oops/markOop.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/markOop.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)markOop.hpp 1.65 08/06/19 12:45:45 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -360,7 +357,4 @@ - - // Recover address of oop from encoded form used in mark - inline void* decode_pointer() { if (UseBiasedLocking && has_bias_pattern()) return NULL; return clear_lock_bits(); } -- -- // see the definition in markOop.cpp for the gory details -- bool should_not_be_cached() const; - }; -diff -ruNb openjdk6/hotspot/src/share/vm/oops/markOop.inline.hpp openjdk/hotspot/src/share/vm/oops/markOop.inline.hpp ---- openjdk6/hotspot/src/share/vm/oops/markOop.inline.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/markOop.inline.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)markOop.inline.hpp 1.7 07/05/05 17:06:04 JVM" --#endif - /* - * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/oops/methodDataKlass.cpp openjdk/hotspot/src/share/vm/oops/methodDataKlass.cpp ---- openjdk6/hotspot/src/share/vm/oops/methodDataKlass.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/methodDataKlass.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)methodDataKlass.cpp 1.36 07/05/29 09:44:22 JVM" --#endif - /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -239,4 +236,3 @@ - guarantee(m->is_perm(), "should be in permspace"); - m->verify_data_on(st); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/methodDataKlass.hpp openjdk/hotspot/src/share/vm/oops/methodDataKlass.hpp ---- openjdk6/hotspot/src/share/vm/oops/methodDataKlass.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/methodDataKlass.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)methodDataKlass.hpp 1.30 07/05/29 09:44:23 JVM" --#endif - /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/oops/methodDataOop.cpp openjdk/hotspot/src/share/vm/oops/methodDataOop.cpp ---- openjdk6/hotspot/src/share/vm/oops/methodDataOop.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/methodDataOop.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)methodDataOop.cpp 1.51 07/05/29 09:44:22 JVM" --#endif - /* - * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/oops/methodDataOop.hpp openjdk/hotspot/src/share/vm/oops/methodDataOop.hpp ---- openjdk6/hotspot/src/share/vm/oops/methodDataOop.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/methodDataOop.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)methodDataOop.hpp 1.53 07/05/29 09:44:23 JVM" --#endif - /* - * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -189,6 +186,9 @@ - intptr_t cell_at(int index) { - return _cells[index]; - } -+ intptr_t* adr_cell_at(int index) { -+ return &_cells[index]; -+ } - oop* adr_oop_at(int index) { - return (oop*)&(_cells[index]); - } -@@ -573,6 +573,14 @@ - uint taken() { - return uint_at(taken_off_set); - } -+ // Saturating counter -+ uint inc_taken() { -+ uint cnt = taken() + 1; -+ // Did we wrap? Will compiler screw us?? -+ if (cnt == 0) cnt--; -+ set_uint_at(taken_off_set, cnt); -+ return cnt; -+ } - - int displacement() { - return int_at(displacement_off_set); -@@ -858,6 +866,14 @@ - return uint_at(not_taken_off_set); - } - -+ uint inc_not_taken() { -+ uint cnt = not_taken() + 1; -+ // Did we wrap? Will compiler screw us?? -+ if (cnt == 0) cnt--; -+ set_uint_at(not_taken_off_set, cnt); -+ return cnt; -+ } -+ - // Code generation support - static ByteSize not_taken_offset() { - return cell_offset(not_taken_off_set); -diff -ruNb openjdk6/hotspot/src/share/vm/oops/methodKlass.cpp openjdk/hotspot/src/share/vm/oops/methodKlass.cpp ---- openjdk6/hotspot/src/share/vm/oops/methodKlass.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/methodKlass.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)methodKlass.cpp 1.120 07/05/29 09:44:23 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -362,4 +359,3 @@ - constMethodKlass* ck = constMethodKlass::cast(xconst->klass()); - ck->oop_set_partially_loaded(xconst); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/methodKlass.hpp openjdk/hotspot/src/share/vm/oops/methodKlass.hpp ---- openjdk6/hotspot/src/share/vm/oops/methodKlass.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/methodKlass.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)methodKlass.hpp 1.49 07/05/29 09:44:23 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -85,4 +82,3 @@ - bool oop_partially_loaded(oop obj) const; - void oop_set_partially_loaded(oop obj); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/methodOop.cpp openjdk/hotspot/src/share/vm/oops/methodOop.cpp ---- openjdk6/hotspot/src/share/vm/oops/methodOop.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/methodOop.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)methodOop.cpp 1.313 08/06/19 12:45:47 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -218,8 +215,8 @@ - - - void methodOopDesc::set_interpreter_kind() { -- int kind = AbstractInterpreter::method_kind(methodOop(this)); -- assert(kind != AbstractInterpreter::invalid, -+ int kind = Interpreter::method_kind(methodOop(this)); -+ assert(kind != Interpreter::invalid, - "interpreter entry must be valid"); - set_interpreter_kind(kind); - } -@@ -315,7 +312,7 @@ - - #ifdef CC_INTERP - void methodOopDesc::set_result_index(BasicType type) { -- _result_index = AbstractInterpreter::BasicType_as_index(type); -+ _result_index = Interpreter::BasicType_as_index(type); - } - #endif - -@@ -650,7 +647,7 @@ - - // Setup interpreter entrypoint - assert(this == h_method(), "wrong h_method()" ); -- address entry = AbstractInterpreter::entry_for_method(h_method); -+ address entry = Interpreter::entry_for_method(h_method); - assert(entry != NULL, "interpreter entry must be non-null"); - // Sets both _i2i_entry and _from_interpreted_entry - set_interpreter_entry(entry); -@@ -768,28 +765,6 @@ - } - - --// give advice about whether this methodOop should be cached or not --bool methodOopDesc::should_not_be_cached() const { -- if (is_old()) { -- // This method has been redefined. It is either EMCP or obsolete -- // and we don't want to cache it because that would pin the method -- // down and prevent it from being collectible if and when it -- // finishes executing. -- return true; -- } -- -- if (mark()->should_not_be_cached()) { -- // It is either not safe or not a good idea to cache this -- // method at this time because of the state of the embedded -- // markOop. See markOop.cpp for the gory details. -- return true; -- } -- -- // caching this method should be just fine -- return false; --} -- -- - methodHandle methodOopDesc:: clone_with_new_data(methodHandle m, u_char* new_code, int new_code_length, - u_char* new_compressed_linenumber_table, int new_compressed_linenumber_size, TRAPS) { - // Code below does not work for native methods - they should never get rewritten anyway -@@ -1080,18 +1055,18 @@ - } - - --void methodOopDesc::print_codes() const { -- print_codes(0, code_size()); -+void methodOopDesc::print_codes_on(outputStream* st) const { -+ print_codes_on(0, code_size(), st); - } - --void methodOopDesc::print_codes(int from, int to) const { -+void methodOopDesc::print_codes_on(int from, int to, outputStream* st) const { - Thread *thread = Thread::current(); - ResourceMark rm(thread); - methodHandle mh (thread, (methodOop)this); - BytecodeStream s(mh); - s.set_interval(from, to); - BytecodeTracer::set_closure(BytecodeTracer::std_closure()); -- while (s.next() >= 0) BytecodeTracer::trace(mh, s.bcp()); -+ while (s.next() >= 0) BytecodeTracer::trace(mh, s.bcp(), st); - } - #endif // not PRODUCT - -diff -ruNb openjdk6/hotspot/src/share/vm/oops/methodOop.hpp openjdk/hotspot/src/share/vm/oops/methodOop.hpp ---- openjdk6/hotspot/src/share/vm/oops/methodOop.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/methodOop.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)methodOop.hpp 1.220 08/06/19 12:45:48 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -368,8 +365,10 @@ - address code_base() const { return constMethod()->code_base(); } - bool contains(address bcp) const { return constMethod()->contains(bcp); } - -- void print_codes() const PRODUCT_RETURN; // prints byte codes -- void print_codes(int from, int to) const PRODUCT_RETURN; -+ // prints byte codes -+ void print_codes() const { print_codes_on(tty); } -+ void print_codes_on(outputStream* st) const PRODUCT_RETURN; -+ void print_codes_on(int from, int to, outputStream* st) const PRODUCT_RETURN; - - // checked exceptions - int checked_exceptions_length() const -@@ -396,6 +395,7 @@ - void compute_size_of_parameters(Thread *thread); // word size of parameters (receiver if any + arguments) - symbolOop klass_name() const; // returns the name of the method holder - BasicType result_type() const; // type of the method result -+ int result_type_index() const; // type index of the method result - bool is_returning_oop() const { BasicType r = result_type(); return (r == T_OBJECT || r == T_ARRAY); } - bool is_returning_fp() const { BasicType r = result_type(); return (r == T_FLOAT || r == T_DOUBLE); } - -@@ -524,8 +524,6 @@ - void set_is_old() { _access_flags.set_is_old(); } - bool is_obsolete() const { return access_flags().is_obsolete(); } - void set_is_obsolete() { _access_flags.set_is_obsolete(); } -- // see the definition in methodOop.cpp for the gory details -- bool should_not_be_cached() const; - - // JVMTI Native method prefixing support: - bool is_prefixed_native() const { return access_flags().is_prefixed_native(); } -@@ -739,5 +737,3 @@ - void set(methodOop method); - void clear(methodOop method); - }; -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/objArrayKlass.cpp openjdk/hotspot/src/share/vm/oops/objArrayKlass.cpp ---- openjdk6/hotspot/src/share/vm/oops/objArrayKlass.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/objArrayKlass.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)objArrayKlass.cpp 1.147 07/05/29 09:44:23 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/oops/objArrayKlass.hpp openjdk/hotspot/src/share/vm/oops/objArrayKlass.hpp ---- openjdk6/hotspot/src/share/vm/oops/objArrayKlass.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/objArrayKlass.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)objArrayKlass.hpp 1.87 07/05/29 09:44:23 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -129,4 +126,3 @@ - void oop_verify_old_oop(oop obj, oop* p, bool allow_dirty); - - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/objArrayKlassKlass.cpp openjdk/hotspot/src/share/vm/oops/objArrayKlassKlass.cpp ---- openjdk6/hotspot/src/share/vm/oops/objArrayKlassKlass.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/objArrayKlassKlass.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)objArrayKlassKlass.cpp 1.79 07/05/29 09:44:24 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -309,4 +306,3 @@ - Klass* bk = Klass::cast(oak->bottom_klass()); - guarantee(bk->oop_is_instance() || bk->oop_is_typeArray(), "invalid bottom klass"); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/objArrayKlassKlass.hpp openjdk/hotspot/src/share/vm/oops/objArrayKlassKlass.hpp ---- openjdk6/hotspot/src/share/vm/oops/objArrayKlassKlass.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/objArrayKlassKlass.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)objArrayKlassKlass.hpp 1.48 07/05/29 09:44:24 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -80,4 +77,3 @@ - void oop_verify_on(oop obj, outputStream* st); - - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/objArrayOop.cpp openjdk/hotspot/src/share/vm/oops/objArrayOop.cpp ---- openjdk6/hotspot/src/share/vm/oops/objArrayOop.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/objArrayOop.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)objArrayOop.cpp 1.14 07/05/05 17:06:07 JVM" --#endif - /* - * Copyright 1997 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -29,4 +26,3 @@ - # include "incls/_objArrayOop.cpp.incl" - - // <> -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/objArrayOop.hpp openjdk/hotspot/src/share/vm/oops/objArrayOop.hpp ---- openjdk6/hotspot/src/share/vm/oops/objArrayOop.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/objArrayOop.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)objArrayOop.hpp 1.29 07/05/05 17:06:07 JVM" --#endif - /* - * Copyright 1997-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/oops/oop.cpp openjdk/hotspot/src/share/vm/oops/oop.cpp ---- openjdk6/hotspot/src/share/vm/oops/oop.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/oop.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)oop.cpp 1.99 07/05/29 09:44:21 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/oops/oop.hpp openjdk/hotspot/src/share/vm/oops/oop.hpp ---- openjdk6/hotspot/src/share/vm/oops/oop.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/oop.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)oop.hpp 1.116 07/05/29 09:44:21 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -254,7 +251,7 @@ - #endif // SERIALGC - - bool is_perm() const; -- bool is_perm_and_alloced() const; -+ bool is_perm_or_null() const; - bool is_shared() const; - bool is_shared_readonly() const; - bool is_shared_readwrite() const; -diff -ruNb openjdk6/hotspot/src/share/vm/oops/oop.inline.hpp openjdk/hotspot/src/share/vm/oops/oop.inline.hpp ---- openjdk6/hotspot/src/share/vm/oops/oop.inline.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/oop.inline.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)oop.inline.hpp 1.141 07/06/12 15:40:38 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -202,7 +199,8 @@ - // technique, or when G1 is integrated (and currently uses this array chunking - // technique) we will need to suitably modify the assertion. - assert((s == klass->oop_size(this)) || -- ((UseParNewGC && Universe::heap()->is_gc_active()) && -+ (((UseParNewGC || UseParallelGC) && -+ Universe::heap()->is_gc_active()) && - (is_typeArray() || - (is_objArray() && is_forwarded()))), - "wrong array object size"); -diff -ruNb openjdk6/hotspot/src/share/vm/oops/oop.inline2.hpp openjdk/hotspot/src/share/vm/oops/oop.inline2.hpp ---- openjdk6/hotspot/src/share/vm/oops/oop.inline2.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/oop.inline2.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)oop.inline2.hpp 1.12 07/05/05 17:06:07 JVM" --#endif - /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -33,13 +30,7 @@ - return Universe::heap()->is_in_permanent(this); - } - --// is_perm only verifies that oop is in the reserved space for --// the perm gen. Things like forte stackwalking need something that --// assures us that the pointer is in the commited area so we don't --// segv checking suspicious frame contents. -- --inline bool oopDesc::is_perm_and_alloced() const { -- return Universe::heap()->is_permanent(this); -+// Check for NULL also. -+inline bool oopDesc::is_perm_or_null() const { -+ return this == NULL || is_perm(); - } -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/oop.pcgc.inline.hpp openjdk/hotspot/src/share/vm/oops/oop.pcgc.inline.hpp ---- openjdk6/hotspot/src/share/vm/oops/oop.pcgc.inline.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/oop.pcgc.inline.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)oop.pcgc.inline.hpp 1.16 07/05/29 09:44:24 JVM" --#endif - /* - * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/oops/oop.psgc.inline.hpp openjdk/hotspot/src/share/vm/oops/oop.psgc.inline.hpp ---- openjdk6/hotspot/src/share/vm/oops/oop.psgc.inline.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/oop.psgc.inline.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)oop.psgc.inline.hpp 1.17 07/05/05 17:06:07 JVM" --#endif - /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -44,4 +41,3 @@ - } - // Else skip it. The typeArrayKlass in the header never needs scavenging. - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/oopsHierarchy.cpp openjdk/hotspot/src/share/vm/oops/oopsHierarchy.cpp ---- openjdk6/hotspot/src/share/vm/oops/oopsHierarchy.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/oopsHierarchy.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)oopsHierarchy.cpp 1.7 07/05/05 17:06:08 JVM" --#endif - /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/oops/oopsHierarchy.hpp openjdk/hotspot/src/share/vm/oops/oopsHierarchy.hpp ---- openjdk6/hotspot/src/share/vm/oops/oopsHierarchy.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/oopsHierarchy.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)oopsHierarchy.hpp 1.31 07/05/17 15:57:10 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/oops/symbolKlass.cpp openjdk/hotspot/src/share/vm/oops/symbolKlass.cpp ---- openjdk6/hotspot/src/share/vm/oops/symbolKlass.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/symbolKlass.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)symbolKlass.cpp 1.66 07/05/29 09:44:24 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/oops/symbolKlass.hpp openjdk/hotspot/src/share/vm/oops/symbolKlass.hpp ---- openjdk6/hotspot/src/share/vm/oops/symbolKlass.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/symbolKlass.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)symbolKlass.hpp 1.42 07/05/29 09:44:24 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -75,4 +72,3 @@ - #endif - const char* internal_name() const; - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/symbolOop.cpp openjdk/hotspot/src/share/vm/oops/symbolOop.cpp ---- openjdk6/hotspot/src/share/vm/oops/symbolOop.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/symbolOop.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)symbolOop.cpp 1.28 07/05/05 17:06:08 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/oops/symbolOop.hpp openjdk/hotspot/src/share/vm/oops/symbolOop.hpp ---- openjdk6/hotspot/src/share/vm/oops/symbolOop.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/symbolOop.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)symbolOop.hpp 1.40 07/05/05 17:06:07 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -119,4 +116,3 @@ - return (((uintptr_t)this < (uintptr_t)other) ? -1 - : ((uintptr_t)this == (uintptr_t) other) ? 0 : 1); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/typeArrayKlass.cpp openjdk/hotspot/src/share/vm/oops/typeArrayKlass.cpp ---- openjdk6/hotspot/src/share/vm/oops/typeArrayKlass.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/typeArrayKlass.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)typeArrayKlass.cpp 1.125 07/05/29 09:44:24 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/oops/typeArrayKlass.hpp openjdk/hotspot/src/share/vm/oops/typeArrayKlass.hpp ---- openjdk6/hotspot/src/share/vm/oops/typeArrayKlass.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/typeArrayKlass.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)typeArrayKlass.hpp 1.69 07/05/29 09:44:25 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/oops/typeArrayKlassKlass.cpp openjdk/hotspot/src/share/vm/oops/typeArrayKlassKlass.cpp ---- openjdk6/hotspot/src/share/vm/oops/typeArrayKlassKlass.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/typeArrayKlassKlass.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)typeArrayKlassKlass.cpp 1.30 07/05/05 17:06:08 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -71,4 +68,3 @@ - const char* typeArrayKlassKlass::internal_name() const { - return "{type array class}"; - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/typeArrayKlassKlass.hpp openjdk/hotspot/src/share/vm/oops/typeArrayKlassKlass.hpp ---- openjdk6/hotspot/src/share/vm/oops/typeArrayKlassKlass.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/typeArrayKlassKlass.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)typeArrayKlassKlass.hpp 1.24 07/05/05 17:06:08 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -59,4 +56,3 @@ - public: - const char* internal_name() const; - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/typeArrayOop.cpp openjdk/hotspot/src/share/vm/oops/typeArrayOop.cpp ---- openjdk6/hotspot/src/share/vm/oops/typeArrayOop.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/typeArrayOop.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)typeArrayOop.cpp 1.14 07/05/05 17:06:08 JVM" --#endif - /* - * Copyright 1997 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -29,4 +26,3 @@ - # include "incls/_typeArrayOop.cpp.incl" - - // <> -- -diff -ruNb openjdk6/hotspot/src/share/vm/oops/typeArrayOop.hpp openjdk/hotspot/src/share/vm/oops/typeArrayOop.hpp ---- openjdk6/hotspot/src/share/vm/oops/typeArrayOop.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/oops/typeArrayOop.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)typeArrayOop.hpp 1.46 07/05/05 17:06:08 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/opto/addnode.cpp openjdk/hotspot/src/share/vm/opto/addnode.cpp ---- openjdk6/hotspot/src/share/vm/opto/addnode.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/addnode.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)addnode.cpp 1.141 07/05/05 17:06:10 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/opto/addnode.hpp openjdk/hotspot/src/share/vm/opto/addnode.hpp ---- openjdk6/hotspot/src/share/vm/opto/addnode.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/addnode.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)addnode.hpp 1.58 07/05/05 17:06:10 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/opto/adlcVMDeps.hpp openjdk/hotspot/src/share/vm/opto/adlcVMDeps.hpp ---- openjdk6/hotspot/src/share/vm/opto/adlcVMDeps.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/adlcVMDeps.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)adlcVMDeps.hpp 1.19 07/05/05 17:06:10 JVM" --#endif - /* - * Copyright 1998-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/opto/block.cpp openjdk/hotspot/src/share/vm/opto/block.cpp ---- openjdk6/hotspot/src/share/vm/opto/block.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/block.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)block.cpp 1.169 07/05/17 15:57:15 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -134,7 +131,7 @@ - int Block::is_Empty() const { - - // Root or start block is not considered empty -- if (_nodes[0]->is_Root() || _nodes[0]->is_Start()) { -+ if (head()->is_Root() || head()->is_Start()) { - return not_empty; - } - -@@ -167,16 +164,45 @@ - return not_empty; - } - -+//------------------------------has_uncommon_code------------------------------ -+// Return true if the block's code implies that it is not likely to be -+// executed infrequently. Check to see if the block ends in a Halt or -+// a low probability call. -+bool Block::has_uncommon_code() const { -+ Node* en = end(); -+ -+ if (en->is_Goto()) -+ en = en->in(0); -+ if (en->is_Catch()) -+ en = en->in(0); -+ if (en->is_Proj() && en->in(0)->is_MachCall()) { -+ MachCallNode* call = en->in(0)->as_MachCall(); -+ if (call->cnt() != COUNT_UNKNOWN && call->cnt() <= PROB_UNLIKELY_MAG(4)) { -+ // This is true for slow-path stubs like new_{instance,array}, -+ // slow_arraycopy, complete_monitor_locking, uncommon_trap. -+ // The magic number corresponds to the probability of an uncommon_trap, -+ // even though it is a count not a probability. -+ return true; -+ } -+ } -+ -+ int op = en->is_Mach() ? en->as_Mach()->ideal_Opcode() : en->Opcode(); -+ return op == Op_Halt; -+} -+ - //------------------------------is_uncommon------------------------------------ - // True if block is low enough frequency or guarded by a test which - // mostly does not go here. - bool Block::is_uncommon( Block_Array &bbs ) const { - // Initial blocks must never be moved, so are never uncommon. -- if (_nodes[0]->is_Root() || _nodes[0]->is_Start()) return false; -+ if (head()->is_Root() || head()->is_Start()) return false; - - // Check for way-low freq - if( _freq < BLOCK_FREQUENCY(0.00001f) ) return true; - -+ // Look for code shape indicating uncommon_trap or slow path -+ if (has_uncommon_code()) return true; -+ - const float epsilon = 0.05f; - const float guard_factor = PROB_UNLIKELY_MAG(4) / (1.f - epsilon); - uint uncommon_preds = 0; -@@ -280,11 +306,10 @@ - } - tty->print("\tLoop: B%d-B%d ", bhead->_pre_order, bx->_pre_order); - // Dump any loop-specific bits, especially for CountedLoops. -- loop->dump_spec(); -+ loop->dump_spec(tty); - } - tty->print(" Freq: %g",_freq); - if( Verbose || WizardMode ) { -- tty->print(" Count: %g",_cnt); - tty->print(" IDom: %d/#%d", _idom ? _idom->_pre_order : 0, _dom_depth); - tty->print(" RegPressure: %d",_reg_pressure); - tty->print(" IHRP Index: %d",_ihrp_index); -@@ -521,7 +546,7 @@ - break; - // Scan through block, yanking dead path from - // all regions and phis. -- dead->_nodes[0]->del_req(j); -+ dead->head()->del_req(j); - for( int k = 1; dead->_nodes[k]->is_Phi(); k++ ) - dead->_nodes[k]->del_req(j); - } -@@ -560,7 +585,7 @@ - return true; - } - --//------------------------------MoveEmptyToEnd--------------------------------- -+//------------------------------MoveToEnd-------------------------------------- - // Move empty and uncommon blocks to the end. - void PhaseCFG::MoveToEnd(Block *b, uint i) { - int e = b->is_Empty(); -@@ -689,8 +714,8 @@ - ProjNode *proj1 = b->_nodes[b->_nodes.size()-1]->as_Proj(); - - // Assert that proj0 and succs[0] match up. Similarly for proj1 and succs[1]. -- assert(proj0->raw_out(0) == b->_succs[0]->_nodes[0], "Mismatch successor 0"); -- assert(proj1->raw_out(0) == b->_succs[1]->_nodes[0], "Mismatch successor 1"); -+ assert(proj0->raw_out(0) == b->_succs[0]->head(), "Mismatch successor 0"); -+ assert(proj1->raw_out(0) == b->_succs[1]->head(), "Mismatch successor 1"); - - Block *bs1 = b->non_connector_successor(1); - -diff -ruNb openjdk6/hotspot/src/share/vm/opto/block.hpp openjdk/hotspot/src/share/vm/opto/block.hpp ---- openjdk6/hotspot/src/share/vm/opto/block.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/block.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)block.hpp 1.98 07/05/17 15:57:17 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -28,6 +25,7 @@ - // Optimization - Graph Style - - class Block; -+class CFGLoop; - class MachCallNode; - class Matcher; - class RootNode; -@@ -80,11 +78,22 @@ - }; - - -+class CFGElement : public ResourceObj { -+ public: -+ float _freq; // Execution frequency (estimate) -+ -+ CFGElement() : _freq(0.0f) {} -+ virtual bool is_block() { return false; } -+ virtual bool is_loop() { return false; } -+ Block* as_Block() { assert(is_block(), "must be block"); return (Block*)this; } -+ CFGLoop* as_CFGLoop() { assert(is_loop(), "must be loop"); return (CFGLoop*)this; } -+}; -+ - //------------------------------Block------------------------------------------ - // This class defines a Basic Block. - // Basic blocks are used during the output routines, and are not used during - // any optimization pass. They are created late in the game. --class Block : public ResourceObj { -+class Block : public CFGElement { - public: - // Nodes in this block, in order - Node_List _nodes; -@@ -116,6 +125,12 @@ - uint _dom_depth; // Depth in dominator tree for fast LCA - Block* _idom; // Immediate dominator block - -+ CFGLoop *_loop; // Loop to which this block belongs -+ uint _rpo; // Number in reverse post order walk -+ -+ virtual bool is_block() { return true; } -+ float succ_prob(uint i); // return probability of i'th successor -+ - Block* dom_lca(Block* that); // Compute LCA in dominator tree. - #ifdef ASSERT - bool dominates(Block* that) { -@@ -135,19 +150,6 @@ - // FreqCountInvocations relative to the old value of 1500. - #define BLOCK_FREQUENCY(f) ((f * (float) 1500) / FreqCountInvocations) - -- // Execution frequency (estimate) -- float _freq; -- float _cnt; -- --#ifdef ASSERT -- // Validate _cnt and _freq -- bool has_valid_counts() const { -- if (_freq <= 0.0f) return false; -- if ((_cnt <= 0.0f) && (_cnt != COUNT_UNKNOWN)) return false; -- return true; -- } --#endif -- - // Register Pressure (estimate) for Splitting heuristic - uint _reg_pressure; - uint _ihrp_index; -@@ -203,13 +205,13 @@ - // Create a new Block with given head Node. - // Creates the (empty) predecessor arrays. - Block( Arena *a, Node *headnode ) -- : _nodes(a), -+ : CFGElement(), -+ _nodes(a), - _succs(a), - _num_succs(0), - _pre_order(0), - _idom(0), -- _freq(0.0f), -- _cnt(COUNT_UNKNOWN), -+ _loop(NULL), - _reg_pressure(0), - _ihrp_index(1), - _freg_pressure(0), -@@ -278,7 +280,11 @@ - return _succs[i]->non_connector(); - } - -- // True if block is way uncommon -+ // Examine block's code shape to predict if it is not commonly executed. -+ bool has_uncommon_code() const; -+ -+ // Use frequency calculations and code shape to predict if the block -+ // is uncommon. - bool is_uncommon( Block_Array &bbs ) const; - - #ifndef PRODUCT -@@ -330,6 +336,7 @@ - Block_Array _bbs; // Map Nodes to owning Basic Block - Block *_broot; // Basic block of root - uint _rpo_ctr; -+ CFGLoop* _root_loop; - - // Per node latency estimation, valid only during GCM - GrowableArray _node_latency; -@@ -384,6 +391,8 @@ - // into Goto's so that when you enter the infinite loop you indeed hang. - void convert_NeverBranch_to_Goto(Block *b); - -+ CFGLoop* create_loop_tree(); -+ - // Insert a node into a block, and update the _bbs - void insert( Block *b, uint idx, Node *n ) { - b->_nodes.insert( idx, n ); -@@ -439,3 +448,63 @@ - - }; - -+//----------------------------BlockProbPair--------------------------- -+// Ordered pair of Node*. -+class BlockProbPair VALUE_OBJ_CLASS_SPEC { -+protected: -+ Block* _target; // block target -+ float _prob; // probability of edge to block -+public: -+ BlockProbPair() : _target(NULL), _prob(0.0) {} -+ BlockProbPair(Block* b, float p) : _target(b), _prob(p) {} -+ -+ Block* get_target() const { return _target; } -+ float get_prob() const { return _prob; } -+}; -+ -+//------------------------------CFGLoop------------------------------------------- -+class CFGLoop : public CFGElement { -+ int _id; -+ int _depth; -+ CFGLoop *_parent; // root of loop tree is the method level "pseudo" loop, it's parent is null -+ CFGLoop *_sibling; // null terminated list -+ CFGLoop *_child; // first child, use child's sibling to visit all immediately nested loops -+ GrowableArray _members; // list of members of loop -+ GrowableArray _exits; // list of successor blocks and their probabilities -+ float _exit_prob; // probability any loop exit is taken on a single loop iteration -+ void update_succ_freq(Block* b, float freq); -+ -+ public: -+ CFGLoop(int id) : -+ CFGElement(), -+ _id(id), -+ _depth(0), -+ _parent(NULL), -+ _sibling(NULL), -+ _child(NULL), -+ _exit_prob(1.0f) {} -+ CFGLoop* parent() { return _parent; } -+ void push_pred(Block* blk, int i, Block_List& worklist, Block_Array& node_to_blk); -+ void add_member(CFGElement *s) { _members.push(s); } -+ void add_nested_loop(CFGLoop* cl); -+ Block* head() { -+ assert(_members.at(0)->is_block(), "head must be a block"); -+ Block* hd = _members.at(0)->as_Block(); -+ assert(hd->_loop == this, "just checking"); -+ assert(hd->head()->is_Loop(), "must begin with loop head node"); -+ return hd; -+ } -+ Block* backedge_block(); // Return the block on the backedge of the loop (else NULL) -+ void compute_loop_depth(int depth); -+ void compute_freq(); // compute frequency with loop assuming head freq 1.0f -+ void scale_freq(); // scale frequency by loop trip count (including outer loops) -+ bool in_loop_nest(Block* b); -+ float trip_count() const { return 1.0f / _exit_prob; } -+ virtual bool is_loop() { return true; } -+ int id() { return _id; } -+ -+#ifndef PRODUCT -+ void dump( ) const; -+ void dump_tree() const; -+#endif -+}; -diff -ruNb openjdk6/hotspot/src/share/vm/opto/buildOopMap.cpp openjdk/hotspot/src/share/vm/opto/buildOopMap.cpp ---- openjdk6/hotspot/src/share/vm/opto/buildOopMap.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/buildOopMap.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)buildOopMap.cpp 1.37 07/05/05 17:06:11 JVM" --#endif - /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/opto/bytecodeInfo.cpp openjdk/hotspot/src/share/vm/opto/bytecodeInfo.cpp ---- openjdk6/hotspot/src/share/vm/opto/bytecodeInfo.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/bytecodeInfo.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)bytecodeInfo.cpp 1.122 07/05/05 17:06:12 JVM" --#endif - /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/opto/c2_globals.cpp openjdk/hotspot/src/share/vm/opto/c2_globals.cpp ---- openjdk6/hotspot/src/share/vm/opto/c2_globals.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/c2_globals.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)c2_globals.cpp 1.14 07/05/17 15:57:19 JVM" --#endif - /* - * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/opto/c2_globals.hpp openjdk/hotspot/src/share/vm/opto/c2_globals.hpp ---- openjdk6/hotspot/src/share/vm/opto/c2_globals.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/c2_globals.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)c2_globals.hpp 1.90 07/09/25 22:01:58 JVM" --#endif - /* - * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -131,6 +128,9 @@ - notproduct(bool, PrintOptoPeephole, false, \ - "Print New compiler peephole replacements") \ - \ -+ develop(bool, PrintCFGBlockFreq, false, \ -+ "Print CFG block freqencies") \ -+ \ - develop(bool, TraceOptoParse, false, \ - "Trace bytecode parse and control-flow merge") \ - \ -@@ -147,6 +147,10 @@ - "UnrollLimitForProfileCheck. A higher value allows more " \ - "unrolling. Zero acts as a very large value." ) \ - \ -+ product(intx, MultiArrayExpandLimit, 6, \ -+ "Maximum number of individual allocations in an inline-expanded " \ -+ "multianewarray instruction") \ -+ \ - notproduct(bool, TraceProfileTripCount, false, \ - "Trace profile loop trip count information") \ - \ -@@ -159,6 +163,18 @@ - develop(bool, UseExactTypes, true, \ - "Use exact types to eliminate array store checks and v-calls") \ - \ -+ product(intx, TrackedInitializationLimit, 50, \ -+ "When initializing fields, track up to this many words") \ -+ \ -+ product(bool, ReduceFieldZeroing, true, \ -+ "When initializing fields, try to avoid needless zeroing") \ -+ \ -+ product(bool, ReduceInitialCardMarks, true, \ -+ "When initializing fields, try to avoid needless card marks") \ -+ \ -+ product(bool, ReduceBulkZeroing, true, \ -+ "When bulk-initializing, try to avoid needless zeroing") \ -+ \ - develop_pd(intx, RegisterCostAreaRatio, \ - "Spill selection in reg allocator: scale area by (X/64K) before " \ - "adding cost") \ -@@ -169,7 +185,7 @@ - notproduct(bool, VerifyGraphEdges , false, \ - "Verify Bi-directional Edges") \ - \ -- notproduct(bool, VerifyDUIterators, false, \ -+ notproduct(bool, VerifyDUIterators, true, \ - "Verify the safety of all iterations of Bi-directional Edges") \ - \ - notproduct(bool, VerifyHashTableKeys, true, \ -@@ -211,7 +227,7 @@ - notproduct(bool, TraceLoopUnswitching, false, \ - "Trace loop unswitching") \ - \ -- product(bool, UseSuperWord, false, \ -+ product(bool, UseSuperWord, true, \ - "Transform scalar operations into superword operations") \ - \ - develop(bool, SuperWordRTDepCheck, false, \ -@@ -233,6 +249,20 @@ - develop(bool, SparcV9RegsHiBitsZero, true, \ - "Assume Sparc V9 I&L registers on V8+ systems are zero-extended") \ - \ -+ develop(intx, PrintIdealGraphLevel, 0, \ -+ "Print ideal graph to XML file / network interface. " \ -+ "By default attempts to connect to the visualizer on a socket.") \ -+ \ -+ develop(intx, PrintIdealGraphPort, 4444, \ -+ "Ideal graph printer to network port") \ -+ \ -+ develop(ccstr, PrintIdealGraphAddress, "127.0.0.1", \ -+ "IP address to connect to visualizer") \ -+ \ -+ develop(ccstr, PrintIdealGraphFile, NULL, \ -+ "File to dump ideal graph to. If set overrides the " \ -+ "use of the network") \ -+ \ - product(bool, UseOldInlining, true, \ - "Enable the 1.3 inlining strategy") \ - \ -@@ -343,8 +373,10 @@ - notproduct(bool, PrintEscapeAnalysis, false, \ - "Print the results of escape analysis") \ - \ -+ product(bool, EliminateAllocations, true, \ -+ "Use escape analysis to eliminate allocations") \ -+ \ - product(intx, MaxLabelRootDepth, 1100, \ - "Maximum times call Label_Root to prevent stack overflow") \ - - C2_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_NOTPRODUCT_FLAG) -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/c2compiler.cpp openjdk/hotspot/src/share/vm/opto/c2compiler.cpp ---- openjdk6/hotspot/src/share/vm/opto/c2compiler.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/c2compiler.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)c2compiler.cpp 1.29 07/05/05 17:06:11 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/opto/c2compiler.hpp openjdk/hotspot/src/share/vm/opto/c2compiler.hpp ---- openjdk6/hotspot/src/share/vm/opto/c2compiler.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/c2compiler.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)c2compiler.hpp 1.28 07/05/05 17:06:11 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -57,10 +54,3 @@ - // Print compilation timers and statistics - void print_timers(); - }; -- -- -- -- -- -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/callGenerator.cpp openjdk/hotspot/src/share/vm/opto/callGenerator.cpp ---- openjdk6/hotspot/src/share/vm/opto/callGenerator.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/callGenerator.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)callGenerator.cpp 1.47 07/05/05 17:06:12 JVM" --#endif - /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -403,6 +400,11 @@ - CallGenerator* if_hit, float hit_prob) - : CallGenerator(if_missed->method()) - { -+ // The call profile data may predict the hit_prob as extreme as 0 or 1. -+ // Remove the extremes values from the range. -+ if (hit_prob > PROB_MAX) hit_prob = PROB_MAX; -+ if (hit_prob < PROB_MIN) hit_prob = PROB_MIN; -+ - _predicted_receiver = predicted_receiver; - _if_missed = if_missed; - _if_hit = if_hit; -@@ -556,7 +558,17 @@ - int nargs = method()->arg_size(); - kit.inc_sp(nargs); - assert(nargs <= kit.sp() && kit.sp() <= jvms->stk_size(), "sane sp w/ args pushed"); -+ if (_reason == Deoptimization::Reason_class_check && -+ _action == Deoptimization::Action_maybe_recompile) { -+ // Temp fix for 6529811 -+ // Don't allow uncommon_trap to override our decision to recompile in the event -+ // of a class cast failure for a monomorphic call as it will never let us convert -+ // the call to either bi-morphic or megamorphic and can lead to unc-trap loops -+ bool keep_exact_action = true; -+ kit.uncommon_trap(_reason, _action, NULL, "monomorphic vcall checkcast", false, keep_exact_action); -+ } else { - kit.uncommon_trap(_reason, _action); -+ } - return kit.transfer_exceptions_into_jvms(); - } - -diff -ruNb openjdk6/hotspot/src/share/vm/opto/callGenerator.hpp openjdk/hotspot/src/share/vm/opto/callGenerator.hpp ---- openjdk6/hotspot/src/share/vm/opto/callGenerator.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/callGenerator.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)callGenerator.hpp 1.19 07/05/05 17:06:12 JVM" --#endif - /* - * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/opto/callnode.cpp openjdk/hotspot/src/share/vm/opto/callnode.cpp ---- openjdk6/hotspot/src/share/vm/opto/callnode.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/callnode.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)callnode.cpp 1.235 07/05/05 17:06:13 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -39,7 +36,7 @@ - const Type *StartNode::bottom_type() const { return _domain; } - const Type *StartNode::Value(PhaseTransform *phase) const { return _domain; } - #ifndef PRODUCT --void StartNode::dump_spec() const { tty->print(" #"); _domain->dump();} -+void StartNode::dump_spec(outputStream *st) const { st->print(" #"); _domain->dump_on(st);} - #endif - - //------------------------------Ideal------------------------------------------ -@@ -100,13 +97,13 @@ - }; - - #ifndef PRODUCT --void ParmNode::dump_spec() const { -+void ParmNode::dump_spec(outputStream *st) const { - if( _con < TypeFunc::Parms ) { -- tty->print(names[_con]); -+ st->print(names[_con]); - } else { -- tty->print("Parm%d: ",_con-TypeFunc::Parms); -+ st->print("Parm%d: ",_con-TypeFunc::Parms); - // Verbose and WizardMode dump bottom_type for all nodes -- if( !Verbose && !WizardMode ) bottom_type()->dump(); -+ if( !Verbose && !WizardMode ) bottom_type()->dump_on(st); - } - } - #endif -@@ -304,42 +301,42 @@ - // Given an allocation (a Chaitin object) and a Node decide if the Node carries - // any defined value or not. If it does, print out the register or constant. - #ifndef PRODUCT --static void format_helper( PhaseRegAlloc *regalloc, Node *n, const char *msg, uint i ) { -- if (n == NULL) { tty->print(" NULL"); return; } -+static void format_helper( PhaseRegAlloc *regalloc, outputStream* st, Node *n, const char *msg, uint i ) { -+ if (n == NULL) { st->print(" NULL"); return; } - if( OptoReg::is_valid(regalloc->get_reg_first(n))) { // Check for undefined - char buf[50]; - regalloc->dump_register(n,buf); -- tty->print(" %s%d]=%s",msg,i,buf); -+ st->print(" %s%d]=%s",msg,i,buf); - } else { // No register, but might be constant - const Type *t = n->bottom_type(); - switch (t->base()) { - case Type::Int: -- tty->print(" %s%d]=#"INT32_FORMAT,msg,i,t->is_int()->get_con()); -+ st->print(" %s%d]=#"INT32_FORMAT,msg,i,t->is_int()->get_con()); - break; - case Type::AnyPtr: - assert( t == TypePtr::NULL_PTR, "" ); -- tty->print(" %s%d]=#NULL",msg,i); -+ st->print(" %s%d]=#NULL",msg,i); - break; - case Type::AryPtr: - case Type::KlassPtr: - case Type::InstPtr: -- tty->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,t->isa_oopptr()->const_oop()); -+ st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,t->isa_oopptr()->const_oop()); - break; - case Type::RawPtr: -- tty->print(" %s%d]=#Raw" INTPTR_FORMAT,msg,i,t->is_rawptr()); -+ st->print(" %s%d]=#Raw" INTPTR_FORMAT,msg,i,t->is_rawptr()); - break; - case Type::DoubleCon: -- tty->print(" %s%d]=#%fD",msg,i,t->is_double_constant()->_d); -+ st->print(" %s%d]=#%fD",msg,i,t->is_double_constant()->_d); - break; - case Type::FloatCon: -- tty->print(" %s%d]=#%fF",msg,i,t->is_float_constant()->_f); -+ st->print(" %s%d]=#%fF",msg,i,t->is_float_constant()->_f); - break; - case Type::Long: -- tty->print(" %s%d]=#"INT64_FORMAT,msg,i,t->is_long()->get_con()); -+ st->print(" %s%d]=#"INT64_FORMAT,msg,i,t->is_long()->get_con()); - break; - case Type::Half: - case Type::Top: -- tty->print(" %s%d]=_",msg,i); -+ st->print(" %s%d]=_",msg,i); - break; - default: ShouldNotReachHere(); - } -@@ -349,13 +346,13 @@ - - //------------------------------format----------------------------------------- - #ifndef PRODUCT --void JVMState::format(PhaseRegAlloc *regalloc, const Node *n) const { -- tty->print(" #"); -+void JVMState::format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st) const { -+ st->print(" #"); - if( _method ) { -- _method->print_short_name(); -- tty->print(" @ bci:%d ",_bci); -+ _method->print_short_name(st); -+ st->print(" @ bci:%d ",_bci); - } else { -- tty->print_cr(" runtime stub "); -+ st->print_cr(" runtime stub "); - return; - } - if (n->is_MachSafePoint()) { -@@ -363,37 +360,37 @@ - uint i; - // Print locals - for( i = 0; i < (uint)loc_size(); i++ ) -- format_helper( regalloc, mcall->local(this, i), "L[", i ); -+ format_helper( regalloc, st, mcall->local(this, i), "L[", i ); - // Print stack - for (i = 0; i < (uint)stk_size(); i++) { - if ((uint)(_stkoff + i) >= mcall->len()) -- tty->print(" oob "); -+ st->print(" oob "); - else -- format_helper( regalloc, mcall->stack(this, i), "STK[", i ); -+ format_helper( regalloc, st, mcall->stack(this, i), "STK[", i ); - } - for (i = 0; (int)i < nof_monitors(); i++) { - Node *box = mcall->monitor_box(this, i); - Node *obj = mcall->monitor_obj(this, i); - if ( OptoReg::is_valid(regalloc->get_reg_first(box)) ) { - while( !box->is_BoxLock() ) box = box->in(1); -- format_helper( regalloc, box, "MON-BOX[", i ); -+ format_helper( regalloc, st, box, "MON-BOX[", i ); - } else { - OptoReg::Name box_reg = BoxLockNode::stack_slot(box); -- tty->print(" MON-BOX%d=%s+%d", -+ st->print(" MON-BOX%d=%s+%d", - i, - OptoReg::regname(OptoReg::c_frame_pointer), - regalloc->reg2offset(box_reg)); - } -- format_helper( regalloc, obj, "MON-OBJ[", i ); -+ format_helper( regalloc, st, obj, "MON-OBJ[", i ); - } - } -- tty->print_cr(""); -- if (caller() != NULL) caller()->format(regalloc, n); -+ st->print_cr(""); -+ if (caller() != NULL) caller()->format(regalloc, n, st); - } - #endif - - #ifndef PRODUCT --void JVMState::dump_spec() const { -+void JVMState::dump_spec(outputStream *st) const { - if (_method != NULL) { - bool printed = false; - if (!Verbose) { -@@ -410,22 +407,22 @@ - if (endcn == NULL) endcn = name + strlen(name); - while (endcn > name && endcn[-1] != '.' && endcn[-1] != '/') - --endcn; -- tty->print(" %s", endcn); -+ st->print(" %s", endcn); - printed = true; - } - } - if (!printed) -- _method->print_short_name(tty); -- tty->print(" @ bci:%d",_bci); -+ _method->print_short_name(st); -+ st->print(" @ bci:%d",_bci); - } else { -- tty->print(" runtime stub"); -+ st->print(" runtime stub"); - } -- if (caller() != NULL) caller()->dump_spec(); -+ if (caller() != NULL) caller()->dump_spec(st); - } - #endif - - #ifndef PRODUCT --void JVMState::dump() const { -+void JVMState::dump_on(outputStream* st) const { - if (_map && !((uintptr_t)_map & 1)) { - if (_map->len() > _map->req()) { // _map->has_exceptions() - Node* ex = _map->in(_map->req()); // _map->next_exception() -@@ -437,20 +434,20 @@ - } - _map->dump(2); - } -- tty->print("JVMS depth=%d loc=%d stk=%d mon=%d end=%d mondepth=%d sp=%d bci=%d method=", -+ st->print("JVMS depth=%d loc=%d stk=%d mon=%d end=%d mondepth=%d sp=%d bci=%d method=", - depth(), locoff(), stkoff(), monoff(), endoff(), monitor_depth(), sp(), bci()); - if (_method == NULL) { -- tty->print_cr("(none)"); -+ st->print_cr("(none)"); - } else { -- _method->print_name(); -- tty->cr(); -+ _method->print_name(st); -+ st->cr(); - if (bci() >= 0 && bci() < _method->code_size()) { -- tty->print(" bc: "); -- _method->print_codes(bci(), bci()+1); -+ st->print(" bc: "); -+ _method->print_codes_on(bci(), bci()+1, st); - } - } - if (caller() != NULL) { -- caller()->dump(); -+ caller()->dump_on(st); - } - } - -@@ -500,11 +497,11 @@ - tty->print(")"); - } - --void CallNode::dump_spec() const { -- tty->print(" "); -- tf()->dump(); -- if (_cnt != COUNT_UNKNOWN) tty->print(" C=%f",_cnt); -- if (jvms() != NULL) jvms()->dump_spec(); -+void CallNode::dump_spec(outputStream *st) const { -+ st->print(" "); -+ tf()->dump_on(st); -+ if (_cnt != COUNT_UNKNOWN) st->print(" C=%f",_cnt); -+ if (jvms() != NULL) jvms()->dump_spec(st); - } - #endif - -@@ -567,9 +564,9 @@ - return CallNode::cmp(call) && _method == call._method; - } - #ifndef PRODUCT --void CallJavaNode::dump_spec() const { -- if( _method ) _method->print_short_name(); -- CallNode::dump_spec(); -+void CallJavaNode::dump_spec(outputStream *st) const { -+ if( _method ) _method->print_short_name(st); -+ CallNode::dump_spec(st); - } - #endif - -@@ -602,20 +599,20 @@ - } - - #ifndef PRODUCT --void CallStaticJavaNode::dump_spec() const { -- tty->print("# Static "); -+void CallStaticJavaNode::dump_spec(outputStream *st) const { -+ st->print("# Static "); - if (_name != NULL) { -- tty->print("%s", _name); -+ st->print("%s", _name); - int trap_req = uncommon_trap_request(); - if (trap_req != 0) { - char buf[100]; -- tty->print("(%s)", -+ st->print("(%s)", - Deoptimization::format_trap_request(buf, sizeof(buf), - trap_req)); - } -- tty->print(" "); -+ st->print(" "); - } -- CallJavaNode::dump_spec(); -+ CallJavaNode::dump_spec(st); - } - #endif - -@@ -626,9 +623,9 @@ - return CallJavaNode::cmp(call); - } - #ifndef PRODUCT --void CallDynamicJavaNode::dump_spec() const { -- tty->print("# Dynamic "); -- CallJavaNode::dump_spec(); -+void CallDynamicJavaNode::dump_spec(outputStream *st) const { -+ st->print("# Dynamic "); -+ CallJavaNode::dump_spec(st); - } - #endif - -@@ -639,10 +636,10 @@ - return CallNode::cmp(call) && !strcmp(_name,call._name); - } - #ifndef PRODUCT --void CallRuntimeNode::dump_spec() const { -- tty->print("# "); -- tty->print(_name); -- CallNode::dump_spec(); -+void CallRuntimeNode::dump_spec(outputStream *st) const { -+ st->print("# "); -+ st->print(_name); -+ CallNode::dump_spec(st); - } - #endif - -@@ -657,10 +654,10 @@ - - //============================================================================= - #ifndef PRODUCT --void CallLeafNode::dump_spec() const { -- tty->print("# "); -- tty->print(_name); -- CallNode::dump_spec(); -+void CallLeafNode::dump_spec(outputStream *st) const { -+ st->print("# "); -+ st->print(_name); -+ CallNode::dump_spec(st); - } - #endif - -@@ -750,8 +747,8 @@ - } - - #ifndef PRODUCT --void SafePointNode::dump_spec() const { -- tty->print(" SafePoint "); -+void SafePointNode::dump_spec(outputStream *st) const { -+ st->print(" SafePoint "); - } - #endif - -@@ -830,8 +827,7 @@ - - AllocateNode::AllocateNode(Compile* C, const TypeFunc *atype, - Node *ctrl, Node *mem, Node *abio, -- Node *size, Node *klass_node, Node *initial_test, -- Node *eden_top, Node *eden_end) -+ Node *size, Node *klass_node, Node *initial_test) - : CallNode(atype, NULL, TypeRawPtr::BOTTOM) - { - init_class_id(Class_Allocate); -@@ -846,8 +842,6 @@ - init_req( AllocSize , size); - init_req( KlassNode , klass_node); - init_req( InitialTest , initial_test); -- init_req( EdenTop , eden_top); -- init_req( EdenEnd , eden_end); - init_req( ALength , topnode); - C->add_macro_node(this); - } -diff -ruNb openjdk6/hotspot/src/share/vm/opto/callnode.hpp openjdk/hotspot/src/share/vm/opto/callnode.hpp ---- openjdk6/hotspot/src/share/vm/opto/callnode.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/callnode.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)callnode.hpp 1.192 07/05/17 15:57:24 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -75,7 +72,7 @@ - virtual Node *match( const ProjNode *proj, const Matcher *m ); - virtual uint ideal_reg() const { return 0; } - #ifndef PRODUCT -- virtual void dump_spec() const; -+ virtual void dump_spec(outputStream *st) const; - #endif - }; - -@@ -99,7 +96,7 @@ - virtual bool is_CFG() const { return (_con == TypeFunc::Control); } - virtual uint ideal_reg() const; - #ifndef PRODUCT -- virtual void dump_spec() const; -+ virtual void dump_spec(outputStream *st) const; - #endif - }; - -@@ -266,9 +263,12 @@ - JVMState* clone_shallow(Compile* C) const; // retains uncloned caller - - #ifndef PRODUCT -- void format(PhaseRegAlloc *regalloc, const Node *n) const; -- void dump_spec() const; -- void dump() const; -+ void format(PhaseRegAlloc *regalloc, const Node *n, outputStream* st) const; -+ void dump_spec(outputStream *st) const; -+ void dump_on(outputStream* st) const; -+ void dump() const { -+ dump_on(tty); -+ } - #endif - }; - -@@ -393,7 +393,7 @@ - static bool needs_polling_address_input(); - - #ifndef PRODUCT -- virtual void dump_spec() const; -+ virtual void dump_spec(outputStream *st) const; - #endif - }; - -@@ -445,7 +445,7 @@ - - #ifndef PRODUCT - virtual void dump_req() const; -- virtual void dump_spec() const; -+ virtual void dump_spec(outputStream *st) const; - #endif - }; - -@@ -476,7 +476,7 @@ - bool is_optimized_virtual() const { return _optimized_virtual; } - - #ifndef PRODUCT -- virtual void dump_spec() const; -+ virtual void dump_spec(outputStream *st) const; - #endif - }; - -@@ -507,7 +507,7 @@ - - virtual int Opcode() const; - #ifndef PRODUCT -- virtual void dump_spec() const; -+ virtual void dump_spec(outputStream *st) const; - #endif - }; - -@@ -524,7 +524,7 @@ - int _vtable_index; - virtual int Opcode() const; - #ifndef PRODUCT -- virtual void dump_spec() const; -+ virtual void dump_spec(outputStream *st) const; - #endif - }; - -@@ -547,7 +547,7 @@ - virtual void calling_convention( BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt ) const; - - #ifndef PRODUCT -- virtual void dump_spec() const; -+ virtual void dump_spec(outputStream *st) const; - #endif - }; - -@@ -565,7 +565,7 @@ - virtual int Opcode() const; - virtual bool guaranteed_safepoint() { return false; } - #ifndef PRODUCT -- virtual void dump_spec() const; -+ virtual void dump_spec(outputStream *st) const; - #endif - }; - -@@ -602,8 +602,6 @@ - AllocSize = TypeFunc::Parms, // size (in bytes) of the new object - KlassNode, // type (maybe dynamic) of the obj. - InitialTest, // slow-path test (may be constant) -- EdenTop, // eden pointers -- EdenEnd, - ALength, // array length (or TOP if none) - ParmLimit - }; -@@ -613,9 +611,7 @@ - fields[AllocSize] = TypeInt::POS; - fields[KlassNode] = TypeInstPtr::NOTNULL; - fields[InitialTest] = TypeInt::BOOL; -- fields[EdenTop] = TypeRawPtr::NOTNULL; -- fields[EdenEnd] = TypeRawPtr::NOTNULL; -- fields[ALength] = TypeInt::INT; // length >= 0 -+ fields[ALength] = TypeInt::INT; // length (can be a bad length) - - const TypeTuple *domain = TypeTuple::make(ParmLimit, fields); - -@@ -630,8 +626,7 @@ - - virtual uint size_of() const; // Size is bigger - AllocateNode(Compile* C, const TypeFunc *atype, Node *ctrl, Node *mem, Node *abio, -- Node *size, Node *klass_node, Node *initial_test, -- Node *eden_top, Node *eden_end); -+ Node *size, Node *klass_node, Node *initial_test); - // Expansion modifies the JVMState, so we need to clone it - virtual void clone_jvms() { - set_jvms(jvms()->clone_deep(Compile::current())); -@@ -651,6 +646,7 @@ - - // Fancy version which uses AddPNode::Ideal_base_and_offset to strip - // an offset, which is reported back to the caller. -+ // (Note: AllocateNode::Ideal_allocation is defined in graphKit.cpp.) - static AllocateNode* Ideal_allocation(Node* ptr, PhaseTransform* phase, - intptr_t& offset); - -@@ -664,6 +660,15 @@ - int minimum_header_size() { - return is_AllocateArray() ? sizeof(arrayOopDesc) : sizeof(oopDesc); - } -+ -+ // Return the corresponding initialization barrier (or null if none). -+ // Walks out edges to find it... -+ // (Note: Both InitializeNode::allocation and AllocateNode::initialization -+ // are defined in graphKit.cpp, which sets up the bidirectional relation.) -+ InitializeNode* initialization(); -+ -+ // Convenience for initialization->maybe_set_complete(phase) -+ bool maybe_set_complete(PhaseGVN* phase); - }; - - //------------------------------AllocateArray--------------------------------- -@@ -674,10 +679,10 @@ - public: - AllocateArrayNode(Compile* C, const TypeFunc *atype, Node *ctrl, Node *mem, Node *abio, - Node* size, Node* klass_node, Node* initial_test, -- Node* eden_top, Node* eden_end, Node* count_val -+ Node* count_val - ) - : AllocateNode(C, atype, ctrl, mem, abio, size, klass_node, -- initial_test, eden_top, eden_end) -+ initial_test) - { - init_class_id(Class_AllocateArray); - set_req(AllocateNode::ALength, count_val); -diff -ruNb openjdk6/hotspot/src/share/vm/opto/cfgnode.cpp openjdk/hotspot/src/share/vm/opto/cfgnode.cpp ---- openjdk6/hotspot/src/share/vm/opto/cfgnode.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/cfgnode.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)cfgnode.cpp 1.261 08/06/22 00:57:20 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -536,9 +533,16 @@ - } - else if( n->is_Region() ) { // Update all incoming edges - assert( !igvn->eqv(n, this), "Must be removed from DefUse edges"); -- for( uint k=1; k < n->req(); k++ ) -- if( n->in(k) == this ) -+ uint uses_found = 0; -+ for( uint k=1; k < n->req(); k++ ) { -+ if( n->in(k) == this ) { - n->set_req(k, parent_ctrl); -+ uses_found++; -+ } -+ } -+ if( uses_found > 1 ) { // (--i) done at the end of the loop. -+ i -= (uses_found - 1); -+ } - } - else { - assert( igvn->eqv(n->in(0), this), "Expect RegionNode to be control parent"); -@@ -1551,6 +1555,64 @@ - if (opt != NULL) return opt; - } - -+ if (in(1) != NULL && in(1)->Opcode() == Op_AddP && can_reshape) { -+ // Try to undo Phi of AddP: -+ // (Phi (AddP base base y) (AddP base2 base2 y)) -+ // becomes: -+ // newbase := (Phi base base2) -+ // (AddP newbase newbase y) -+ // -+ // This occurs as a result of unsuccessful split_thru_phi and -+ // interferes with taking advantage of addressing modes. See the -+ // clone_shift_expressions code in matcher.cpp -+ Node* addp = in(1); -+ const Type* type = addp->in(AddPNode::Base)->bottom_type(); -+ Node* y = addp->in(AddPNode::Offset); -+ if (y != NULL && addp->in(AddPNode::Base) == addp->in(AddPNode::Address)) { -+ // make sure that all the inputs are similar to the first one, -+ // i.e. AddP with base == address and same offset as first AddP -+ bool doit = true; -+ for (uint i = 2; i < req(); i++) { -+ if (in(i) == NULL || -+ in(i)->Opcode() != Op_AddP || -+ in(i)->in(AddPNode::Base) != in(i)->in(AddPNode::Address) || -+ in(i)->in(AddPNode::Offset) != y) { -+ doit = false; -+ break; -+ } -+ // Accumulate type for resulting Phi -+ type = type->meet(in(i)->in(AddPNode::Base)->bottom_type()); -+ } -+ Node* base = NULL; -+ if (doit) { -+ // Check for neighboring AddP nodes in a tree. -+ // If they have a base, use that it. -+ for (DUIterator_Fast kmax, k = this->fast_outs(kmax); k < kmax; k++) { -+ Node* u = this->fast_out(k); -+ if (u->is_AddP()) { -+ Node* base2 = u->in(AddPNode::Base); -+ if (base2 != NULL && !base2->is_top()) { -+ if (base == NULL) -+ base = base2; -+ else if (base != base2) -+ { doit = false; break; } -+ } -+ } -+ } -+ } -+ if (doit) { -+ if (base == NULL) { -+ base = new (phase->C, in(0)->req()) PhiNode(in(0), type, NULL); -+ for (uint i = 1; i < req(); i++) { -+ base->init_req(i, in(i)->in(AddPNode::Base)); -+ } -+ phase->is_IterGVN()->register_new_node_with_optimizer(base); -+ } -+ return new (phase->C, 4) AddPNode(base, base, y); -+ } -+ } -+ } -+ - // Split phis through memory merges, so that the memory merges will go away. - // Piggy-back this transformation on the search for a unique input.... - // It will be as if the merged memory is the unique value of the phi. -@@ -1692,12 +1754,12 @@ - } - - #ifndef PRODUCT --void PhiNode::dump_spec() const { -- TypeNode::dump_spec(); -+void PhiNode::dump_spec(outputStream *st) const { -+ TypeNode::dump_spec(st); - if (in(0) != NULL && - in(0)->is_CountedLoop() && - in(0)->as_CountedLoop()->phi() == this) { -- tty->print(" #tripcount"); -+ st->print(" #tripcount"); - } - } - #endif -@@ -1774,9 +1836,9 @@ - } - - #ifndef PRODUCT --void JumpProjNode::dump_spec() const { -- ProjNode::dump_spec(); -- tty->print("@bci %d ",_dest_bci); -+void JumpProjNode::dump_spec(outputStream *st) const { -+ ProjNode::dump_spec(st); -+ st->print("@bci %d ",_dest_bci); - } - #endif - -@@ -1862,9 +1924,9 @@ - - - #ifndef PRODUCT --void CatchProjNode::dump_spec() const { -- ProjNode::dump_spec(); -- tty->print("@bci %d ",_handler_bci); -+void CatchProjNode::dump_spec(outputStream *st) const { -+ ProjNode::dump_spec(st); -+ st->print("@bci %d ",_handler_bci); - } - #endif - -@@ -1886,8 +1948,7 @@ - - //============================================================================= - #ifndef PRODUCT --void NeverBranchNode::format( PhaseRegAlloc *ra_ ) const { -- tty->print("%s", Name()); -+void NeverBranchNode::format( PhaseRegAlloc *ra_, outputStream *st) const { -+ st->print("%s", Name()); - } - #endif -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/cfgnode.hpp openjdk/hotspot/src/share/vm/opto/cfgnode.hpp ---- openjdk6/hotspot/src/share/vm/opto/cfgnode.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/cfgnode.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)cfgnode.hpp 1.115 07/05/05 17:06:11 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -170,7 +167,7 @@ - virtual const RegMask &out_RegMask() const; - virtual const RegMask &in_RegMask(uint) const; - #ifndef PRODUCT -- virtual void dump_spec() const; -+ virtual void dump_spec(outputStream *st) const; - #endif - #ifdef ASSERT - void verify_adr_type(VectorSet& visited, const TypePtr* at) const; -@@ -316,7 +313,7 @@ - static Node* up_one_dom(Node* curr, bool linear_only = false); - - #ifndef PRODUCT -- virtual void dump_spec() const; -+ virtual void dump_spec(outputStream *st) const; - #endif - }; - -@@ -398,7 +395,7 @@ - int switch_val() const { return _switch_val; } - uint proj_no() const { return _proj_no; } - #ifndef PRODUCT -- virtual void dump_spec() const; -+ virtual void dump_spec(outputStream *st) const; - #endif - }; - -@@ -445,7 +442,7 @@ - int handler_bci() const { return _handler_bci; } - bool is_handler_proj() const { return _handler_bci >= 0; } - #ifndef PRODUCT -- virtual void dump_spec() const; -+ virtual void dump_spec(outputStream *st) const; - #endif - }; - -@@ -479,7 +476,6 @@ - virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { } - virtual uint size(PhaseRegAlloc *ra_) const { return 0; } - #ifndef PRODUCT -- virtual void format( PhaseRegAlloc * ) const; -+ virtual void format( PhaseRegAlloc *, outputStream *st ) const; - #endif - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/chaitin.cpp openjdk/hotspot/src/share/vm/opto/chaitin.cpp ---- openjdk6/hotspot/src/share/vm/opto/chaitin.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/chaitin.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)chaitin.cpp 1.115 07/05/05 17:06:11 JVM" --#endif - /* - * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -1685,8 +1682,8 @@ - tty->print("L%d",r); - tty->print("/N%d ",m->_idx); - } -- if( n->is_Mach() ) n->as_Mach()->dump_spec(); -- else n->dump_spec(); -+ if( n->is_Mach() ) n->as_Mach()->dump_spec(tty); -+ else n->dump_spec(tty); - if( _spilled_once.test(n->_idx ) ) { - tty->print(" Spill_1"); - if( _spilled_twice.test(n->_idx ) ) -diff -ruNb openjdk6/hotspot/src/share/vm/opto/chaitin.hpp openjdk/hotspot/src/share/vm/opto/chaitin.hpp ---- openjdk6/hotspot/src/share/vm/opto/chaitin.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/chaitin.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)chaitin.hpp 1.159 07/05/05 17:06:09 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -295,7 +292,6 @@ - VectorSet _spilled_twice; // Nodes that have been spilled twice - - LRG_List _names; // Map from Nodes to Live RanGes -- uint n2lidx( const Node *n ) const { return _names[n->_idx]; } - - // Union-find map. Declared as a short for speed. - // Indexed by live-range number, it returns the compacted live-range number -@@ -359,6 +355,8 @@ - // Do all the real work of allocate - void Register_Allocate(); - -+ uint n2lidx( const Node *n ) const { return _names[n->_idx]; } -+ - #ifndef PRODUCT - bool trace_spilling() const { return _trace_spilling; } - #endif -diff -ruNb openjdk6/hotspot/src/share/vm/opto/classes.cpp openjdk/hotspot/src/share/vm/opto/classes.cpp ---- openjdk6/hotspot/src/share/vm/opto/classes.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/classes.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)classes.cpp 1.31 07/05/05 17:06:12 JVM" --#endif - /* - * Copyright 1997-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -35,4 +32,3 @@ - #define macro(x) int x##Node::Opcode() const { return Op_##x; } - #include "classes.hpp" - #undef macro -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/classes.hpp openjdk/hotspot/src/share/vm/opto/classes.hpp ---- openjdk6/hotspot/src/share/vm/opto/classes.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/classes.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)classes.hpp 1.177 07/05/05 17:06:12 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -118,6 +115,7 @@ - macro(If) - macro(IfFalse) - macro(IfTrue) -+macro(Initialize) - macro(JProj) - macro(Jump) - macro(JumpProj) -diff -ruNb openjdk6/hotspot/src/share/vm/opto/coalesce.cpp openjdk/hotspot/src/share/vm/opto/coalesce.cpp ---- openjdk6/hotspot/src/share/vm/opto/coalesce.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/coalesce.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)coalesce.cpp 1.195 07/05/17 17:43:24 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -218,7 +215,7 @@ - } - - // Dump node-specific info -- n->dump_spec(); -+ n->dump_spec(tty); - tty->print("\n"); - - } -@@ -916,4 +913,3 @@ - */ - } - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/coalesce.hpp openjdk/hotspot/src/share/vm/opto/coalesce.hpp ---- openjdk6/hotspot/src/share/vm/opto/coalesce.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/coalesce.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)coalesce.hpp 1.44 07/05/05 17:06:14 JVM" --#endif - /* - * Copyright 1997-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -110,4 +107,3 @@ - - void update_ifg(uint lr1, uint lr2, IndexSet *n_lr1, IndexSet *n_lr2); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/compile.cpp openjdk/hotspot/src/share/vm/opto/compile.cpp ---- openjdk6/hotspot/src/share/vm/opto/compile.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/compile.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)compile.cpp 1.631 07/05/17 15:57:33 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -313,8 +310,13 @@ - compile->init_type_arena(); - Type::Initialize(compile); - _compile->set_scratch_buffer_blob(NULL); -+ _compile->begin_method(); - } - CompileWrapper::~CompileWrapper() { -+ if (_compile->failing()) { -+ _compile->print_method("Failed"); -+ } -+ _compile->end_method(); - if (_compile->scratch_buffer_blob() != NULL) - BufferBlob::free(_compile->scratch_buffer_blob()); - _compile->env()->set_compiler_data(NULL); -@@ -436,6 +438,7 @@ - _node_bundling_base(NULL), - #ifndef PRODUCT - _trace_opto_output(TraceOptoOutput || method()->has_option("TraceOptoOutput")), -+ _printer(IdealGraphPrinter::printer()), - #endif - _congraph(NULL) { - C = this; -@@ -561,6 +564,12 @@ - - // Drain the list. - Finish_Warm(); -+#ifndef PRODUCT -+ if (_printer) { -+ _printer->print_inlining(this); -+ } -+#endif -+ - if (failing()) return; - NOT_PRODUCT( verify_graph_edges(); ) - -@@ -672,6 +681,7 @@ - _node_bundling_base(NULL), - #ifndef PRODUCT - _trace_opto_output(TraceOptoOutput), -+ _printer(NULL), - #endif - _congraph(NULL) { - C = this; -@@ -763,6 +773,7 @@ - set_root(new (this, 3) RootNode()); - // Now that you have a Root to point to, create the real TOP - set_cached_top_node( new (this, 1) ConNode(Type::TOP) ); -+ set_recent_alloc(NULL, NULL); - - // Create Debug Information Recorder to record scopes, oopmaps, etc. - env()->set_oop_recorder(new OopRecorder(comp_arena())); -@@ -1177,7 +1188,7 @@ - st->print(" +any"); - else st->print(" +%-3d", offset); - st->print(" in "); -- adr_type()->dump(); -+ adr_type()->dump_on(st); - const TypeOopPtr* tjp = adr_type()->isa_oopptr(); - if (field() != NULL && tjp) { - if (tjp->klass() != field()->holder() || -@@ -1447,6 +1458,8 @@ - - NOT_PRODUCT( verify_graph_edges(); ) - -+ print_method("Start"); -+ - { - // Iterative Global Value Numbering, including ideal transforms - // Initialize IterGVN with types and values from parse-time GVN -@@ -1455,6 +1468,9 @@ - NOT_PRODUCT( TracePhase t2("iterGVN", &_t_iterGVN, TimeCompiler); ) - igvn.optimize(); - } -+ -+ print_method("Iter GVN 1", 2); -+ - if (failing()) return; - - // get rid of the connection graph since it's information is not -@@ -1472,6 +1488,7 @@ - TracePhase t2("idealLoop", &_t_idealLoop, true); - PhaseIdealLoop ideal_loop( igvn, NULL, true ); - loop_opts_cnt--; -+ if (major_progress()) print_method("PhaseIdealLoop 1", 2); - if (failing()) return; - } - // Loop opts pass if partial peeling occurred in previous pass -@@ -1479,6 +1496,7 @@ - TracePhase t3("idealLoop", &_t_idealLoop, true); - PhaseIdealLoop ideal_loop( igvn, NULL, false ); - loop_opts_cnt--; -+ if (major_progress()) print_method("PhaseIdealLoop 2", 2); - if (failing()) return; - } - // Loop opts pass for loop-unrolling before CCP -@@ -1486,6 +1504,7 @@ - TracePhase t4("idealLoop", &_t_idealLoop, true); - PhaseIdealLoop ideal_loop( igvn, NULL, false ); - loop_opts_cnt--; -+ if (major_progress()) print_method("PhaseIdealLoop 3", 2); - } - } - if (failing()) return; -@@ -1497,6 +1516,8 @@ - TracePhase t2("ccp", &_t_ccp, true); - ccp.do_transform(); - } -+ print_method("PhaseCPP 1", 2); -+ - assert( true, "Break here to ccp.dump_old2new_map()"); - - // Iterative Global Value Numbering, including ideal transforms -@@ -1505,6 +1526,9 @@ - igvn = ccp; - igvn.optimize(); - } -+ -+ print_method("Iter GVN 2", 2); -+ - if (failing()) return; - - // Loop transforms on the ideal graph. Range Check Elimination, -@@ -1516,6 +1540,7 @@ - assert( cnt++ < 40, "infinite cycle in loop optimization" ); - PhaseIdealLoop ideal_loop( igvn, NULL, true ); - loop_opts_cnt--; -+ if (major_progress()) print_method("PhaseIdealLoop iterations", 2); - if (failing()) return; - } - } -@@ -1538,6 +1563,8 @@ - return; - } - } -+ -+ print_method("Optimize finished", 2); - } - - -@@ -1583,6 +1610,9 @@ - - cfg.Estimate_Block_Frequency(); - cfg.GlobalCodeMotion(m,unique(),proj_list); -+ -+ print_method("Global code motion", 2); -+ - if (failing()) return; - NOT_PRODUCT( verify_graph_edges(); ) - -@@ -1635,6 +1665,8 @@ - Output(); - } - -+ print_method("End"); -+ - // He's dead, Jim. - _cfg = (PhaseCFG*)0xdeadbeef; - _regalloc = (PhaseChaitin*)0xdeadbeef; -@@ -1703,7 +1735,7 @@ - tty->print(" %c ", starts_bundle); - starts_bundle = ' '; - tty->print("\t"); -- n->format(_regalloc); -+ n->format(_regalloc, tty); - tty->cr(); - } - -@@ -1720,7 +1752,7 @@ - tty->print(" %c ", starts_bundle); - starts_bundle = ' '; - tty->print("\t"); -- delay->format(_regalloc); -+ delay->format(_regalloc, tty); - tty->print_cr(""); - delay = NULL; - } -@@ -2123,17 +2155,28 @@ - CallNode *call = n->in(0)->in(0)->as_Call(); - if (call->entry_point() == OptoRuntime::rethrow_stub()) { - expected_kids--; // Rethrow always has 1 less kid -- } else if (call->req() > TypeFunc::Parms) { -+ } else if (call->req() > TypeFunc::Parms && -+ call->is_CallDynamicJava()) { - // Check for null receiver. In such case, the optimizer has - // detected that the virtual call will always result in a null - // pointer exception. The fall-through projection of this CatchNode - // will not be populated. - Node *arg0 = call->in(TypeFunc::Parms); -- if (call->is_CallDynamicJava() && -- arg0->is_Type() && -+ if (arg0->is_Type() && - arg0->as_Type()->type()->higher_equal(TypePtr::NULL_PTR)) { - expected_kids--; - } -+ } else if (call->entry_point() == OptoRuntime::new_array_Java() && -+ call->req() > TypeFunc::Parms+1 && -+ call->is_CallStaticJava()) { -+ // Check for negative array length. In such case, the optimizer has -+ // detected that the allocation attempt will always result in an -+ // exception. There is no fall-through projection of this CatchNode . -+ Node *arg1 = call->in(TypeFunc::Parms+1); -+ if (arg1->is_Type() && -+ arg1->as_Type()->type()->join(TypeInt::POS)->empty()) { -+ expected_kids--; -+ } - } - } - } -diff -ruNb openjdk6/hotspot/src/share/vm/opto/compile.hpp openjdk/hotspot/src/share/vm/opto/compile.hpp ---- openjdk6/hotspot/src/share/vm/opto/compile.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/compile.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)compile.hpp 1.230 07/05/17 15:57:38 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -174,6 +171,9 @@ - GrowableArray* _intrinsics; // List of intrinsics. - GrowableArray* _macro_nodes; // List of nodes which need to be expanded before matching. - ConnectionGraph* _congraph; -+#ifndef PRODUCT -+ IdealGraphPrinter* _printer; -+#endif - - // Node management - uint _unique; // Counter for unique Node indices -@@ -185,6 +185,9 @@ - - Node* _immutable_memory; // Initial memory state - -+ Node* _recent_alloc_obj; -+ Node* _recent_alloc_ctl; -+ - // Blocked array of debugging and profiling information, - // tracked per node. - enum { _log2_node_notes_block_size = 8, -@@ -316,6 +319,23 @@ - #ifndef PRODUCT - bool trace_opto_output() const { return _trace_opto_output; } - #endif -+ -+ void begin_method() { -+#ifndef PRODUCT -+ if (_printer) _printer->begin_method(this); -+#endif -+ } -+ void print_method(const char * name, int level = 1) { -+#ifndef PRODUCT -+ if (_printer) _printer->print_method(this, name, level); -+#endif -+ } -+ void end_method() { -+#ifndef PRODUCT -+ if (_printer) _printer->end_method(); -+#endif -+ } -+ - int macro_count() { return _macro_nodes->length(); } - Node* macro_node(int idx) { return _macro_nodes->at(idx); } - ConnectionGraph* congraph() { return _congraph;} -@@ -373,6 +393,13 @@ - void init_start(StartNode* s); - Node* immutable_memory(); - -+ Node* recent_alloc_ctl() const { return _recent_alloc_ctl; } -+ Node* recent_alloc_obj() const { return _recent_alloc_obj; } -+ void set_recent_alloc(Node* ctl, Node* obj) { -+ _recent_alloc_ctl = ctl; -+ _recent_alloc_obj = obj; -+ } -+ - // Handy undefined Node - Node* top() const { return _top; } - -diff -ruNb openjdk6/hotspot/src/share/vm/opto/connode.cpp openjdk/hotspot/src/share/vm/opto/connode.cpp ---- openjdk6/hotspot/src/share/vm/opto/connode.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/connode.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)connode.cpp 1.217 07/05/17 15:57:42 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -780,7 +777,7 @@ - // remove this node's type assertion until no more loop ops can happen. - // The progress bit is set in the major loop optimizations THEN comes the - // call to IterGVN and any chance of hitting this code. Cf. Opaque1Node. -- if (!phase->C->major_progress()) { -+ if (can_reshape && !phase->C->major_progress()) { - const TypeInt* in_type = phase->type(in(1))->isa_int(); - if (in_type != NULL && this_type != NULL && - (in_type->_lo != this_type->_lo || -@@ -790,12 +787,34 @@ - // of slightly differing type assertions. Such slight differences - // arise routinely as a result of loop unrolling, so this is a - // post-unrolling graph cleanup. Choose a type which depends only -- // on my input. -- set_type(TypeLong::make(in_type->_lo, in_type->_hi, in_type->_widen)); -+ // on my input. (Exception: Keep a range assertion of >=0 or <0.) -+ jlong lo1 = this_type->_lo; -+ jlong hi1 = this_type->_hi; -+ int w1 = this_type->_widen; -+ if (lo1 != (jint)lo1 || -+ hi1 != (jint)hi1 || -+ lo1 > hi1) { -+ // Overflow leads to wraparound, wraparound leads to range saturation. -+ lo1 = min_jint; hi1 = max_jint; -+ } else if (lo1 >= 0) { -+ // Keep a range assertion of >=0. -+ lo1 = 0; hi1 = max_jint; -+ } else if (hi1 < 0) { -+ // Keep a range assertion of <0. -+ lo1 = min_jint; hi1 = -1; -+ } else { -+ lo1 = min_jint; hi1 = max_jint; -+ } -+ const TypeLong* wtype = TypeLong::make(MAX2((jlong)in_type->_lo, lo1), -+ MIN2((jlong)in_type->_hi, hi1), -+ MAX2((int)in_type->_widen, w1)); -+ if (wtype != type()) { -+ set_type(wtype); - // Note: this_type still has old type value, for the logic below. - this_changed = this; - } - } -+ } - - #ifdef _LP64 - // Convert ConvI2L(AddI(x, y)) to AddL(ConvI2L(x), ConvI2L(y)) , -diff -ruNb openjdk6/hotspot/src/share/vm/opto/connode.hpp openjdk/hotspot/src/share/vm/opto/connode.hpp ---- openjdk6/hotspot/src/share/vm/opto/connode.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/connode.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)connode.hpp 1.160 07/05/05 17:06:13 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/opto/divnode.cpp openjdk/hotspot/src/share/vm/opto/divnode.cpp ---- openjdk6/hotspot/src/share/vm/opto/divnode.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/divnode.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)divnode.cpp 1.88 07/05/05 17:06:13 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/opto/divnode.hpp openjdk/hotspot/src/share/vm/opto/divnode.hpp ---- openjdk6/hotspot/src/share/vm/opto/divnode.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/divnode.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)divnode.hpp 1.31 07/05/05 17:06:16 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -178,4 +175,3 @@ - // Make a divmod and associated projections from a div or mod. - static DivModLNode* make(Compile* C, Node* div_or_mod); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/doCall.cpp openjdk/hotspot/src/share/vm/opto/doCall.cpp ---- openjdk6/hotspot/src/share/vm/opto/doCall.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/doCall.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)doCall.cpp 1.206 07/05/17 15:57:45 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -151,8 +148,8 @@ - (profile.morphism() == 2 && UseBimorphicInlining)) { - // receiver_method = profile.method(); - // Profiles do not suggest methods now. Look it up in the major receiver. -- ciInstanceKlass* ik = profile.receiver(0)->as_instance_klass(); -- receiver_method = call_method->resolve_invoke(jvms->method()->holder(), ik); -+ receiver_method = call_method->resolve_invoke(jvms->method()->holder(), -+ profile.receiver(0)); - } - if (receiver_method != NULL) { - // The single majority receiver sufficiently outweighs the minority. -@@ -163,8 +160,8 @@ - CallGenerator* next_hit_cg = NULL; - ciMethod* next_receiver_method = NULL; - if (profile.morphism() == 2 && UseBimorphicInlining) { -- ciInstanceKlass* next_ik = profile.receiver(1)->as_instance_klass(); -- next_receiver_method = call_method->resolve_invoke(jvms->method()->holder(), next_ik); -+ next_receiver_method = call_method->resolve_invoke(jvms->method()->holder(), -+ profile.receiver(1)); - if (next_receiver_method != NULL) { - next_hit_cg = this->call_generator(next_receiver_method, - vtable_index, !call_is_virtual, jvms, -@@ -313,7 +310,7 @@ - // Try to get the most accurate receiver type - if (is_virtual_or_interface) { - Node* receiver_node = stack(sp() - nargs); -- const TypeInstPtr* receiver_type = _gvn.type(receiver_node)->isa_instptr(); -+ const TypeOopPtr* receiver_type = _gvn.type(receiver_node)->isa_oopptr(); - ciMethod* optimized_virtual_method = optimize_inlining(method(), bci(), klass, dest_method, receiver_type); - - // Have the call been sufficiently improved such that it is no longer a virtual? -@@ -768,7 +765,7 @@ - - // Identify possible target method and inlining style - ciMethod* Parse::optimize_inlining(ciMethod* caller, int bci, ciInstanceKlass* klass, -- ciMethod *dest_method, const TypeInstPtr* receiver_type) { -+ ciMethod *dest_method, const TypeOopPtr* receiver_type) { - // only use for virtual or interface calls - - // If it is obviously final, do not bother to call find_monomorphic_target, -@@ -783,6 +780,17 @@ - bool actual_receiver_is_exact = false; - ciInstanceKlass* actual_receiver = klass; - if (receiver_type != NULL) { -+ // Array methods are all inherited from Object, and are monomorphic. -+ if (receiver_type->isa_aryptr() && -+ dest_method->holder() == env()->Object_klass()) { -+ return dest_method; -+ } -+ -+ // All other interesting cases are instance klasses. -+ if (!receiver_type->isa_instptr()) { -+ return NULL; -+ } -+ - ciInstanceKlass *ikl = receiver_type->klass()->as_instance_klass(); - if (ikl->is_loaded() && ikl->is_initialized() && !ikl->is_interface() && - (ikl == actual_receiver || ikl->is_subclass_of(actual_receiver))) { -diff -ruNb openjdk6/hotspot/src/share/vm/opto/domgraph.cpp openjdk/hotspot/src/share/vm/opto/domgraph.cpp ---- openjdk6/hotspot/src/share/vm/opto/domgraph.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/domgraph.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)domgraph.cpp 1.75 07/05/05 17:06:16 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -281,7 +278,9 @@ - } - else { - // Build a reverse post-order in the CFG _blocks array -- _blocks.map(--_rpo_ctr, bstack.pop()); -+ Block *stack_top = bstack.pop(); -+ stack_top->_rpo = --_rpo_ctr; -+ _blocks.map(stack_top->_rpo, stack_top); - } - } - return pre_order; -@@ -663,4 +662,3 @@ - - } - #endif -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/escape.cpp openjdk/hotspot/src/share/vm/opto/escape.cpp ---- openjdk6/hotspot/src/share/vm/opto/escape.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/escape.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)escape.cpp 1.10 07/05/17 15:58:23 JVM" --#endif - /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/opto/escape.hpp openjdk/hotspot/src/share/vm/opto/escape.hpp ---- openjdk6/hotspot/src/share/vm/opto/escape.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/escape.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)escape.hpp 1.9 07/05/17 15:58:25 JVM" --#endif - /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -320,4 +317,3 @@ - void dump(); - #endif - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/gcm.cpp openjdk/hotspot/src/share/vm/opto/gcm.cpp ---- openjdk6/hotspot/src/share/vm/opto/gcm.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/gcm.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)gcm.cpp 1.251 07/05/17 15:58:45 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -743,7 +740,7 @@ - - // Now schedule all uses as late as possible. - uint src = self->is_Proj() ? self->in(0)->_idx : self->_idx; -- uint src_pre_order = _bbs[src]->_pre_order; -+ uint src_rpo = _bbs[src]->_rpo; - - // Schedule all nodes in a post-order visit - Node *unvisited = NULL; // Unvisited anti-dependent Node, if any -@@ -759,13 +756,13 @@ - - // do not traverse backward control edges - Node *use = n->is_Proj() ? n->in(0) : n; -- uint use_pre_order = _bbs[use->_idx]->_pre_order; -+ uint use_rpo = _bbs[use->_idx]->_rpo; - -- if ( use_pre_order < src_pre_order ) -+ if ( use_rpo < src_rpo ) - continue; - - // Phi nodes always precede uses in a basic block -- if ( use_pre_order == src_pre_order && use->is_Phi() ) -+ if ( use_rpo == src_rpo && use->is_Phi() ) - continue; - - unvisited = n; // Found unvisited -@@ -1314,323 +1311,457 @@ - #endif - } - --#define MAXFREQ BLOCK_FREQUENCY(1e35f) --#define MINFREQ BLOCK_FREQUENCY(1e-35f) - - //------------------------------Estimate_Block_Frequency----------------------- - // Estimate block frequencies based on IfNode probabilities. --// Two pass algorithm does a forward propagation in the first pass with some --// correction factors where static predictions are needed. Then, the second --// pass pushes through changes caused by back edges. This will give "exact" --// results for all dynamic frequencies, and for all staticly predicted code --// with loop nesting depth of one or less. Static predictions with greater --// than nesting depth of one are already subject to so many static fudge --// factors that it is not worth iterating to a fixed point. - void PhaseCFG::Estimate_Block_Frequency() { -- assert( _blocks[0] == _broot, "" ); - int cnts = C->method() ? C->method()->interpreter_invocation_count() : 1; - // Most of our algorithms will die horribly if frequency can become - // negative so make sure cnts is a sane value. - if( cnts <= 0 ) cnts = 1; - float f = (float)cnts/(float)FreqCountInvocations; -- _broot->_freq = f; -- _broot->_cnt = f; -- // Do a two pass propagation of frequency information -- // PASS 1: Walk the blocks in RPO, propagating frequency info -- uint i; -- for( i = 0; i < _num_blocks; i++ ) { -+ -+ // Create the loop tree and calculate loop depth. -+ _root_loop = create_loop_tree(); -+ _root_loop->compute_loop_depth(0); -+ -+ // Compute block frequency of each block, relative to a single loop entry. -+ _root_loop->compute_freq(); -+ -+ // Adjust all frequencies to be relative to a single method entry -+ _root_loop->_freq = f * 1.0; -+ _root_loop->scale_freq(); -+ -+ // force paths ending at uncommon traps to be infrequent -+ Block_List worklist; -+ Block* root_blk = _blocks[0]; -+ for (uint i = 0; i < root_blk->num_preds(); i++) { -+ Block *pb = _bbs[root_blk->pred(i)->_idx]; -+ if (pb->has_uncommon_code()) { -+ worklist.push(pb); -+ } -+ } -+ while (worklist.size() > 0) { -+ Block* uct = worklist.pop(); -+ uct->_freq = PROB_MIN; -+ for (uint i = 0; i < uct->num_preds(); i++) { -+ Block *pb = _bbs[uct->pred(i)->_idx]; -+ if (pb->_num_succs == 1 && pb->_freq > PROB_MIN) { -+ worklist.push(pb); -+ } -+ } -+ } -+ -+#ifndef PRODUCT -+ if (PrintCFGBlockFreq) { -+ tty->print_cr("CFG Block Frequencies"); -+ _root_loop->dump_tree(); -+ if (Verbose) { -+ tty->print_cr("PhaseCFG dump"); -+ dump(); -+ tty->print_cr("Node dump"); -+ _root->dump(99999); -+ } -+ } -+#endif -+} -+ -+//----------------------------create_loop_tree-------------------------------- -+// Create a loop tree from the CFG -+CFGLoop* PhaseCFG::create_loop_tree() { -+ -+#ifdef ASSERT -+ assert( _blocks[0] == _broot, "" ); -+ for (uint i = 0; i < _num_blocks; i++ ) { - Block *b = _blocks[i]; -+ // Check that _loop field are clear...we could clear them if not. -+ assert(b->_loop == NULL, "clear _loop expected"); -+ // Sanity check that the RPO numbering is reflected in the _blocks array. -+ // It doesn't have to be for the loop tree to be built, but if it is not, -+ // then the blocks have been reordered since dom graph building...which -+ // may question the RPO numbering -+ assert(b->_rpo == i, "unexpected reverse post order number"); -+ } -+#endif -+ -+ int idct = 0; -+ CFGLoop* root_loop = new CFGLoop(idct++); - -- // Make any necessary modifications to b's frequency -- int hop = b->head()->Opcode(); -- // On first trip, scale loop heads by 10 if no counts are available -- if( (hop == Op_Loop || hop == Op_CountedLoop) && -- (b->_cnt == COUNT_UNKNOWN) && (b->_freq < MAXFREQ) ) { -- // Try to figure out how much to scale the loop by; look for a -- // gating loop-exit test with "reasonable" back-branch -- // frequency. -- -- // Try and find a real loop-back controlling edge and use that -- // frequency. If we can't find it, use the old default of 10 -- // otherwise use the new value. This helps loops with low -- // frequency (like allocation contention loops with -UseTLE). -- // Note special treatment below of LoopNode::EntryControl edges. -- Block *loopprior = b; -- Block *loopback = _bbs[b->pred(LoopNode::LoopBackControl)->_idx]; -- // See if this block ends in a test (probably not) or just a -- // goto the loop head. -- if( loopback->_num_succs == 1 && -- loopback->num_preds() == 2 ) { -- loopprior = loopback; -- // NOTE: constant 1 here isn't magic, it's just that there's exactly 1 -- // predecessor (checked just above) and predecessors are 1-based, so -- // the "1" refers to the first (and only) predecessor. -- loopback = _bbs[loopprior->pred(1)->_idx]; -- } -- // Call the edge frequency leading from loopback to loopprior f. -- // Then scale the loop by 1/(1-f). Thus a loop-back edge -- // frequency of 0.9 leads to a scale factor of 10. -- float f = 0.9f; // Default scale factor -- -- if( loopback->_num_succs == 2 ) { -- int eidx = loopback->end_idx(); -- Node *mn = loopback->_nodes[eidx]; // Get ending Node -- if( mn->is_MachIf() ) { -- // MachIfNode has branch probability info -- f = mn->as_MachIf()->_prob; -- int taken = (loopback->_succs[1] == loopprior); -- assert( loopback->_succs[taken] == loopprior, "" ); -- if( loopback->_nodes[eidx+1+taken]->Opcode() == Op_IfFalse ) -- f = 1-f; // Inverted branch sense -- if( f > 0.99f ) // Limit scale to 100 -- f = 0.99f; -+ Block_List worklist; -+ -+ // Assign blocks to loops -+ for(uint i = _num_blocks - 1; i > 0; i-- ) { // skip Root block -+ Block *b = _blocks[i]; -+ -+ if (b->head()->is_Loop()) { -+ Block* loop_head = b; -+ assert(loop_head->num_preds() - 1 == 2, "loop must have 2 predecessors"); -+ Node* tail_n = loop_head->pred(LoopNode::LoopBackControl); -+ Block* tail = _bbs[tail_n->_idx]; -+ -+ // Defensively filter out Loop nodes for non-single-entry loops. -+ // For all reasonable loops, the head occurs before the tail in RPO. -+ if (i <= tail->_rpo) { -+ -+ // The tail and (recursive) predecessors of the tail -+ // are made members of a new loop. -+ -+ assert(worklist.size() == 0, "nonempty worklist"); -+ CFGLoop* nloop = new CFGLoop(idct++); -+ assert(loop_head->_loop == NULL, "just checking"); -+ loop_head->_loop = nloop; -+ // Add to nloop so push_pred() will skip over inner loops -+ nloop->add_member(loop_head); -+ nloop->push_pred(loop_head, LoopNode::LoopBackControl, worklist, _bbs); -+ -+ while (worklist.size() > 0) { -+ Block* member = worklist.pop(); -+ if (member != loop_head) { -+ for (uint j = 1; j < member->num_preds(); j++) { -+ nloop->push_pred(member, j, worklist, _bbs); -+ } -+ } -+ } -+ } - } - } - -- // Scale loop head by this much -- b->_freq *= 1/(1-f); -- assert(b->_freq > 0.0f,"Bad frequency assignment"); -- } -- -- // Push b's frequency to successors -- int eidx = b->end_idx(); -- Node *n = b->_nodes[eidx]; // Get ending Node -- int op = n->is_Mach() ? n->as_Mach()->ideal_Opcode() : n->Opcode(); -- // Switch on branch type -- switch( op ) { -- // Conditionals pass on only part of their frequency and count -- case Op_CountedLoopEnd: -- case Op_If: { -- int taken = 0; // this is the index of the TAKEN path -- int ntaken = 1; // this is the index of the NOT TAKEN path -- // If succ[0] is the FALSE branch, invert path info -- if( b->_nodes[eidx+1]->Opcode() == Op_IfFalse ) { -- taken = 1; -- ntaken = 0; -+ // Create a member list for each loop consisting -+ // of both blocks and (immediate child) loops. -+ for (uint i = 0; i < _num_blocks; i++) { -+ Block *b = _blocks[i]; -+ CFGLoop* lp = b->_loop; -+ if (lp == NULL) { -+ // Not assigned to a loop. Add it to the method's pseudo loop. -+ b->_loop = root_loop; -+ lp = root_loop; - } -- float prob = n->as_MachIf()->_prob; -- float nprob = 1.0f - prob; -- float cnt = n->as_MachIf()->_fcnt; -- // If branch frequency info is available, use it -- if(cnt != COUNT_UNKNOWN) { -- float tcnt = b->_succs[taken]->_cnt; -- float ncnt = b->_succs[ntaken]->_cnt; -- // Taken Branch -- b->_succs[taken]->_freq += prob * cnt; -- b->_succs[taken]->_cnt = (tcnt == COUNT_UNKNOWN) ? (prob * cnt) : tcnt + (prob * cnt); -- // Not Taken Branch -- b->_succs[ntaken]->_freq += nprob * cnt; -- b->_succs[ntaken]->_cnt = (ncnt == COUNT_UNKNOWN) ? (nprob * cnt) : ncnt + (nprob * cnt); -- } -- // Otherwise, split frequency amongst children -- else { -- b->_succs[taken]->_freq += prob * b->_freq; -- b->_succs[ntaken]->_freq += nprob * b->_freq; -- } -- // Special case for underflow caused by infrequent branches -- if(b->_succs[taken]->_freq < MINFREQ) b->_succs[taken]->_freq = MINFREQ; -- if(b->_succs[ntaken]->_freq < MINFREQ) b->_succs[ntaken]->_freq = MINFREQ; -- assert(b->_succs[0]->has_valid_counts(),"Bad frequency/count"); -- assert(b->_succs[1]->has_valid_counts(),"Bad frequency/count"); -- break; -+ if (lp == root_loop || b != lp->head()) { // loop heads are already members -+ lp->add_member(b); - } -- case Op_NeverBranch: { -- b->_succs[0]->_freq += b->_freq; -- // Special case for underflow caused by infrequent branches -- if(b->_succs[0]->_freq < MINFREQ) b->_succs[0]->_freq = MINFREQ; -- if(b->_succs[1]->_freq < MINFREQ) b->_succs[1]->_freq = MINFREQ; -- break; -+ if (lp != root_loop) { -+ if (lp->parent() == NULL) { -+ // Not a nested loop. Make it a child of the method's pseudo loop. -+ root_loop->add_nested_loop(lp); - } -- // Split frequency amongst children -- case Op_Jump: { -- // Divide the frequency between all successors evenly -- float predfreq = b->_freq/b->_num_succs; -- float predcnt = COUNT_UNKNOWN; -- for (uint j = 0; j < b->_num_succs; j++) { -- b->_succs[j]->_freq += predfreq; -- if (b->_succs[j]->_freq < MINFREQ) { -- b->_succs[j]->_freq = MINFREQ; -+ if (b == lp->head()) { -+ // Add nested loop to member list of parent loop. -+ lp->parent()->add_member(lp); - } -- assert(b->_succs[j]->has_valid_counts(), "Bad frequency/count"); - } -- break; - } -- // Split frequency amongst children -- case Op_Catch: { -- // Fall-thru path gets the lion's share. -- float fall = (1.0f - PROB_UNLIKELY_MAG(5)*b->_num_succs)*b->_freq; -- // Exception exits are uncommon. -- float expt = PROB_UNLIKELY_MAG(5) * b->_freq; -- // Iterate over children pushing out frequency -- for( uint j = 0; j < b->_num_succs; j++ ) { -- const CatchProjNode *x = b->_nodes[eidx+1+j]->as_CatchProj(); -- b->_succs[j]->_freq += -- ((x->_con == CatchProjNode::fall_through_index) ? fall : expt); -- // Special case for underflow caused by nested catches -- if(b->_succs[j]->_freq < MINFREQ) b->_succs[j]->_freq = MINFREQ; -- assert(b->_succs[j]->has_valid_counts(), "Bad Catch frequency/count assignment"); -+ -+ return root_loop; -+} -+ -+//------------------------------push_pred-------------------------------------- -+void CFGLoop::push_pred(Block* blk, int i, Block_List& worklist, Block_Array& node_to_blk) { -+ Node* pred_n = blk->pred(i); -+ Block* pred = node_to_blk[pred_n->_idx]; -+ CFGLoop *pred_loop = pred->_loop; -+ if (pred_loop == NULL) { -+ // Filter out blocks for non-single-entry loops. -+ // For all reasonable loops, the head occurs before the tail in RPO. -+ if (pred->_rpo > head()->_rpo) { -+ pred->_loop = this; -+ worklist.push(pred); -+ } -+ } else if (pred_loop != this) { -+ // Nested loop. -+ while (pred_loop->_parent != NULL && pred_loop->_parent != this) { -+ pred_loop = pred_loop->_parent; -+ } -+ // Make pred's loop be a child -+ if (pred_loop->_parent == NULL) { -+ add_nested_loop(pred_loop); -+ // Continue with loop entry predecessor. -+ Block* pred_head = pred_loop->head(); -+ assert(pred_head->num_preds() - 1 == 2, "loop must have 2 predecessors"); -+ assert(pred_head != head(), "loop head in only one loop"); -+ push_pred(pred_head, LoopNode::EntryControl, worklist, node_to_blk); -+ } else { -+ assert(pred_loop->_parent == this && _parent == NULL, "just checking"); - } -- break; - } -- // Pass frequency straight thru to target -- case Op_Root: -- case Op_Goto: { -- Block *bs = b->_succs[0]; -- int hop = bs->head()->Opcode(); -- bool notloop = (hop != Op_Loop && hop != Op_CountedLoop); -- // Pass count straight thru to target (except for loops) -- if( notloop && b->_cnt != COUNT_UNKNOWN ) { -- if( bs->_cnt == COUNT_UNKNOWN ) -- bs->_cnt = 0; -- bs->_cnt += b->_cnt; -- } -- // Loops and counted loops have already had their heads scaled -- // by an amount which accounts for the backedge (but not their -- // entry). Add frequency for normal blocks and loop entries. -- // Note special treatment above of LoopNode::LoopBackControl edges. -- if( notloop || bs->_freq <= 0 /*this is needed for irreducible loops*/|| -- _bbs[bs->pred(LoopNode::EntryControl)->_idx] == b ) -- bs->_freq += b->_freq; -+} - -- assert(bs->has_valid_counts(), "Bad goto frequency/count assignment"); -- break; -+//------------------------------add_nested_loop-------------------------------- -+// Make cl a child of the current loop in the loop tree. -+void CFGLoop::add_nested_loop(CFGLoop* cl) { -+ assert(_parent == NULL, "no parent yet"); -+ assert(cl != this, "not my own parent"); -+ cl->_parent = this; -+ CFGLoop* ch = _child; -+ if (ch == NULL) { -+ _child = cl; -+ } else { -+ while (ch->_sibling != NULL) { ch = ch->_sibling; } -+ ch->_sibling = cl; - } -- // Do not push out freq to root block -- case Op_TailCall: -- case Op_TailJump: -- case Op_Return: -- case Op_Halt: -- case Op_Rethrow: -- break; -- default: -- ShouldNotReachHere(); -- } // End switch(op) -- assert(b->has_valid_counts(), "Bad first pass frequency/count"); -- } // End for all blocks -+} - -+//------------------------------compute_loop_depth----------------------------- -+// Store the loop depth in each CFGLoop object. -+// Recursively walk the children to do the same for them. -+void CFGLoop::compute_loop_depth(int depth) { -+ _depth = depth; -+ CFGLoop* ch = _child; -+ while (ch != NULL) { -+ ch->compute_loop_depth(depth + 1); -+ ch = ch->_sibling; -+ } -+} - -- // PASS 2: Fix up loop bodies -- for( i = 1; i < _num_blocks; i++ ) { -- Block *b = _blocks[i]; -- float freq = 0.0f; -- float cnt = COUNT_UNKNOWN; -- // If it ends in a Halt or call marked uncommon, assume the block is uncommon. -- Node* be = b->end(); -- if (be->is_Goto()) -- be = be->in(0); -- if (be->is_Catch()) -- be = be->in(0); -- if (be->is_Proj() && be->in(0)->is_MachCall()) { -- MachCallNode* call = be->in(0)->as_MachCall(); -- if (call->cnt() != COUNT_UNKNOWN && call->cnt() <= PROB_UNLIKELY_MAG(4)) { -- // This is true for slow-path stubs like new_{instance,array}, -- // slow_arraycopy, complete_monitor_locking, uncommon_trap. -- // The magic number corresponds to the probability of an uncommon_trap, -- // even though it is a count not a probability. -- if (b->_freq > BLOCK_FREQUENCY(1e-6)) -- b->_freq = BLOCK_FREQUENCY(1e-6f); -- continue; -+//------------------------------compute_freq----------------------------------- -+// Compute the frequency of each block and loop, relative to a single entry -+// into the dominating loop head. -+void CFGLoop::compute_freq() { -+ // Bottom up traversal of loop tree (visit inner loops first.) -+ // Set loop head frequency to 1.0, then transitively -+ // compute frequency for all successors in the loop, -+ // as well as for each exit edge. Inner loops are -+ // treated as single blocks with loop exit targets -+ // as the successor blocks. -+ -+ // Nested loops first -+ CFGLoop* ch = _child; -+ while (ch != NULL) { -+ ch->compute_freq(); -+ ch = ch->_sibling; -+ } -+ assert (_members.length() > 0, "no empty loops"); -+ Block* hd = head(); -+ hd->_freq = 1.0f; -+ for (int i = 0; i < _members.length(); i++) { -+ CFGElement* s = _members.at(i); -+ float freq = s->_freq; -+ if (s->is_block()) { -+ Block* b = s->as_Block(); -+ for (uint j = 0; j < b->_num_succs; j++) { -+ Block* sb = b->_succs[j]; -+ update_succ_freq(sb, freq * b->succ_prob(j)); -+ } -+ } else { -+ CFGLoop* lp = s->as_CFGLoop(); -+ assert(lp->_parent == this, "immediate child"); -+ for (int k = 0; k < lp->_exits.length(); k++) { -+ Block* eb = lp->_exits.at(k).get_target(); -+ float prob = lp->_exits.at(k).get_prob(); -+ update_succ_freq(eb, freq * prob); - } - } -- if (be->is_Mach() && be->as_Mach()->ideal_Opcode() == Op_Halt) { -- if( b->_freq > BLOCK_FREQUENCY(1e-6) ) -- b->_freq = BLOCK_FREQUENCY(1e-6f); -- continue; - } - -- // Recompute frequency based upon predecessors' frequencies -- for(uint j = 1; j < b->num_preds(); j++) { -- // Compute the frequency passed along this path -- Node *pred = b->head()->in(j); -- // Peek through projections -- if(pred->is_Proj()) pred = pred->in(0); -- // Grab the predecessor block's frequency -- Block *pblock = _bbs[pred->_idx]; -- float predfreq = pblock->_freq; -- float predcnt = pblock->_cnt; -- // Properly modify the frequency for this exit path -- int op = pred->is_Mach() ? pred->as_Mach()->ideal_Opcode() : pred->Opcode(); -+#if 0 -+ // Raise frequency of the loop backedge block, in an effort -+ // to keep it empty. Skip the method level "loop". -+ if (_parent != NULL) { -+ CFGElement* s = _members.at(_members.length() - 1); -+ if (s->is_block()) { -+ Block* bk = s->as_Block(); -+ if (bk->_num_succs == 1 && bk->_succs[0] == hd) { -+ // almost any value >= 1.0f works -+ // FIXME: raw constant -+ bk->_freq = 1.05f; -+ } -+ } -+ } -+#endif -+ -+ // For all loops other than the outer, "method" loop, -+ // sum and normalize the exit probability. The "method" loop -+ // should keep the initial exit probability of 1, so that -+ // inner blocks do not get erroneously scaled. -+ if (_depth != 0) { -+ // Total the exit probabilities for this loop. -+ float exits_sum = 0.0f; -+ for (int i = 0; i < _exits.length(); i++) { -+ exits_sum += _exits.at(i).get_prob(); -+ } -+ -+ // Normalize the exit probabilities. Until now, the -+ // probabilities estimate the possibility of exit per -+ // a single loop iteration; afterward, they estimate -+ // the probability of exit per loop entry. -+ for (int i = 0; i < _exits.length(); i++) { -+ Block* et = _exits.at(i).get_target(); -+ float new_prob = _exits.at(i).get_prob() / exits_sum; -+ BlockProbPair bpp(et, new_prob); -+ _exits.at_put(i, bpp); -+ } -+ -+ // Save the total, but guard against unreasoable probability, -+ // as the value is used to estimate the loop trip count. -+ // An infinite trip count would blur relative block -+ // frequencies. -+ if (exits_sum > 1.0f) exits_sum = 1.0; -+ if (exits_sum < PROB_MIN) exits_sum = PROB_MIN; -+ _exit_prob = exits_sum; -+ } -+} -+ -+//------------------------------succ_prob------------------------------------- -+// Determine the probability of reaching successor 'i' from the receiver block. -+float Block::succ_prob(uint i) { -+ int eidx = end_idx(); -+ Node *n = _nodes[eidx]; // Get ending Node -+ int op = n->is_Mach() ? n->as_Mach()->ideal_Opcode() : n->Opcode(); -+ - // Switch on branch type -- switch(op) { -- // Conditionals pass on only part of their frequency and count -+ switch( op ) { - case Op_CountedLoopEnd: - case Op_If: { -- float prob = pred->as_MachIf()->_prob; -- float cnt = pred->as_MachIf()->_fcnt; -- bool path = true; -- // Is this the TRUE branch or the FALSE branch? -- if( b->head()->in(j)->Opcode() == Op_IfFalse ) -- path = false; -- // If branch frequency info is available, use it -- if(cnt != COUNT_UNKNOWN) { -- predfreq = (path) ? (prob * cnt) : ((1.0f-prob) * cnt); -- predcnt = (path) ? (prob * cnt) : ((1.0f-prob) * cnt); -- } -- // Otherwise, split frequency amongst children -- else { -- predfreq = (path) ? (prob * predfreq) : ((1.0f-prob) * predfreq); -- predcnt = COUNT_UNKNOWN; -+ assert (i < 2, "just checking"); -+ // Conditionals pass on only part of their frequency -+ float prob = n->as_MachIf()->_prob; -+ assert(prob >= 0.0 && prob <= 1.0, "out of range probability"); -+ // If succ[i] is the FALSE branch, invert path info -+ if( _nodes[i + eidx + 1]->Opcode() == Op_IfFalse ) { -+ return 1.0f - prob; // not taken -+ } else { -+ return prob; // taken - } -- if( predfreq < MINFREQ ) predfreq = MINFREQ; -- -- // Raise frequency of the loop backedge block, in an effort -- // to keep it empty. Must raise it by 10%+ because counted -- // loops normally keep a 90/10 exit ratio. -- if( op == Op_CountedLoopEnd && b->num_preds() == 2 && path == true ) -- predfreq *= 1.15f; -- break; - } -- // Catch splits frequency amongst multiple children -- case Op_Jump: { -+ -+ case Op_Jump: - // Divide the frequency between all successors evenly -- predfreq = predfreq / pblock->_num_succs; -- predcnt = COUNT_UNKNOWN; -- if (predfreq < MINFREQ) predfreq = MINFREQ; -- break; -- } -- // Catch splits frequency amongst multiple children, favoring -- // fall through -+ return 1.0f/_num_succs; -+ - case Op_Catch: { -+ const CatchProjNode *ci = _nodes[i + eidx + 1]->as_CatchProj(); -+ if (ci->_con == CatchProjNode::fall_through_index) { - // Fall-thru path gets the lion's share. -- float fall = (1.0f - PROB_UNLIKELY_MAG(5)*pblock->_num_succs)*predfreq; -- // Exception exits are uncommon. -- float expt = PROB_UNLIKELY_MAG(5) * predfreq; -- // Determine if this is fall-thru path -- const CatchProjNode *x = b->head()->in(j)->as_CatchProj(); -- predfreq = (x->_con == CatchProjNode::fall_through_index) ? fall :expt; -- predcnt = COUNT_UNKNOWN; -- if(predfreq < MINFREQ) predfreq = MINFREQ; -- break; -+ return 1.0f - PROB_UNLIKELY_MAG(5)*_num_succs; -+ } else { -+ // Presume exceptional paths are equally unlikely -+ return PROB_UNLIKELY_MAG(5); - } -- // Pass frequency straight thru to target -+ } -+ - case Op_Root: - case Op_Goto: -- case Op_Start: -+ // Pass frequency straight thru to target -+ return 1.0f; -+ - case Op_NeverBranch: -- break; -- // These do not push out a frequency or count -+ return 0.0f; -+ - case Op_TailCall: - case Op_TailJump: - case Op_Return: - case Op_Halt: - case Op_Rethrow: -- predfreq = 0.0f; -- predcnt = COUNT_UNKNOWN; -- break; -+ // Do not push out freq to root block -+ return 0.0f; -+ - default: - ShouldNotReachHere(); -- } // End switch(op) -- assert(predfreq > 0.0f,"Bad intermediate frequency"); -- assert((predcnt > 0.0f) || (predcnt == COUNT_UNKNOWN),"Bad intermediate count"); -- // Accumulate frequency from predecessor block -- freq += predfreq; -- if (predcnt != COUNT_UNKNOWN) { -- cnt = (cnt == COUNT_UNKNOWN) ? predcnt : cnt + predcnt; - } -+ -+ return 0.0f; -+} -+ -+//------------------------------update_succ_freq------------------------------- -+// Update the appropriate frequency associated with block 'b', a succesor of -+// a block in this loop. -+void CFGLoop::update_succ_freq(Block* b, float freq) { -+ if (b->_loop == this) { -+ if (b == head()) { -+ // back branch within the loop -+ // Do nothing now, the loop carried frequency will be -+ // adjust later in scale_freq(). -+ } else { -+ // simple branch within the loop -+ b->_freq += freq; -+ } -+ } else if (!in_loop_nest(b)) { -+ // branch is exit from this loop -+ BlockProbPair bpp(b, freq); -+ _exits.append(bpp); -+ } else { -+ // branch into nested loop -+ CFGLoop* ch = b->_loop; -+ ch->_freq += freq; -+ } -+} -+ -+//------------------------------in_loop_nest----------------------------------- -+// Determine if block b is in the receiver's loop nest. -+bool CFGLoop::in_loop_nest(Block* b) { -+ int depth = _depth; -+ CFGLoop* b_loop = b->_loop; -+ int b_depth = b_loop->_depth; -+ if (depth == b_depth) { -+ return true; -+ } -+ while (b_depth > depth) { -+ b_loop = b_loop->_parent; -+ b_depth = b_loop->_depth; - } -- // Assign new frequency -- b->_freq = freq; -- b->_cnt = cnt; -- assert(b->has_valid_counts(), "Bad final frequency/count assignment"); -- } // End for all blocks -+ return b_loop == this; - } -+ -+//------------------------------scale_freq------------------------------------- -+// Scale frequency of loops and blocks by trip counts from outer loops -+// Do a top down traversal of loop tree (visit outer loops first.) -+void CFGLoop::scale_freq() { -+ float loop_freq = _freq * trip_count(); -+ for (int i = 0; i < _members.length(); i++) { -+ CFGElement* s = _members.at(i); -+ s->_freq *= loop_freq; -+ } -+ CFGLoop* ch = _child; -+ while (ch != NULL) { -+ ch->scale_freq(); -+ ch = ch->_sibling; -+ } -+} -+ -+#ifndef PRODUCT -+//------------------------------dump_tree-------------------------------------- -+void CFGLoop::dump_tree() const { -+ dump(); -+ if (_child != NULL) _child->dump_tree(); -+ if (_sibling != NULL) _sibling->dump_tree(); -+} -+ -+//------------------------------dump------------------------------------------- -+void CFGLoop::dump() const { -+ for (int i = 0; i < _depth; i++) tty->print(" "); -+ tty->print("%s: %d trip_count: %6.0f freq: %6.0f\n", -+ _depth == 0 ? "Method" : "Loop", _id, trip_count(), _freq); -+ for (int i = 0; i < _depth; i++) tty->print(" "); -+ tty->print(" members:", _id); -+ int k = 0; -+ for (int i = 0; i < _members.length(); i++) { -+ if (k++ >= 6) { -+ tty->print("\n "); -+ for (int j = 0; j < _depth+1; j++) tty->print(" "); -+ k = 0; -+ } -+ CFGElement *s = _members.at(i); -+ if (s->is_block()) { -+ Block *b = s->as_Block(); -+ tty->print(" B%d(%6.3f)", b->_pre_order, b->_freq); -+ } else { -+ CFGLoop* lp = s->as_CFGLoop(); -+ tty->print(" L%d(%6.3f)", lp->_id, lp->_freq); -+ } -+ } -+ tty->print("\n"); -+ for (int i = 0; i < _depth; i++) tty->print(" "); -+ tty->print(" exits: "); -+ k = 0; -+ for (int i = 0; i < _exits.length(); i++) { -+ if (k++ >= 7) { -+ tty->print("\n "); -+ for (int j = 0; j < _depth+1; j++) tty->print(" "); -+ k = 0; -+ } -+ Block *blk = _exits.at(i).get_target(); -+ float prob = _exits.at(i).get_prob(); -+ tty->print(" ->%d@%d%%", blk->_pre_order, (int)(prob*100)); -+ } -+ tty->print("\n"); -+} -+#endif -diff -ruNb openjdk6/hotspot/src/share/vm/opto/generateOptoStub.cpp openjdk/hotspot/src/share/vm/opto/generateOptoStub.cpp ---- openjdk6/hotspot/src/share/vm/opto/generateOptoStub.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/generateOptoStub.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)generateOptoStub.cpp 1.101 07/05/05 17:06:17 JVM" --#endif - /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -292,4 +289,3 @@ - } - root()->add_req(_gvn.transform(ret)); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/graphKit.cpp openjdk/hotspot/src/share/vm/opto/graphKit.cpp ---- openjdk6/hotspot/src/share/vm/opto/graphKit.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/graphKit.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)graphKit.cpp 1.128 07/05/17 17:43:32 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -541,11 +538,10 @@ - // Weblogic sometimes mutates the detail message of exceptions - // using reflection. - int offset = java_lang_Throwable::get_detailMessage_offset(); -- uint alias_idx = C->get_alias_index(ex_con->add_offset(offset)); -+ const TypePtr* adr_typ = ex_con->add_offset(offset); - - Node *adr = basic_plus_adr(ex_node, ex_node, offset); -- Node *store = store_to_memory(control(), adr, null(), T_OBJECT, alias_idx, false); -- store_barrier(store, T_OBJECT, ex_node, adr, null()); -+ Node *store = store_oop_to_object(control(), ex_node, adr, adr_typ, null(), ex_con, T_OBJECT); - - add_exception_state(make_exception_state(ex_node)); - return; -@@ -1352,6 +1348,102 @@ - return st; - } - -+void GraphKit::pre_barrier(Node* ctl, -+ Node* obj, -+ Node* adr, -+ uint adr_idx, -+ Node *val, -+ const Type* val_type, -+ BasicType bt) { -+ BarrierSet* bs = Universe::heap()->barrier_set(); -+ set_control(ctl); -+ switch (bs->kind()) { -+ -+ case BarrierSet::CardTableModRef: -+ case BarrierSet::CardTableExtension: -+ case BarrierSet::ModRef: -+ break; -+ -+ case BarrierSet::Other: -+ default : -+ ShouldNotReachHere(); -+ -+ } -+} -+ -+void GraphKit::post_barrier(Node* ctl, -+ Node* store, -+ Node* obj, -+ Node* adr, -+ uint adr_idx, -+ Node *val, -+ BasicType bt, -+ bool use_precise) { -+ BarrierSet* bs = Universe::heap()->barrier_set(); -+ set_control(ctl); -+ switch (bs->kind()) { -+ -+ case BarrierSet::CardTableModRef: -+ case BarrierSet::CardTableExtension: -+ write_barrier_post(store, obj, adr, val, use_precise); -+ break; -+ -+ case BarrierSet::ModRef: -+ break; -+ -+ case BarrierSet::Other: -+ default : -+ ShouldNotReachHere(); -+ -+ } -+} -+ -+Node* GraphKit::store_oop_to_object(Node* ctl, -+ Node* obj, -+ Node* adr, -+ const TypePtr* adr_type, -+ Node *val, -+ const Type* val_type, -+ BasicType bt) { -+ uint adr_idx = C->get_alias_index(adr_type); -+ Node* store; -+ pre_barrier(ctl, obj, adr, adr_idx, val, val_type, bt); -+ store = store_to_memory(control(), adr, val, bt, adr_idx); -+ post_barrier(control(), store, obj, adr, adr_idx, val, bt, false); -+ return store; -+} -+ -+Node* GraphKit::store_oop_to_array(Node* ctl, -+ Node* obj, -+ Node* adr, -+ const TypePtr* adr_type, -+ Node *val, -+ const Type* val_type, -+ BasicType bt) { -+ uint adr_idx = C->get_alias_index(adr_type); -+ Node* store; -+ pre_barrier(ctl, obj, adr, adr_idx, val, val_type, bt); -+ store = store_to_memory(control(), adr, val, bt, adr_idx); -+ post_barrier(control(), store, obj, adr, adr_idx, val, bt, true); -+ return store; -+} -+ -+Node* GraphKit::store_oop_to_unknown(Node* ctl, -+ Node* obj, -+ Node* adr, -+ const TypePtr* adr_type, -+ Node *val, -+ const Type* val_type, -+ BasicType bt) { -+ uint adr_idx = C->get_alias_index(adr_type); -+ Node* store; -+ pre_barrier(ctl, obj, adr, adr_idx, val, val_type, bt); -+ store = store_to_memory(control(), adr, val, bt, adr_idx); -+ post_barrier(control(), store, obj, adr, adr_idx, val, bt, true); -+ return store; -+} -+ -+ - //-------------------------array_element_address------------------------- - Node* GraphKit::array_element_address(Node* ary, Node* idx, BasicType elembt, - const TypeInt* sizetype) { -@@ -1537,7 +1629,8 @@ - // right debug info. - void GraphKit::uncommon_trap(int trap_request, - ciKlass* klass, const char* comment, -- bool must_throw) { -+ bool must_throw, -+ bool keep_exact_action) { - if (failing()) stop(); - if (stopped()) return; // trap reachable? - -@@ -1564,8 +1657,11 @@ - switch (action) { - case Deoptimization::Action_maybe_recompile: - case Deoptimization::Action_reinterpret: -- if (Deoptimization::trap_request_index(trap_request) < 0 -- && too_many_recompiles(reason)) { -+ // Temporary fix for 6529811 to allow virtual calls to be sure they -+ // get the chance to go from mono->bi->mega -+ if (!keep_exact_action && -+ Deoptimization::trap_request_index(trap_request) < 0 && -+ too_many_recompiles(reason)) { - // This BCI is causing too many recompilations. - action = Deoptimization::Action_none; - trap_request = Deoptimization::make_trap_request(reason, action); -@@ -1646,30 +1742,55 @@ - } - - -+//--------------------------just_allocated_object------------------------------ -+// Report the object that was just allocated. -+// It must be the case that there are no intervening safepoints. -+// We use this to determine if an object is so "fresh" that -+// it does not require card marks. -+Node* GraphKit::just_allocated_object(Node* current_control) { -+ if (C->recent_alloc_ctl() == current_control) -+ return C->recent_alloc_obj(); -+ return NULL; -+} -+ -+ - //------------------------------store_barrier---------------------------------- - // Insert a write-barrier store. This is to let generational GC work; we have - // to flag all oop-stores before the next GC point. --void GraphKit::store_barrier(Node* oop_store, BasicType obj_type, -- Node* obj, Node* adr, Node* val) { -+void GraphKit::write_barrier_post(Node* oop_store, Node* obj, Node* adr, -+ Node* val, bool use_precise) { - // No store check needed if we're storing a NULL or an old object - // (latter case is probably a string constant). The concurrent - // mark sweep garbage collector, however, needs to have all nonNull - // oop updates flagged via card-marks. -- if (val != NULL && val->is_Con() && -- (!UseConcMarkSweepGC || val->bottom_type() == TypePtr::NULL_PTR)) { -+ if (val != NULL && val->is_Con()) { - // must be either an oop or NULL - const Type* t = val->bottom_type(); -- assert( t == Type::TOP || t == TypePtr::NULL_PTR || t->is_oopptr()->const_oop() != NULL, -- "must be either a constant oop or NULL"); -+ if (t == TypePtr::NULL_PTR || t == Type::TOP) -+ // stores of null never (?) need barriers -+ return; -+ ciObject* con = t->is_oopptr()->const_oop(); -+ if (con != NULL -+ && con->is_perm() -+ && Universe::heap()->can_elide_permanent_oop_store_barriers()) - // no store barrier needed, because no old-to-new ref created - return; - } - -- if (obj_type == T_OBJECT) { -+ if (use_ReduceInitialCardMarks() -+ && obj == just_allocated_object(control())) { -+ // We can skip marks on a freshly-allocated object. -+ // Keep this code in sync with do_eager_card_mark in runtime.cpp. -+ // That routine eagerly marks the occasional object which is produced -+ // by the slow path, so that we don't have to do it here. -+ return; -+ } -+ -+ if (!use_precise) { - // All card marks for a (non-array) instance are in one place: - adr = obj; - } -- // (Else it's an array, and we want more precise card marks.) -+ // (Else it's an array (or unknown), and we want more precise card marks.) - assert(adr != NULL, ""); - - // Get the alias_index for raw card-mark memory -@@ -1681,9 +1802,8 @@ - "Only one we handle so far."); - CardTableModRefBS* ct = - (CardTableModRefBS*)(Universe::heap()->barrier_set()); -- Node *a = _gvn.transform(new (C, 3) URShiftXNode( cast, _gvn.intcon(CardTableModRefBS::card_shift) )); -+ Node *b = _gvn.transform(new (C, 3) URShiftXNode( cast, _gvn.intcon(CardTableModRefBS::card_shift) )); - // We store into a byte array, so do not bother to left-shift by zero -- Node *b = a; - // Get base of card map - assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), - "adjust this code"); -@@ -2483,6 +2603,7 @@ - if (alias_idx == Compile::AliasIdxBot) { - mb->set_req(TypeFunc::Memory, merged_memory()->base_memory()); - } else { -+ assert(!(opcode == Op_Initialize && alias_idx != Compile::AliasIdxRaw), "fix caller"); - mb->set_req(TypeFunc::Memory, memory(alias_idx)); - } - Node* membar = _gvn.transform(mb); -@@ -2602,21 +2723,6 @@ - map()->pop_monitor( ); - } - --//---------------------------set_eden_pointers------------------------- --void GraphKit::set_eden_pointers( Node * &eden_top_adr, Node * &eden_end_adr) { -- CollectedHeap* ch = Universe::heap(); -- if( UseTLAB ) { // Private allocation: load from TLS -- Node *thread = _gvn.transform(new (C, 1) ThreadLocalNode()); -- eden_top_adr = _gvn.transform( new (C, 4) AddPNode(top()/*not oop*/, thread, _gvn.MakeConX( in_bytes(JavaThread::tlab_top_offset())))); -- eden_end_adr = _gvn.transform( new (C, 4) AddPNode(top()/*not oop*/, thread, _gvn.MakeConX( in_bytes(JavaThread::tlab_end_offset())))); -- } else { // Shared allocation: load from globals -- address top_adr = (address)ch->top_addr(); -- address end_adr = (address)ch->end_addr(); -- eden_top_adr = makecon(TypeRawPtr::make(top_adr)); -- eden_end_adr = basic_plus_adr( eden_top_adr, eden_top_adr, end_adr - top_adr ); -- } --} -- - //-------------------------------get_layout_helper----------------------------- - // If the given klass is a constant or known to be an array, - // fetch the constant layout helper value into constant_value -@@ -2642,6 +2748,19 @@ - return make_load(NULL, lhp, TypeInt::INT, T_INT); - } - -+// We just put in an allocate/initialize with a big raw-memory effect. -+// Hook selected additional alias categories on the initialization. -+static void hook_memory_on_init(GraphKit& kit, int alias_idx, -+ MergeMemNode* init_in_merge, -+ Node* init_out_raw) { -+ DEBUG_ONLY(Node* init_in_raw = init_in_merge->base_memory()); -+ assert(init_in_merge->memory_at(alias_idx) == init_in_raw, ""); -+ -+ Node* prevmem = kit.memory(alias_idx); -+ init_in_merge->set_memory_at(alias_idx, prevmem); -+ kit.set_memory(init_out_raw, alias_idx); -+} -+ - //---------------------------set_output_for_allocation------------------------- - Node* GraphKit::set_output_for_allocation(AllocateNode* alloc, - const TypeOopPtr* oop_type, -@@ -2664,9 +2783,45 @@ - set_i_o(_gvn.transform( new (C, 1) ProjNode(allocx, TypeFunc::I_O, false) ) ); - Node* rawoop = _gvn.transform( new (C, 1) ProjNode(allocx, TypeFunc::Parms) ); - -+ // put in an initialization barrier -+ InitializeNode* init = insert_mem_bar_volatile(Op_Initialize, rawidx, -+ rawoop)->as_Initialize(); -+ assert(alloc->initialization() == init, "2-way macro link must work"); -+ assert(init ->allocation() == alloc, "2-way macro link must work"); -+ if (ReduceFieldZeroing && !raw_mem_only) { -+ // Extract memory strands which may participate in the new object's -+ // initialization, and source them from the new InitializeNode. -+ // This will allow us to observe initializations when they occur, -+ // and link them properly (as a group) to the InitializeNode. -+ Node* klass_node = alloc->in(AllocateNode::KlassNode); -+ assert(init->in(InitializeNode::Memory) == malloc, ""); -+ MergeMemNode* minit_in = MergeMemNode::make(C, malloc); -+ init->set_req(InitializeNode::Memory, minit_in); -+ record_for_igvn(minit_in); // fold it up later, if possible -+ Node* minit_out = memory(rawidx); -+ assert(minit_out->is_Proj() && minit_out->in(0) == init, ""); -+ if (oop_type->isa_aryptr()) { -+ const TypePtr* telemref = oop_type->add_offset(Type::OffsetBot); -+ int elemidx = C->get_alias_index(telemref); -+ hook_memory_on_init(*this, elemidx, minit_in, minit_out); -+ } else if (oop_type->isa_instptr()) { -+ ciInstanceKlass* ik = oop_type->klass()->as_instance_klass(); -+ for (int i = 0, len = ik->nof_nonstatic_fields(); i < len; i++) { -+ ciField* field = ik->nonstatic_field_at(i); -+ if (field->offset() >= TrackedInitializationLimit) -+ continue; // do not bother to track really large numbers of fields -+ // Find (or create) the alias category for this field: -+ int fieldidx = C->alias_type(field)->index(); -+ hook_memory_on_init(*this, fieldidx, minit_in, minit_out); -+ } -+ } -+ } -+ - // Cast raw oop to the real thing... - Node* javaoop = new (C, 2) CheckCastPPNode(control(), rawoop, oop_type); - javaoop = _gvn.transform(javaoop); -+ C->set_recent_alloc(control(), javaoop); -+ assert(just_allocated_object(control()) == javaoop, "just allocated"); - - #ifdef ASSERT - { // Verify that the AllocateNode::Ideal_foo recognizers work: -@@ -2703,7 +2858,6 @@ - Node* extra_slow_test, - bool raw_mem_only, // affect only raw memory - Node* *return_size_val) { -- - // Compute size in doublewords - // The size is always an integral number of doublewords, represented - // as a positive bytewise size stored in the klass's layout_helper. -@@ -2713,7 +2867,6 @@ - int layout_is_con = (layout_val == NULL); - - if (extra_slow_test == NULL) extra_slow_test = intcon(0); -- - // Generate the initial go-slow test. It's either ALWAYS (return a - // Node for 1) or NEVER (return a NULL) or perhaps (in the reflective - // case) a computed value derived from the layout_helper. -@@ -2761,16 +2914,12 @@ - const TypeOopPtr* oop_type = tklass->as_instance_type(); - - // Now generate allocation code -- Node *eden_top_adr; -- Node *eden_end_adr; -- set_eden_pointers(eden_top_adr, eden_end_adr); -- - AllocateNode* alloc - = new (C, AllocateNode::ParmLimit) - AllocateNode(C, AllocateNode::alloc_type(), - control(), memory(Compile::AliasIdxRaw), i_o(), - size, klass_node, -- initial_slow_test, eden_top_adr, eden_end_adr); -+ initial_slow_test); - - return set_output_for_allocation(alloc, oop_type, raw_mem_only); - } -@@ -2832,10 +2981,11 @@ - int round_mask = MinObjAlignmentInBytes - 1; - Node* header_size = NULL; - int header_size_min = arrayOopDesc::base_offset_in_bytes(T_BYTE); -- // (T_BYTE has the smallest alignment restriction...) -+ // (T_BYTE has the weakest alignment and size restrictions...) - if (layout_is_con) { - int hsize = Klass::layout_helper_header_size(layout_con); - int eshift = Klass::layout_helper_log2_element_size(layout_con); -+ BasicType etype = Klass::layout_helper_element_type(layout_con); - if ((round_mask & ~right_n_bits(eshift)) == 0) - round_mask = 0; // strength-reduce it if it goes away completely - assert((hsize & right_n_bits(eshift)) == 0, "hsize is pre-rounded"); -@@ -2866,6 +3016,17 @@ - // Transition to native address size for all offset calculations: - Node* lengthx = ConvI2X(length); - Node* headerx = ConvI2X(header_size); -+#ifdef _LP64 -+ { const TypeLong* tllen = _gvn.find_long_type(lengthx); -+ if (tllen != NULL && tllen->_lo < 0) { -+ // Add a manual constraint to a positive range. Cf. array_element_address. -+ jlong size_max = arrayOopDesc::max_array_length(T_BYTE); -+ if (size_max > tllen->_hi) size_max = tllen->_hi; -+ const TypeLong* tlcon = TypeLong::make(CONST64(0), size_max, Type::WidenMin); -+ lengthx = _gvn.transform( new (C, 2) ConvI2LNode(length, tlcon)); -+ } -+ } -+#endif - - // Combine header size (plus rounding) and body size. Then round down. - // This computation cannot overflow, because it is used only in two -@@ -2886,56 +3047,43 @@ - (*return_size_val) = size; - } - -- const TypeInt* length_type = _gvn.type(length)->isa_int(); -- const TypeInt* pos_length_type = NULL; -- if (length_type != NULL) { -- pos_length_type = length_type->join(TypeInt::POS)->isa_int(); -- if (pos_length_type == NULL || pos_length_type->empty()) { -- // Optimize only if length is provably non-negative. -- length_type = NULL; -- pos_length_type = NULL; -- } -- } -- -- // Cast to correct type. Note that the klass_node may be constant or not, -- // and in the latter case the actual array type will be inexact also. -- // (This happens via a non-constant argument to inline_native_newArray.) -- // In any case, the value of klass_node provides the desired array type. -- const TypeOopPtr* ary_type = _gvn.type(klass_node)->is_klassptr()->as_instance_type(); -- if (ary_type->isa_aryptr() && pos_length_type != NULL) { -- // Try to get a better type than POS for the size -- ary_type = ary_type->is_aryptr()->cast_to_size(pos_length_type); -- } -- - // Now generate allocation code -- Node *eden_top_adr; -- Node *eden_end_adr; -- set_eden_pointers(eden_top_adr, eden_end_adr); -- - // Create the AllocateArrayNode and its result projections - AllocateArrayNode* alloc - = new (C, AllocateArrayNode::ParmLimit) - AllocateArrayNode(C, AllocateArrayNode::alloc_type(), - control(), memory(Compile::AliasIdxRaw), i_o(), - size, klass_node, -- initial_slow_test, eden_top_adr, eden_end_adr, -+ initial_slow_test, - length); - -+ // Cast to correct type. Note that the klass_node may be constant or not, -+ // and in the latter case the actual array type will be inexact also. -+ // (This happens via a non-constant argument to inline_native_newArray.) -+ // In any case, the value of klass_node provides the desired array type. -+ const TypeInt* length_type = _gvn.find_int_type(length); -+ const TypeInt* narrow_length_type = NULL; -+ const TypeOopPtr* ary_type = _gvn.type(klass_node)->is_klassptr()->as_instance_type(); -+ if (ary_type->isa_aryptr() && length_type != NULL) { -+ // Try to get a better type than POS for the size -+ ary_type = ary_type->is_aryptr()->cast_to_size(length_type); -+ narrow_length_type = ary_type->is_aryptr()->size(); -+ if (narrow_length_type == length_type) -+ narrow_length_type = NULL; -+ } -+ - Node* javaoop = set_output_for_allocation(alloc, ary_type, raw_mem_only); - -- /* -- Not yet. We don't know what to do when the cast tops out. - // Cast length on remaining path to be positive: -- if (pos_length_type != NULL && -- pos_length_type != length_type && -- map()->find_edge(length) >= 0) { -- Node* ccast = new (C, 2) CastIINode(length, pos_length_type); -+ if (narrow_length_type != NULL) { -+ Node* ccast = new (C, 2) CastIINode(length, narrow_length_type); - ccast->set_req(0, control()); - _gvn.set_type_bottom(ccast); - record_for_igvn(ccast); -+ if (map()->find_edge(length) >= 0) { - replace_in_map(length, ccast); - } -- */ -+ } - - return javaoop; - } -@@ -2970,3 +3118,29 @@ - if (base == NULL) return NULL; - return Ideal_allocation(base, phase); - } -+ -+// Trace Initialize <- Proj[Parm] <- Allocate -+AllocateNode* InitializeNode::allocation() { -+ Node* rawoop = in(InitializeNode::RawAddress); -+ if (rawoop->is_Proj()) { -+ Node* alloc = rawoop->in(0); -+ if (alloc->is_Allocate()) { -+ return alloc->as_Allocate(); -+ } -+ } -+ return NULL; -+} -+ -+// Trace Allocate -> Proj[Parm] -> Initialize -+InitializeNode* AllocateNode::initialization() { -+ ProjNode* rawoop = proj_out(AllocateNode::RawAddress); -+ if (rawoop == NULL) return NULL; -+ for (DUIterator_Fast imax, i = rawoop->fast_outs(imax); i < imax; i++) { -+ Node* init = rawoop->fast_out(i); -+ if (init->is_Initialize()) { -+ assert(init->as_Initialize()->allocation() == this, "2-way link"); -+ return init->as_Initialize(); -+ } -+ } -+ return NULL; -+} -diff -ruNb openjdk6/hotspot/src/share/vm/opto/graphKit.hpp openjdk/hotspot/src/share/vm/opto/graphKit.hpp ---- openjdk6/hotspot/src/share/vm/opto/graphKit.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/graphKit.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)graphKit.hpp 1.56 07/05/17 15:58:52 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -426,6 +423,51 @@ - int adr_idx, - bool require_atomic_access = false); - -+ -+ // All in one pre-barrier, store, post_barrier -+ // Insert a write-barrier'd store. This is to let generational GC -+ // work; we have to flag all oop-stores before the next GC point. -+ // -+ // It comes in 3 flavors of store to an object, array, or unknown. -+ // We use precise card marks for arrays to avoid scanning the entire -+ // array. We use imprecise for object. We use precise for unknown -+ // since we don't know if we have an array or and object or even -+ // where the object starts. -+ // -+ // If val==NULL, it is taken to be a completely unknown value. QQQ -+ -+ Node* store_oop_to_object(Node* ctl, -+ Node* obj, // containing obj -+ Node* adr, // actual adress to store val at -+ const TypePtr* adr_type, -+ Node* val, -+ const Type* val_type, -+ BasicType bt); -+ -+ Node* store_oop_to_array(Node* ctl, -+ Node* obj, // containing obj -+ Node* adr, // actual adress to store val at -+ const TypePtr* adr_type, -+ Node* val, -+ const Type* val_type, -+ BasicType bt); -+ -+ // Could be an array or object we don't know at compile time (unsafe ref.) -+ Node* store_oop_to_unknown(Node* ctl, -+ Node* obj, // containing obj -+ Node* adr, // actual adress to store val at -+ const TypePtr* adr_type, -+ Node* val, -+ const Type* val_type, -+ BasicType bt); -+ -+ // For the few case where the barriers need special help -+ void pre_barrier(Node* ctl, Node* obj, Node* adr, uint adr_idx, -+ Node* val, const Type* val_type, BasicType bt); -+ -+ void post_barrier(Node* ctl, Node* store, Node* obj, Node* adr, uint adr_idx, -+ Node* val, BasicType bt, bool use_precise); -+ - // Return addressing for an array element. - Node* array_element_address(Node* ary, Node* idx, BasicType elembt, - // Optional constraint on the array size: -@@ -505,15 +547,15 @@ - // Optional must_throw is the same as with add_safepoint_edges. - void uncommon_trap(int trap_request, - ciKlass* klass = NULL, const char* reason_string = NULL, -- bool must_throw = false); -+ bool must_throw = false, bool keep_exact_action = false); - - // Shorthand, to avoid saying "Deoptimization::" so many times. - void uncommon_trap(Deoptimization::DeoptReason reason, - Deoptimization::DeoptAction action, - ciKlass* klass = NULL, const char* reason_string = NULL, -- bool must_throw = false) { -+ bool must_throw = false, bool keep_exact_action = false) { - uncommon_trap(Deoptimization::make_trap_request(reason, action), -- klass, reason_string, must_throw); -+ klass, reason_string, must_throw, keep_exact_action); - } - - // Report if there were too many traps at the current method and bci. -@@ -528,14 +570,16 @@ - return C->too_many_recompiles(method(), bci(), reason); - } - -- // Insert a write-barrier'd store. This is to let generational GC -- // work; we have to flag all oop-stores before the next GC point. -- // The obj_type value is one of T_OBJECT, T_ARRAY, or T_CONFLICT, -- // meaning obj is an instance, an array, or either (statically unknown). -- // If val==NULL, it is taken to be a completely unknown value. -- void store_barrier(Node *store, BasicType obj_type, -- // dest object, addr within obj, and stored value: -- Node* obj, Node* adr, Node* val); -+ // vanilla/CMS post barrier -+ void write_barrier_post(Node *store, Node* obj, Node* adr, Node* val, bool use_precise); -+ -+ // Returns the object (if any) which was created the moment before. -+ Node* just_allocated_object(Node* current_control); -+ -+ static bool use_ReduceInitialCardMarks() { -+ return (ReduceInitialCardMarks -+ && Universe::heap()->can_elide_tlab_store_barriers()); -+ } - - // Helper function to round double arguments before a call - void round_double_arguments(ciMethod* dest_method); -@@ -613,7 +657,6 @@ - Node* *casted_receiver); - - // implementation of object creation -- void set_eden_pointers(Node * &eden_top_adr, Node * &eden_end_adr); - Node* set_output_for_allocation(AllocateNode* alloc, - const TypeOopPtr* oop_type, - bool raw_mem_only); -@@ -675,4 +718,3 @@ - BuildCutout(GraphKit* kit, Node* p, float prob, float cnt = COUNT_UNKNOWN); - ~BuildCutout(); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/idealGraphPrinter.cpp openjdk/hotspot/src/share/vm/opto/idealGraphPrinter.cpp ---- openjdk6/hotspot/src/share/vm/opto/idealGraphPrinter.cpp 1970-01-01 01:00:00.000000000 +0100 -+++ openjdk/hotspot/src/share/vm/opto/idealGraphPrinter.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -0,0 +1,1919 @@ -+/* -+ * Copyright 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, -+ * CA 95054 USA or visit www.sun.com if you need additional information or -+ * have any questions. -+ * -+ */ -+ -+#include "incls/_precompiled.incl" -+#include "incls/_idealGraphPrinter.cpp.incl" -+ -+#ifndef PRODUCT -+ -+// Constants -+// Keep consistent with Java constants -+const char *IdealGraphPrinter::INDENT = " "; -+const char *IdealGraphPrinter::TOP_ELEMENT = "graphDocument"; -+const char *IdealGraphPrinter::GROUP_ELEMENT = "group"; -+const char *IdealGraphPrinter::GRAPH_ELEMENT = "graph"; -+const char *IdealGraphPrinter::PROPERTIES_ELEMENT = "properties"; -+const char *IdealGraphPrinter::EDGES_ELEMENT = "edges"; -+const char *IdealGraphPrinter::PROPERTY_ELEMENT = "p"; -+const char *IdealGraphPrinter::EDGE_ELEMENT = "edge"; -+const char *IdealGraphPrinter::NODE_ELEMENT = "node"; -+const char *IdealGraphPrinter::NODES_ELEMENT = "nodes"; -+const char *IdealGraphPrinter::REMOVE_EDGE_ELEMENT = "removeEdge"; -+const char *IdealGraphPrinter::REMOVE_NODE_ELEMENT = "removeNode"; -+const char *IdealGraphPrinter::METHOD_NAME_PROPERTY = "name"; -+const char *IdealGraphPrinter::METHOD_IS_PUBLIC_PROPERTY = "public"; -+const char *IdealGraphPrinter::METHOD_IS_STATIC_PROPERTY = "static"; -+const char *IdealGraphPrinter::TRUE_VALUE = "true"; -+const char *IdealGraphPrinter::NODE_NAME_PROPERTY = "name"; -+const char *IdealGraphPrinter::EDGE_NAME_PROPERTY = "name"; -+const char *IdealGraphPrinter::NODE_ID_PROPERTY = "id"; -+const char *IdealGraphPrinter::FROM_PROPERTY = "from"; -+const char *IdealGraphPrinter::TO_PROPERTY = "to"; -+const char *IdealGraphPrinter::PROPERTY_NAME_PROPERTY = "name"; -+const char *IdealGraphPrinter::GRAPH_NAME_PROPERTY = "name"; -+const char *IdealGraphPrinter::INDEX_PROPERTY = "index"; -+const char *IdealGraphPrinter::METHOD_ELEMENT = "method"; -+const char *IdealGraphPrinter::INLINE_ELEMENT = "inline"; -+const char *IdealGraphPrinter::BYTECODES_ELEMENT = "bytecodes"; -+const char *IdealGraphPrinter::METHOD_BCI_PROPERTY = "bci"; -+const char *IdealGraphPrinter::METHOD_SHORT_NAME_PROPERTY = "shortName"; -+const char *IdealGraphPrinter::CONTROL_FLOW_ELEMENT = "controlFlow"; -+const char *IdealGraphPrinter::BLOCK_NAME_PROPERTY = "name"; -+const char *IdealGraphPrinter::BLOCK_DOMINATOR_PROPERTY = "dom"; -+const char *IdealGraphPrinter::BLOCK_ELEMENT = "block"; -+const char *IdealGraphPrinter::SUCCESSORS_ELEMENT = "successors"; -+const char *IdealGraphPrinter::SUCCESSOR_ELEMENT = "successor"; -+const char *IdealGraphPrinter::ASSEMBLY_ELEMENT = "assembly"; -+ -+int IdealGraphPrinter::_file_count = 0; -+ -+IdealGraphPrinter *IdealGraphPrinter::printer() { -+ if (PrintIdealGraphLevel == 0) return NULL; -+ -+ JavaThread *thread = JavaThread::current(); -+ if (!thread->is_Compiler_thread()) return NULL; -+ -+ CompilerThread *compiler_thread = (CompilerThread *)thread; -+ if (compiler_thread->ideal_graph_printer() == NULL) { -+ IdealGraphPrinter *printer = new IdealGraphPrinter(); -+ compiler_thread->set_ideal_graph_printer(printer); -+ } -+ -+ return compiler_thread->ideal_graph_printer(); -+} -+ -+void IdealGraphPrinter::clean_up() { -+ JavaThread *p; -+ for (p = Threads::first(); p; p = p->next()) { -+ if (p->is_Compiler_thread()) { -+ CompilerThread *c = (CompilerThread *)p; -+ IdealGraphPrinter *printer = c->ideal_graph_printer(); -+ if (printer) { -+ delete printer; -+ } -+ c->set_ideal_graph_printer(NULL); -+ } -+ } -+} -+ -+// Constructor, either file or network output -+IdealGraphPrinter::IdealGraphPrinter() { -+ -+ _traverse_outs = false; -+ _should_send_method = true; -+ _output = NULL; -+ buffer[0] = 0; -+ _depth = 0; -+ _current_method = NULL; -+ assert(!_current_method, "current method must be initialized to NULL"); -+ _arena = new Arena(); -+ -+ _stream = new (ResourceObj::C_HEAP) networkStream(); -+ -+ if (PrintIdealGraphFile != NULL) { -+ ThreadCritical tc; -+ // User wants all output to go to files -+ if (_file_count != 0) { -+ ResourceMark rm; -+ stringStream st; -+ const char* dot = strrchr(PrintIdealGraphFile, '.'); -+ if (dot) { -+ st.write(PrintIdealGraphFile, dot - PrintIdealGraphFile); -+ st.print("%d%s", _file_count, dot); -+ } else { -+ st.print("%s%d", PrintIdealGraphFile, _file_count); -+ } -+ _output = new (ResourceObj::C_HEAP) fileStream(st.as_string()); -+ } else { -+ _output = new (ResourceObj::C_HEAP) fileStream(PrintIdealGraphFile); -+ } -+ _file_count++; -+ } else { -+ // Try to connect to visualizer -+ if (_stream->connect(PrintIdealGraphAddress, PrintIdealGraphPort)) { -+ char c = 0; -+ _stream->read(&c, 1); -+ if (c != 'y') { -+ tty->print_cr("Client available, but does not want to receive data!"); -+ _stream->close(); -+ delete _stream; -+ _stream = NULL; -+ return; -+ } -+ _output = _stream; -+ } 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. -+ fatal2("Couldn't connect to visualizer at %s:%d", PrintIdealGraphAddress, PrintIdealGraphPort); -+ } -+ } -+ -+ start_element(TOP_ELEMENT); -+} -+ -+// Destructor, close file or network stream -+IdealGraphPrinter::~IdealGraphPrinter() { -+ -+ end_element(TOP_ELEMENT); -+ -+ if (_stream) { -+ delete _stream; -+ if (_stream == _output) { -+ _output = NULL; -+ } -+ _stream = NULL; -+ } -+ -+ if (_output) { -+ delete _output; -+ _output = NULL; -+ } -+} -+ -+void IdealGraphPrinter::print_ifg(PhaseIFG* ifg) { -+ -+ // Code to print an interference graph to tty, currently not used -+ -+ /* -+ if (!_current_method) return; -+ // Remove neighbor colors -+ -+ for (uint i = 0; i < ifg._maxlrg; i++) { -+ -+ IndexSet *s = ifg.neighbors(i); -+ IndexSetIterator elements(s); -+ uint neighbor; -+ while ((neighbor = elements.next()) != 0) { -+ tty->print_cr("Edge between %d and %d\n", i, neighbor); -+ } -+ } -+ -+ -+ for (uint i = 0; i < ifg._maxlrg; i++) { -+ LRG &l = ifg.lrgs(i); -+ if (l._def) { -+ OptoReg::Name name = l.reg(); -+ tty->print("OptoReg::dump: "); -+ OptoReg::dump(name); -+ tty->print_cr(""); -+ tty->print_cr("name=%d\n", name); -+ if (name) { -+ if (OptoReg::is_stack(name)) { -+ tty->print_cr("Stack number %d\n", OptoReg::reg2stack(name)); -+ -+ } else if (!OptoReg::is_valid(name)) { -+ tty->print_cr("BAD!!!"); -+ } else { -+ -+ if (OptoReg::is_reg(name)) { -+ tty->print_cr(OptoReg::regname(name)); -+ } else { -+ int x = 0; -+ } -+ } -+ int x = 0; -+ } -+ -+ if (l._def == NodeSentinel) { -+ tty->print("multiple mapping from %d: ", i); -+ for (int j=0; jlength(); j++) { -+ tty->print("%d ", l._defs->at(j)->_idx); -+ } -+ tty->print_cr(""); -+ } else { -+ tty->print_cr("mapping between %d and %d\n", i, l._def->_idx); -+ } -+ } -+ }*/ -+} -+ -+void IdealGraphPrinter::print_method(ciMethod *method, int bci, InlineTree *tree) { -+ -+ Properties properties; -+ stringStream str; -+ method->print_name(&str); -+ -+ stringStream shortStr; -+ method->print_short_name(&shortStr); -+ -+ -+ properties.add(new Property(METHOD_NAME_PROPERTY, str.as_string())); -+ properties.add(new Property(METHOD_SHORT_NAME_PROPERTY, shortStr.as_string())); -+ properties.add(new Property(METHOD_BCI_PROPERTY, bci)); -+ start_element(METHOD_ELEMENT, &properties); -+ -+ start_element(BYTECODES_ELEMENT); -+ output()->print_cr("print_codes_on(output()); -+ output()->print_cr("]]>"); -+ end_element(BYTECODES_ELEMENT); -+ -+ start_element(INLINE_ELEMENT); -+ if (tree != NULL) { -+ GrowableArray subtrees = tree->subtrees(); -+ for (int i = 0; i < subtrees.length(); i++) { -+ print_inline_tree(subtrees.at(i)); -+ } -+ } -+ end_element(INLINE_ELEMENT); -+ -+ end_element(METHOD_ELEMENT); -+ output()->flush(); -+} -+ -+void IdealGraphPrinter::print_inline_tree(InlineTree *tree) { -+ -+ if (tree == NULL) return; -+ -+ ciMethod *method = tree->method(); -+ print_method(tree->method(), tree->caller_bci(), tree); -+ -+} -+ -+void IdealGraphPrinter::clear_nodes() { -+ // for (int i = 0; i < _nodes.length(); i++) { -+ // _nodes.at(i)->clear_node(); -+ // } -+} -+ -+void IdealGraphPrinter::print_inlining(Compile* compile) { -+ -+ // Print inline tree -+ if (_should_send_method) { -+ InlineTree *inlineTree = compile->ilt(); -+ if (inlineTree != NULL) { -+ print_inline_tree(inlineTree); -+ } else { -+ // print this method only -+ } -+ } -+} -+ -+// Has to be called whenever a method is compiled -+void IdealGraphPrinter::begin_method(Compile* compile) { -+ -+ ciMethod *method = compile->method(); -+ assert(_output, "output stream must exist!"); -+ assert(method, "null methods are not allowed!"); -+ assert(!_current_method, "current method must be null!"); -+ -+ _arena->destruct_contents(); -+ -+ start_element(GROUP_ELEMENT); -+ -+ // Print properties -+ Properties properties; -+ -+ // Add method name -+ stringStream strStream; -+ method->print_name(&strStream); -+ properties.add(new Property(METHOD_NAME_PROPERTY, strStream.as_string())); -+ -+ if (method->flags().is_public()) { -+ properties.add(new Property(METHOD_IS_PUBLIC_PROPERTY, TRUE_VALUE)); -+ } -+ -+ if (method->flags().is_static()) { -+ properties.add(new Property(METHOD_IS_STATIC_PROPERTY, TRUE_VALUE)); -+ } -+ -+ properties.print(this); -+ -+ if (_stream) { -+ char answer = 0; -+ _stream->flush(); -+ int result = _stream->read(&answer, 1); -+ _should_send_method = (answer == 'y'); -+ } -+ -+ this->_nodes = GrowableArray(_arena, 2, 0, NULL); -+ this->_edges = GrowableArray< EdgeDescription * >(_arena, 2, 0, NULL); -+ -+ -+ this->_current_method = method; -+ -+ -+ -+ _output->flush(); -+} -+ -+// Has to be called whenever a method has finished compilation -+void IdealGraphPrinter::end_method() { -+ -+// if (finish && !in_method) return; -+ -+ nmethod* method = (nmethod*)this->_current_method->code(); -+ -+ start_element(ASSEMBLY_ELEMENT); -+ // Disassembler::decode(method, _output); -+ end_element(ASSEMBLY_ELEMENT); -+ -+ -+ end_element(GROUP_ELEMENT); -+ _current_method = NULL; -+ _output->flush(); -+ for (int i = 0; i < _nodes.length(); i++) { -+ NodeDescription *desc = _nodes.at(i); -+ if (desc) { -+ delete desc; -+ _nodes.at_put(i, NULL); -+ } -+ } -+ this->_nodes.clear(); -+ -+ -+ for (int i = 0; i < _edges.length(); i++) { -+ // for (int j=0; j<_edges.at(i)->length(); j++) { -+ EdgeDescription *conn = _edges.at(i); -+ conn->print(this); -+ if (conn) { -+ delete conn; -+ _edges.at_put(i, NULL); -+ } -+ //} -+ //_edges.at(i)->clear(); -+ //delete _edges.at(i); -+ //_edges.at_put(i, NULL); -+ } -+ this->_edges.clear(); -+ -+// in_method = false; -+} -+ -+// Outputs an XML start element -+void IdealGraphPrinter::start_element(const char *s, Properties *properties /* = NULL */, bool print_indent /* = false */, bool print_return /* = true */) { -+ -+ start_element_helper(s, properties, false, print_indent, print_return); -+ _depth++; -+ -+} -+ -+// Outputs an XML start element without body -+void IdealGraphPrinter::simple_element(const char *s, Properties *properties /* = NULL */, bool print_indent /* = false */) { -+ start_element_helper(s, properties, true, print_indent, true); -+} -+ -+// Outputs an XML start element. If outputEnd is true, the element has no body. -+void IdealGraphPrinter::start_element_helper(const char *s, Properties *properties, bool outputEnd, bool print_indent /* = false */, bool print_return /* = true */) { -+ -+ assert(_output, "output stream must exist!"); -+ -+ if (print_indent) this->print_indent(); -+ _output->print("<"); -+ _output->print(s); -+ if (properties) properties->print_as_attributes(this); -+ -+ if (outputEnd) { -+ _output->print("/"); -+ } -+ -+ _output->print(">"); -+ if (print_return) _output->print_cr(""); -+ -+} -+ -+// Print indent -+void IdealGraphPrinter::print_indent() { -+ for (int i = 0; i < _depth; i++) { -+ _output->print(INDENT); -+ } -+} -+ -+// Outputs an XML end element -+void IdealGraphPrinter::end_element(const char *s, bool print_indent /* = true */, bool print_return /* = true */) { -+ -+ assert(_output, "output stream must exist!"); -+ -+ _depth--; -+ -+ if (print_indent) this->print_indent(); -+ _output->print("print(s); -+ _output->print(">"); -+ if (print_return) _output->print_cr(""); -+ -+} -+ -+bool IdealGraphPrinter::traverse_outs() { -+ return _traverse_outs; -+} -+ -+void IdealGraphPrinter::set_traverse_outs(bool b) { -+ _traverse_outs = b; -+} -+ -+void IdealGraphPrinter::walk(Node *start) { -+ -+ -+ VectorSet visited(Thread::current()->resource_area()); -+ GrowableArray nodeStack(Thread::current()->resource_area(), 0, 0, NULL); -+ nodeStack.push(start); -+ visited.test_set(start->_idx); -+ while(nodeStack.length() > 0) { -+ -+ Node *n = nodeStack.pop(); -+ IdealGraphPrinter::pre_node(n, this); -+ -+ if (_traverse_outs) { -+ for (DUIterator i = n->outs(); n->has_out(i); i++) { -+ Node* p = n->out(i); -+ if (!visited.test_set(p->_idx)) { -+ nodeStack.push(p); -+ } -+ } -+ } -+ -+ for ( uint i = 0; i < n->len(); i++ ) { -+ if ( n->in(i) ) { -+ if (!visited.test_set(n->in(i)->_idx)) { -+ nodeStack.push(n->in(i)); -+ } -+ } -+ } -+ } -+} -+ -+void IdealGraphPrinter::compress(int index, GrowableArray* blocks) { -+ Block *block = blocks->adr_at(index); -+ -+ int ancestor = block->ancestor(); -+ assert(ancestor != -1, ""); -+ -+ Block *ancestor_block = blocks->adr_at(ancestor); -+ if (ancestor_block->ancestor() != -1) { -+ compress(ancestor, blocks); -+ -+ int label = block->label(); -+ Block *label_block = blocks->adr_at(label); -+ -+ int ancestor_label = ancestor_block->label(); -+ Block *ancestor_label_block = blocks->adr_at(label); -+ if (ancestor_label_block->semi() < label_block->semi()) { -+ block->set_label(ancestor_label); -+ } -+ -+ block->set_ancestor(ancestor_block->ancestor()); -+ } -+} -+ -+int IdealGraphPrinter::eval(int index, GrowableArray* blocks) { -+ Block *block = blocks->adr_at(index); -+ if (block->ancestor() == -1) { -+ return index; -+ } else { -+ compress(index, blocks); -+ return block->label(); -+ } -+} -+ -+void IdealGraphPrinter::link(int index1, int index2, GrowableArray* blocks) { -+ Block *block2 = blocks->adr_at(index2); -+ block2->set_ancestor(index1); -+} -+ -+void IdealGraphPrinter::build_dominators(GrowableArray* blocks) { -+ -+ if (blocks->length() == 0) return; -+ -+ GrowableArray stack; -+ stack.append(0); -+ -+ GrowableArray array; -+ -+ assert(blocks->length() > 0, ""); -+ blocks->adr_at(0)->set_dominator(0); -+ -+ int n = 0; -+ while(!stack.is_empty()) { -+ int index = stack.pop(); -+ Block *block = blocks->adr_at(index); -+ block->set_semi(n); -+ array.append(block); -+ n = n + 1; -+ for (int i = 0; i < block->succs()->length(); i++) { -+ int succ_index = block->succs()->at(i); -+ Block *succ = blocks->adr_at(succ_index); -+ if (succ->semi() == -1) { -+ succ->set_parent(index); -+ stack.push(succ_index); -+ } -+ succ->add_pred(index); -+ } -+ } -+ -+ for (int i=n-1; i>0; i--) { -+ Block *block = array.at(i); -+ int block_index = block->index(); -+ for (int j=0; jpred()->length(); j++) { -+ int pred_index = block->pred()->at(j); -+ int cur_index = eval(pred_index, blocks); -+ -+ Block *cur_block = blocks->adr_at(cur_index); -+ if (cur_block->semi() < block->semi()) { -+ block->set_semi(cur_block->semi()); -+ } -+ } -+ -+ int semi_index = block->semi(); -+ Block *semi_block = array.at(semi_index); -+ semi_block->add_to_bucket(block_index); -+ -+ link(block->parent(), block_index, blocks); -+ Block *parent_block = blocks->adr_at(block->parent()); -+ -+ for (int j=0; jbucket()->length(); j++) { -+ int cur_index = parent_block->bucket()->at(j); -+ int new_index = eval(cur_index, blocks); -+ Block *cur_block = blocks->adr_at(cur_index); -+ Block *new_block = blocks->adr_at(new_index); -+ int dom = block->parent(); -+ -+ if (new_block->semi() < cur_block->semi()) { -+ dom = new_index; -+ } -+ -+ cur_block->set_dominator(dom); -+ } -+ -+ parent_block->clear_bucket(); -+ } -+ -+ for (int i=1; i < n; i++) { -+ -+ Block *block = array.at(i); -+ int block_index = block->index(); -+ -+ int semi_index = block->semi(); -+ Block *semi_block = array.at(semi_index); -+ -+ if (block->dominator() != semi_block->index()) { -+ int new_dom = blocks->adr_at(block->dominator())->dominator(); -+ block->set_dominator(new_dom); -+ } -+ } -+ -+ for (int i = 0; i < blocks->length(); i++) { -+ if (blocks->adr_at(i)->dominator() == -1) { -+ blocks->adr_at(i)->set_dominator(0); -+ } -+ } -+ -+ // Build dominates array -+ for (int i=1; i < blocks->length(); i++) { -+ Block *block = blocks->adr_at(i); -+ int dominator = block->dominator(); -+ Block *dom_block = blocks->adr_at(dominator); -+ dom_block->add_dominates(i); -+ dom_block->add_child(i); -+ -+ while(dominator != 0) { -+ dominator = dom_block->dominator(); -+ dom_block = blocks->adr_at(dominator); -+ dom_block->add_child(i); -+ } -+ } -+} -+ -+void IdealGraphPrinter::build_common_dominator(int **common_dominator, int index, GrowableArray* blocks) { -+ -+ common_dominator[index][index] = index; -+ Block *block = blocks->adr_at(index); -+ for (int i = 0; i < block->dominates()->length(); i++) { -+ Block *dominated = blocks->adr_at(block->dominates()->at(i)); -+ -+ for (int j=0; jchildren()->length(); j++) { -+ Block *child = blocks->adr_at(dominated->children()->at(j)); -+ common_dominator[index][child->index()] = common_dominator[child->index()][index] = index; -+ -+ for (int k=0; kadr_at(block->dominates()->at(k)); -+ common_dominator[child->index()][other_dominated->index()] = common_dominator[other_dominated->index()][child->index()] = index; -+ -+ for (int l=0 ; lchildren()->length(); l++) { -+ Block *other_child = blocks->adr_at(other_dominated->children()->at(l)); -+ common_dominator[child->index()][other_child->index()] = common_dominator[other_child->index()][child->index()] = index; -+ } -+ } -+ } -+ -+ build_common_dominator(common_dominator, dominated->index(), blocks); -+ } -+} -+ -+void IdealGraphPrinter::schedule_latest(int **common_dominator, GrowableArray* blocks) { -+ -+ int queue_size = _nodes.length() + 1; -+ NodeDescription **queue = NEW_RESOURCE_ARRAY(NodeDescription *, queue_size); -+ int queue_start = 0; -+ int queue_end = 0; -+ Arena *a = new Arena(); -+ VectorSet on_queue(a); -+ -+ for (int i = 0; i < _nodes.length(); i++) { -+ NodeDescription *desc = _nodes.at(i); -+ if (desc) { -+ desc->init_succs(); -+ } -+ } -+ -+ for (int i = 0; i < _nodes.length(); i++) { -+ NodeDescription *desc = _nodes.at(i); -+ if (desc) { -+ for (uint j=0; jnode()->len(); j++) { -+ Node *n = desc->node()->in(j); -+ if (n) { -+ NodeDescription *other_desc = _nodes.at(n->_idx); -+ other_desc->add_succ(desc); -+ } -+ } -+ } -+ } -+ -+ for (int i = 0; i < _nodes.length(); i++) { -+ NodeDescription *desc = _nodes.at(i); -+ if (desc && desc->block_index() == -1) { -+ -+ // Put Phi into same block as region -+ if (desc->node()->is_Phi() && desc->node()->in(0) && _nodes.at(desc->node()->in(0)->_idx)->block_index() != -1) { -+ int index = _nodes.at(desc->node()->in(0)->_idx)->block_index(); -+ desc->set_block_index(index); -+ blocks->adr_at(index)->add_node(desc); -+ -+ // Put Projections to same block as parent -+ } else if (desc->node()->is_block_proj() && _nodes.at(desc->node()->is_block_proj()->_idx)->block_index() != -1) { -+ int index = _nodes.at(desc->node()->is_block_proj()->_idx)->block_index(); -+ desc->set_block_index(index); -+ blocks->adr_at(index)->add_node(desc); -+ } else { -+ queue[queue_end] = desc; -+ queue_end++; -+ on_queue.set(desc->node()->_idx); -+ } -+ } -+ } -+ -+ -+ int z = 0; -+ while(queue_start != queue_end && z < 10000) { -+ -+ NodeDescription *desc = queue[queue_start]; -+ queue_start = (queue_start + 1) % queue_size; -+ on_queue >>= desc->node()->_idx; -+ -+ Node* node = desc->node(); -+ -+ if (desc->succs()->length() == 0) { -+ int x = 0; -+ } -+ -+ int block_index = -1; -+ if (desc->succs()->length() != 0) { -+ for (int i = 0; i < desc->succs()->length(); i++) { -+ NodeDescription *cur_desc = desc->succs()->at(i); -+ if (cur_desc != desc) { -+ if (cur_desc->succs()->length() == 0) { -+ -+ // Ignore nodes with 0 successors -+ -+ } else if (cur_desc->block_index() == -1) { -+ -+ // Let this node schedule first -+ block_index = -1; -+ break; -+ -+ } else if (cur_desc->node()->is_Phi()){ -+ -+ // Special treatment for Phi functions -+ PhiNode *phi = cur_desc->node()->as_Phi(); -+ assert(phi->in(0) && phi->in(0)->is_Region(), "Must have region node in first input"); -+ RegionNode *region = phi->in(0)->as_Region(); -+ -+ for (uint j=1; jlen(); j++) { -+ Node *cur_phi_input = phi->in(j); -+ if (cur_phi_input == desc->node() && region->in(j)) { -+ NodeDescription *cur_region_input = _nodes.at(region->in(j)->_idx); -+ if (cur_region_input->block_index() == -1) { -+ -+ // Let this node schedule first -+ block_index = -1; -+ break; -+ } else { -+ if (block_index == -1) { -+ block_index = cur_region_input->block_index(); -+ } else { -+ block_index = common_dominator[block_index][cur_region_input->block_index()]; -+ } -+ } -+ } -+ } -+ -+ } else { -+ if (block_index == -1) { -+ block_index = cur_desc->block_index(); -+ } else { -+ block_index = common_dominator[block_index][cur_desc->block_index()]; -+ } -+ } -+ } -+ } -+ } -+ -+ if (block_index == -1) { -+ queue[queue_end] = desc; -+ queue_end = (queue_end + 1) % queue_size; -+ on_queue.set(desc->node()->_idx); -+ z++; -+ } else { -+ assert(desc->block_index() == -1, ""); -+ desc->set_block_index(block_index); -+ blocks->adr_at(block_index)->add_node(desc); -+ z = 0; -+ } -+ } -+ -+ for (int i = 0; i < _nodes.length(); i++) { -+ NodeDescription *desc = _nodes.at(i); -+ if (desc && desc->block_index() == -1) { -+ -+ //if (desc->node()->is_Proj() || desc->node()->is_Con()) { -+ Node *parent = desc->node()->in(0); -+ uint cur = 1; -+ while(!parent && cur < desc->node()->len()) { -+ parent = desc->node()->in(cur); -+ cur++; -+ } -+ -+ if (parent && _nodes.at(parent->_idx)->block_index() != -1) { -+ int index = _nodes.at(parent->_idx)->block_index(); -+ desc->set_block_index(index); -+ blocks->adr_at(index)->add_node(desc); -+ } else { -+ desc->set_block_index(0); -+ blocks->adr_at(0)->add_node(desc); -+ //ShouldNotReachHere(); -+ } -+ //} -+ /* -+ if (desc->node()->is_block_proj() && _nodes.at(desc->node()->is_block_proj()->_idx)->block_index() != -1) { -+ int index = _nodes.at(desc->node()->is_block_proj()->_idx)->block_index(); -+ desc->set_block_index(index); -+ blocks->adr_at(index)->add_node(desc); -+ } */ -+ } -+ } -+ -+ for (int i = 0; i < _nodes.length(); i++) { -+ NodeDescription *desc = _nodes.at(i); -+ if (desc) { -+ desc->clear_succs(); -+ } -+ } -+ -+ for (int i = 0; i < _nodes.length(); i++) { -+ NodeDescription *desc = _nodes.at(i); -+ if (desc) { -+ int block_index = desc->block_index(); -+ -+ assert(block_index >= 0 && block_index < blocks->length(), "Block index must be in range"); -+ assert(blocks->adr_at(block_index)->nodes()->contains(desc), "Node must be child of block"); -+ } -+ } -+ a->destruct_contents(); -+} -+ -+void IdealGraphPrinter::build_blocks(Node *root) { -+ -+ Arena *a = new Arena(); -+ Node_Stack stack(a, 100); -+ -+ VectorSet visited(a); -+ stack.push(root, 0); -+ GrowableArray blocks(a, 2, 0, Block(0)); -+ -+ for (int i = 0; i < _nodes.length(); i++) { -+ if (_nodes.at(i)) _nodes.at(i)->set_block_index(-1); -+ } -+ -+ -+ // Order nodes such that node index is equal to idx -+ for (int i = 0; i < _nodes.length(); i++) { -+ -+ if (_nodes.at(i)) { -+ NodeDescription *node = _nodes.at(i); -+ int index = node->node()->_idx; -+ if (index != i) { -+ _nodes.at_grow(index); -+ NodeDescription *tmp = _nodes.at(index); -+ *(_nodes.adr_at(index)) = node; -+ *(_nodes.adr_at(i)) = tmp; -+ i--; -+ } -+ } -+ } -+ -+ for (int i = 0; i < _nodes.length(); i++) { -+ NodeDescription *node = _nodes.at(i); -+ if (node) { -+ assert(node->node()->_idx == (uint)i, ""); -+ } -+ } -+ -+ while(stack.is_nonempty()) { -+ -+ //Node *n = stack.node(); -+ //int index = stack.index(); -+ Node *proj = stack.node();//n->in(index); -+ const Node *parent = proj->is_block_proj(); -+ if (parent == NULL) { -+ parent = proj; -+ } -+ -+ if (!visited.test_set(parent->_idx)) { -+ -+ NodeDescription *end_desc = _nodes.at(parent->_idx); -+ int block_index = blocks.length(); -+ Block block(block_index); -+ blocks.append(block); -+ Block *b = blocks.adr_at(block_index); -+ b->set_start(end_desc); -+ // assert(end_desc->block_index() == -1, ""); -+ end_desc->set_block_index(block_index); -+ b->add_node(end_desc); -+ -+ // Skip any control-pinned middle'in stuff -+ Node *p = proj; -+ NodeDescription *start_desc = NULL; -+ do { -+ proj = p; // Update pointer to last Control -+ if (p->in(0) == NULL) { -+ start_desc = end_desc; -+ break; -+ } -+ p = p->in(0); // Move control forward -+ start_desc = _nodes.at(p->_idx); -+ assert(start_desc, ""); -+ -+ if (start_desc != end_desc && start_desc->block_index() == -1) { -+ assert(start_desc->block_index() == -1, ""); -+ assert(block_index < blocks.length(), ""); -+ start_desc->set_block_index(block_index); -+ b->add_node(start_desc); -+ } -+ } while( !p->is_block_proj() && -+ !p->is_block_start() ); -+ -+ for (uint i = 0; i < start_desc->node()->len(); i++) { -+ -+ Node *pred_node = start_desc->node()->in(i); -+ -+ -+ if (pred_node && pred_node != start_desc->node()) { -+ const Node *cur_parent = pred_node->is_block_proj(); -+ if (cur_parent != NULL) { -+ pred_node = (Node *)cur_parent; -+ } -+ -+ NodeDescription *pred_node_desc = _nodes.at(pred_node->_idx); -+ if (pred_node_desc->block_index() != -1) { -+ blocks.adr_at(pred_node_desc->block_index())->add_succ(block_index); -+ } -+ } -+ } -+ -+ for (DUIterator_Fast dmax, i = end_desc->node()->fast_outs(dmax); i < dmax; i++) { -+ Node* cur_succ = end_desc->node()->fast_out(i); -+ NodeDescription *cur_succ_desc = _nodes.at(cur_succ->_idx); -+ -+ DUIterator_Fast dmax2, i2 = cur_succ->fast_outs(dmax2); -+ if (cur_succ->is_block_proj() && i2 < dmax2 && !cur_succ->is_Root()) { -+ -+ for (; i2fast_out(i2); -+ if (cur_succ2) { -+ cur_succ_desc = _nodes.at(cur_succ2->_idx); -+ if (cur_succ_desc == NULL) { -+ // dead node so skip it -+ continue; -+ } -+ if (cur_succ2 != end_desc->node() && cur_succ_desc->block_index() != -1) { -+ b->add_succ(cur_succ_desc->block_index()); -+ } -+ } -+ } -+ -+ } else { -+ -+ if (cur_succ != end_desc->node() && cur_succ_desc && cur_succ_desc->block_index() != -1) { -+ b->add_succ(cur_succ_desc->block_index()); -+ } -+ } -+ } -+ -+ -+ int num_preds = p->len(); -+ int bottom = -1; -+ if (p->is_Region() || p->is_Phi()) { -+ bottom = 0; -+ } -+ -+ int pushed = 0; -+ for (int i=num_preds - 1; i > bottom; i--) { -+ if (p->in(i) != NULL && p->in(i) != p) { -+ stack.push(p->in(i), 0); -+ pushed++; -+ } -+ } -+ -+ if (pushed == 0 && p->is_Root() && !_matcher) { -+ // Special case when backedges to root are not yet built -+ for (int i = 0; i < _nodes.length(); i++) { -+ if (_nodes.at(i) && _nodes.at(i)->node()->is_SafePoint() && _nodes.at(i)->node()->outcnt() == 0) { -+ stack.push(_nodes.at(i)->node(), 0); -+ } -+ } -+ } -+ -+ } else { -+ stack.pop(); -+ } -+ } -+ -+ build_dominators(&blocks); -+ -+ int **common_dominator = NEW_RESOURCE_ARRAY(int *, blocks.length()); -+ for (int i = 0; i < blocks.length(); i++) { -+ int *cur = NEW_RESOURCE_ARRAY(int, blocks.length()); -+ common_dominator[i] = cur; -+ -+ for (int j=0; jadd_child(blocks.adr_at(i)->index()); -+ } -+ build_common_dominator(common_dominator, 0, &blocks); -+ -+ schedule_latest(common_dominator, &blocks); -+ -+ start_element(CONTROL_FLOW_ELEMENT); -+ -+ for (int i = 0; i < blocks.length(); i++) { -+ Block *block = blocks.adr_at(i); -+ -+ Properties props; -+ props.add(new Property(BLOCK_NAME_PROPERTY, i)); -+ props.add(new Property(BLOCK_DOMINATOR_PROPERTY, block->dominator())); -+ start_element(BLOCK_ELEMENT, &props); -+ -+ if (block->succs()->length() > 0) { -+ start_element(SUCCESSORS_ELEMENT); -+ for (int j=0; jsuccs()->length(); j++) { -+ int cur_index = block->succs()->at(j); -+ if (cur_index != 0 /* start_block has must not have inputs */) { -+ Properties properties; -+ properties.add(new Property(BLOCK_NAME_PROPERTY, cur_index)); -+ simple_element(SUCCESSOR_ELEMENT, &properties); -+ } -+ } -+ end_element(SUCCESSORS_ELEMENT); -+ } -+ -+ start_element(NODES_ELEMENT); -+ -+ for (int j=0; jnodes()->length(); j++) { -+ NodeDescription *n = block->nodes()->at(j); -+ Properties properties; -+ properties.add(new Property(NODE_ID_PROPERTY, n->id())); -+ simple_element(NODE_ELEMENT, &properties); -+ } -+ -+ end_element(NODES_ELEMENT); -+ -+ end_element(BLOCK_ELEMENT); -+ } -+ -+ -+ end_element(CONTROL_FLOW_ELEMENT); -+ -+ a->destruct_contents(); -+} -+ -+void IdealGraphPrinter::print_method(Compile* compile, const char *name, int level, bool clear_nodes) { -+ print(compile, name, (Node *)compile->root(), level, clear_nodes); -+} -+ -+// Print current ideal graph -+void IdealGraphPrinter::print(Compile* compile, const char *name, Node *node, int level, bool clear_nodes) { -+ -+// if (finish && !in_method) return; -+ if (!_current_method || !_should_send_method || level > PrintIdealGraphLevel) return; -+ -+ assert(_current_method, "newMethod has to be called first!"); -+ -+ if (clear_nodes) { -+ int x = 0; -+ } -+ -+ _clear_nodes = clear_nodes; -+ -+ // Warning, unsafe cast? -+ _chaitin = (PhaseChaitin *)compile->regalloc(); -+ _matcher = compile->matcher(); -+ -+ -+ // Update nodes -+ for (int i = 0; i < _nodes.length(); i++) { -+ NodeDescription *desc = _nodes.at(i); -+ if (desc) { -+ desc->set_state(Invalid); -+ } -+ } -+ Node *n = node; -+ walk(n); -+ -+ // Update edges -+ for (int i = 0; i < _edges.length(); i++) { -+ _edges.at(i)->set_state(Invalid); -+ } -+ -+ for (int i = 0; i < _nodes.length(); i++) { -+ NodeDescription *desc = _nodes.at(i); -+ if (desc && desc->state() != Invalid) { -+ -+ int to = desc->id(); -+ uint len = desc->node()->len(); -+ for (uint j=0; jnode()->in(j); -+ -+ if (n) { -+ -+ -+ intptr_t from = (intptr_t)n; -+ -+ // Assert from node is valid -+ /* -+ bool ok = false; -+ for (int k=0; k<_nodes.length(); k++) { -+ NodeDescription *desc = _nodes.at(k); -+ if (desc && desc->id() == from) { -+ assert(desc->state() != Invalid, ""); -+ ok = true; -+ } -+ } -+ assert(ok, "");*/ -+ -+ uint index = j; -+ if (index >= desc->node()->req()) { -+ index = desc->node()->req(); -+ } -+ -+ print_edge(from, to, index); -+ } -+ } -+ } -+ } -+ -+ bool is_different = false; -+ -+ for (int i = 0; i < _nodes.length(); i++) { -+ NodeDescription *desc = _nodes.at(i); -+ if (desc && desc->state() != Valid) { -+ is_different = true; -+ break; -+ } -+ } -+ -+ if (!is_different) { -+ for (int i = 0; i < _edges.length(); i++) { -+ EdgeDescription *conn = _edges.at(i); -+ if (conn && conn->state() != Valid) { -+ is_different = true; -+ break; -+ } -+ } -+ } -+ -+ // No changes -> do not print graph -+ if (!is_different) return; -+ -+ Properties properties; -+ properties.add(new Property(GRAPH_NAME_PROPERTY, (const char *)name)); -+ start_element(GRAPH_ELEMENT, &properties); -+ -+ start_element(NODES_ELEMENT); -+ for (int i = 0; i < _nodes.length(); i++) { -+ NodeDescription *desc = _nodes.at(i); -+ if (desc) { -+ desc->print(this); -+ if (desc->state() == Invalid) { -+ delete desc; -+ _nodes.at_put(i, NULL); -+ } else { -+ desc->set_state(Valid); -+ } -+ } -+ } -+ end_element(NODES_ELEMENT); -+ -+ build_blocks(node); -+ -+ start_element(EDGES_ELEMENT); -+ for (int i = 0; i < _edges.length(); i++) { -+ EdgeDescription *conn = _edges.at(i); -+ -+ // Assert from and to nodes are valid -+ /* -+ if (!conn->state() == Invalid) { -+ bool ok1 = false; -+ bool ok2 = false; -+ for (int j=0; j<_nodes.length(); j++) { -+ NodeDescription *desc = _nodes.at(j); -+ if (desc && desc->id() == conn->from()) { -+ ok1 = true; -+ } -+ -+ if (desc && desc->id() == conn->to()) { -+ ok2 = true; -+ } -+ } -+ -+ assert(ok1, "from node not found!"); -+ assert(ok2, "to node not found!"); -+ }*/ -+ -+ conn->print(this); -+ if (conn->state() == Invalid) { -+ _edges.remove_at(i); -+ delete conn; -+ i--; -+ } -+ } -+ -+ end_element(EDGES_ELEMENT); -+ -+ end_element(GRAPH_ELEMENT); -+ -+ _output->flush(); -+} -+ -+// Print edge -+void IdealGraphPrinter::print_edge(int from, int to, int index) { -+ -+ EdgeDescription *conn = new EdgeDescription(from, to, index); -+ for (int i = 0; i < _edges.length(); i++) { -+ if (_edges.at(i)->equals(conn)) { -+ conn->set_state(Valid); -+ delete _edges.at(i); -+ _edges.at_put(i, conn); -+ return; -+ } -+ } -+ -+ _edges.append(conn); -+} -+ -+extern const char *NodeClassNames[]; -+ -+// Create node description -+IdealGraphPrinter::NodeDescription *IdealGraphPrinter::create_node_description(Node* node) { -+ -+#ifndef PRODUCT -+ node->_in_dump_cnt++; -+ NodeDescription *desc = new NodeDescription(node); -+ desc->properties()->add(new Property(NODE_NAME_PROPERTY, (const char *)node->Name())); -+ -+ const Type *t = node->bottom_type(); -+ desc->properties()->add(new Property("type", (const char *)Type::msg[t->base()])); -+ -+ desc->properties()->add(new Property("idx", node->_idx)); -+#ifdef ASSERT -+ desc->properties()->add(new Property("debug_idx", node->_debug_idx)); -+#endif -+ -+ -+ const jushort flags = node->flags(); -+ if (flags & Node::Flag_is_Copy) { -+ desc->properties()->add(new Property("is_copy", "true")); -+ } -+ if (flags & Node::Flag_is_Call) { -+ desc->properties()->add(new Property("is_call", "true")); -+ } -+ if (flags & Node::Flag_rematerialize) { -+ desc->properties()->add(new Property("rematerialize", "true")); -+ } -+ if (flags & Node::Flag_needs_anti_dependence_check) { -+ desc->properties()->add(new Property("needs_anti_dependence_check", "true")); -+ } -+ if (flags & Node::Flag_is_macro) { -+ desc->properties()->add(new Property("is_macro", "true")); -+ } -+ if (flags & Node::Flag_is_Con) { -+ desc->properties()->add(new Property("is_con", "true")); -+ } -+ if (flags & Node::Flag_is_cisc_alternate) { -+ desc->properties()->add(new Property("is_cisc_alternate", "true")); -+ } -+ if (flags & Node::Flag_is_Branch) { -+ desc->properties()->add(new Property("is_branch", "true")); -+ } -+ if (flags & Node::Flag_is_block_start) { -+ desc->properties()->add(new Property("is_block_start", "true")); -+ } -+ if (flags & Node::Flag_is_Goto) { -+ desc->properties()->add(new Property("is_goto", "true")); -+ } -+ if (flags & Node::Flag_is_dead_loop_safe) { -+ desc->properties()->add(new Property("is_dead_loop_safe", "true")); -+ } -+ if (flags & Node::Flag_may_be_short_branch) { -+ desc->properties()->add(new Property("may_be_short_branch", "true")); -+ } -+ if (flags & Node::Flag_is_safepoint_node) { -+ desc->properties()->add(new Property("is_safepoint_node", "true")); -+ } -+ if (flags & Node::Flag_is_pc_relative) { -+ desc->properties()->add(new Property("is_pc_relative", "true")); -+ } -+ -+ if (_matcher) { -+ if (_matcher->is_shared(desc->node())) { -+ desc->properties()->add(new Property("is_shared", "true")); -+ } else { -+ desc->properties()->add(new Property("is_shared", "false")); -+ } -+ -+ if (_matcher->is_dontcare(desc->node())) { -+ desc->properties()->add(new Property("is_dontcare", "true")); -+ } else { -+ desc->properties()->add(new Property("is_dontcare", "false")); -+ } -+ } -+ -+ if (node->is_Proj()) { -+ desc->properties()->add(new Property("con", (int)node->as_Proj()->_con)); -+ } -+ -+ if (node->is_Mach()) { -+ desc->properties()->add(new Property("idealOpcode", (const char *)NodeClassNames[node->as_Mach()->ideal_Opcode()])); -+ } -+ -+ -+ -+ -+ -+ outputStream *oldTty = tty; -+ buffer[0] = 0; -+ stringStream s2(buffer, sizeof(buffer) - 1); -+ -+ node->dump_spec(&s2); -+ assert(s2.size() < sizeof(buffer), "size in range"); -+ desc->properties()->add(new Property("dump_spec", buffer)); -+ -+ if (node->is_block_proj()) { -+ desc->properties()->add(new Property("is_block_proj", "true")); -+ } -+ -+ if (node->is_block_start()) { -+ desc->properties()->add(new Property("is_block_start", "true")); -+ } -+ -+ const char *short_name = "short_name"; -+ if (strcmp(node->Name(), "Parm") == 0 && node->as_Proj()->_con >= TypeFunc::Parms) { -+ int index = node->as_Proj()->_con - TypeFunc::Parms; -+ if (index >= 10) { -+ desc->properties()->add(new Property(short_name, "PA")); -+ } else { -+ sprintf(buffer, "P%d", index); -+ desc->properties()->add(new Property(short_name, buffer)); -+ } -+ } else if (strcmp(node->Name(), "IfTrue") == 0) { -+ desc->properties()->add(new Property(short_name, "T")); -+ } else if (strcmp(node->Name(), "IfFalse") == 0) { -+ desc->properties()->add(new Property(short_name, "F")); -+ } else if ((node->is_Con() && node->is_Type()) || node->is_Proj()) { -+ -+ if (t->base() == Type::Int && t->is_int()->is_con()) { -+ const TypeInt *typeInt = t->is_int(); -+ assert(typeInt->is_con(), "must be constant"); -+ jint value = typeInt->get_con(); -+ -+ // max. 2 chars allowed -+ if (value >= -9 && value <= 99) { -+ sprintf(buffer, "%d", value); -+ desc->properties()->add(new Property(short_name, buffer)); -+ } -+ else -+ { -+ desc->properties()->add(new Property(short_name, "I")); -+ } -+ } else if (t == Type::TOP) { -+ desc->properties()->add(new Property(short_name, "^")); -+ } else if (t->base() == Type::Long && t->is_long()->is_con()) { -+ const TypeLong *typeLong = t->is_long(); -+ assert(typeLong->is_con(), "must be constant"); -+ jlong value = typeLong->get_con(); -+ -+ // max. 2 chars allowed -+ if (value >= -9 && value <= 99) { -+ sprintf(buffer, "%d", value); -+ desc->properties()->add(new Property(short_name, buffer)); -+ } -+ else -+ { -+ desc->properties()->add(new Property(short_name, "L")); -+ } -+ } else if (t->base() == Type::KlassPtr) { -+ const TypeKlassPtr *typeKlass = t->is_klassptr(); -+ desc->properties()->add(new Property(short_name, "CP")); -+ } else if (t->base() == Type::Control) { -+ desc->properties()->add(new Property(short_name, "C")); -+ } else if (t->base() == Type::Memory) { -+ desc->properties()->add(new Property(short_name, "M")); -+ } else if (t->base() == Type::Abio) { -+ desc->properties()->add(new Property(short_name, "IO")); -+ } else if (t->base() == Type::Return_Address) { -+ desc->properties()->add(new Property(short_name, "RA")); -+ } else if (t->base() == Type::AnyPtr) { -+ desc->properties()->add(new Property(short_name, "P")); -+ } else if (t->base() == Type::RawPtr) { -+ desc->properties()->add(new Property(short_name, "RP")); -+ } else if (t->base() == Type::AryPtr) { -+ desc->properties()->add(new Property(short_name, "AP")); -+ } -+ } -+ -+ if (node->is_SafePoint()) { -+ SafePointNode *safePointNode = node->as_SafePoint(); -+ if (safePointNode->jvms()) { -+ stringStream bciStream; -+ bciStream.print("%d ", safePointNode->jvms()->bci()); -+ JVMState *caller = safePointNode->jvms()->caller(); -+ while(caller) { -+ bciStream.print("%d ", caller->bci()); -+ -+ caller = caller->caller(); -+ } -+ desc->properties()->add(new Property("bci", bciStream.as_string())); -+ } -+ } -+ -+ if (_chaitin && _chaitin != (PhaseChaitin *)0xdeadbeef) { -+ buffer[0] = 0; -+ _chaitin->dump_register(node, buffer); -+ desc->properties()->add(new Property("reg", buffer)); -+ desc->properties()->add(new Property("lrg", _chaitin->n2lidx(node))); -+ } -+ -+ -+ node->_in_dump_cnt--; -+ return desc; -+#else -+ return NULL; -+#endif -+} -+ -+void IdealGraphPrinter::pre_node(Node* node, void *env) { -+ -+ IdealGraphPrinter *printer = (IdealGraphPrinter *)env; -+ -+ NodeDescription *newDesc = printer->create_node_description(node); -+ -+ if (printer->_clear_nodes) { -+ -+ printer->_nodes.append(newDesc); -+ } else { -+ -+ NodeDescription *desc = printer->_nodes.at_grow(node->_idx, NULL); -+ -+ if (desc && desc->equals(newDesc)) { -+ //desc->set_state(Valid); -+ //desc->set_node(node); -+ delete desc; -+ printer->_nodes.at_put(node->_idx, NULL); -+ newDesc->set_state(Valid); -+ //printer->_nodes.at_put(node->_idx, newDesc); -+ } else { -+ -+ if (desc && desc->id() == newDesc->id()) { -+ delete desc; -+ printer->_nodes.at_put(node->_idx, NULL); -+ newDesc->set_state(New); -+ -+ } -+ -+ //if (desc) { -+ // delete desc; -+ //} -+ -+ //printer->_nodes.at_put(node->_idx, newDesc); -+ } -+ -+ printer->_nodes.append(newDesc); -+ } -+} -+ -+void IdealGraphPrinter::post_node(Node* node, void *env) { -+} -+ -+outputStream *IdealGraphPrinter::output() { -+ return _output; -+} -+ -+IdealGraphPrinter::Description::Description() { -+ _state = New; -+} -+ -+void IdealGraphPrinter::Description::print(IdealGraphPrinter *printer) { -+ if (_state == Invalid) { -+ print_removed(printer); -+ } else if (_state == New) { -+ print_changed(printer); -+ } -+} -+ -+void IdealGraphPrinter::Description::set_state(State s) { -+ _state = s; -+} -+ -+IdealGraphPrinter::State IdealGraphPrinter::Description::state() { -+ return _state; -+} -+ -+void IdealGraphPrinter::Block::set_proj(NodeDescription *n) { -+ _proj = n; -+} -+ -+void IdealGraphPrinter::Block::set_start(NodeDescription *n) { -+ _start = n; -+} -+ -+int IdealGraphPrinter::Block::semi() { -+ return _semi; -+} -+ -+int IdealGraphPrinter::Block::parent() { -+ return _parent; -+} -+ -+GrowableArray* IdealGraphPrinter::Block::bucket() { -+ return &_bucket; -+} -+ -+GrowableArray* IdealGraphPrinter::Block::children() { -+ return &_children; -+} -+ -+void IdealGraphPrinter::Block::add_child(int i) { -+ _children.append(i); -+} -+ -+GrowableArray* IdealGraphPrinter::Block::dominates() { -+ return &_dominates; -+} -+ -+void IdealGraphPrinter::Block::add_dominates(int i) { -+ _dominates.append(i); -+} -+ -+void IdealGraphPrinter::Block::add_to_bucket(int i) { -+ _bucket.append(i); -+} -+ -+void IdealGraphPrinter::Block::clear_bucket() { -+ _bucket.clear(); -+} -+ -+void IdealGraphPrinter::Block::set_dominator(int i) { -+ _dominator = i; -+} -+ -+void IdealGraphPrinter::Block::set_label(int i) { -+ _label = i; -+} -+ -+int IdealGraphPrinter::Block::label() { -+ return _label; -+} -+ -+int IdealGraphPrinter::Block::ancestor() { -+ return _ancestor; -+} -+ -+void IdealGraphPrinter::Block::set_ancestor(int i) { -+ _ancestor = i; -+} -+ -+int IdealGraphPrinter::Block::dominator() { -+ return _dominator; -+} -+ -+int IdealGraphPrinter::Block::index() { -+ return _index; -+} -+ -+void IdealGraphPrinter::Block::set_parent(int i) { -+ _parent = i; -+} -+ -+GrowableArray* IdealGraphPrinter::Block::pred() { -+ return &_pred; -+} -+ -+void IdealGraphPrinter::Block::set_semi(int i) { -+ _semi = i; -+} -+ -+IdealGraphPrinter::Block::Block() { -+} -+ -+IdealGraphPrinter::Block::Block(int index) { -+ _index = index; -+ _label = index; -+ _semi = -1; -+ _ancestor = -1; -+ _dominator = -1; -+} -+ -+void IdealGraphPrinter::Block::add_pred(int i) { -+ _pred.append(i); -+} -+ -+IdealGraphPrinter::NodeDescription *IdealGraphPrinter::Block::proj() { -+ return _proj; -+} -+ -+IdealGraphPrinter::NodeDescription *IdealGraphPrinter::Block::start() { -+ return _start; -+} -+ -+GrowableArray* IdealGraphPrinter::Block::succs() { -+ return &_succs; -+} -+ -+void IdealGraphPrinter::Block::add_succ(int index) { -+ -+ if (this->_index == 16 && index == 15) { -+ int x = 0; -+ } -+ -+ if (!_succs.contains(index)) { -+ _succs.append(index); -+ } -+} -+ -+ -+void IdealGraphPrinter::Block::add_node(NodeDescription *n) { -+ if (!_nodes.contains(n)) { -+ _nodes.append(n); -+ } -+} -+ -+GrowableArray* IdealGraphPrinter::Block::nodes() { -+ return &_nodes; -+} -+ -+int IdealGraphPrinter::NodeDescription::count = 0; -+ -+IdealGraphPrinter::NodeDescription::NodeDescription(Node* node) : _node(node) { -+ _id = (intptr_t)(node); -+ _block_index = -1; -+} -+ -+IdealGraphPrinter::NodeDescription::~NodeDescription() { -+ _properties.clean(); -+} -+ -+// void IdealGraphPrinter::NodeDescription::set_node(Node* node) { -+// //this->_node = node; -+// } -+ -+int IdealGraphPrinter::NodeDescription::block_index() { -+ return _block_index; -+} -+ -+ -+GrowableArray* IdealGraphPrinter::NodeDescription::succs() { -+ return &_succs; -+} -+ -+void IdealGraphPrinter::NodeDescription::clear_succs() { -+ _succs.clear(); -+} -+ -+void IdealGraphPrinter::NodeDescription::init_succs() { -+ _succs = GrowableArray(); -+} -+ -+void IdealGraphPrinter::NodeDescription::add_succ(NodeDescription *desc) { -+ _succs.append(desc); -+} -+ -+void IdealGraphPrinter::NodeDescription::set_block_index(int i) { -+ _block_index = i; -+} -+ -+bool IdealGraphPrinter::NodeDescription::equals(NodeDescription *desc) { -+ if (desc == NULL) return false; -+ if (desc->id() != id()) return false; -+ return properties()->equals(desc->properties()); -+} -+ -+Node* IdealGraphPrinter::NodeDescription::node() { -+ return _node; -+} -+ -+IdealGraphPrinter::Properties* IdealGraphPrinter::NodeDescription::properties() { -+ return &_properties; -+} -+ -+uint IdealGraphPrinter::NodeDescription::id() { -+ return _id; -+} -+ -+void IdealGraphPrinter::NodeDescription::print_changed(IdealGraphPrinter *printer) { -+ -+ -+ Properties properties; -+ properties.add(new Property(NODE_ID_PROPERTY, id())); -+ printer->start_element(NODE_ELEMENT, &properties); -+ -+ this->properties()->print(printer); -+ -+ -+ printer->end_element(NODE_ELEMENT); -+} -+ -+void IdealGraphPrinter::NodeDescription::print_removed(IdealGraphPrinter *printer) { -+ -+ Properties properties; -+ properties.add(new Property(NODE_ID_PROPERTY, id())); -+ printer->simple_element(REMOVE_NODE_ELEMENT, &properties); -+} -+ -+IdealGraphPrinter::EdgeDescription::EdgeDescription(int from, int to, int index) { -+ this->_from = from; -+ this->_to = to; -+ this->_index = index; -+} -+ -+IdealGraphPrinter::EdgeDescription::~EdgeDescription() { -+} -+ -+int IdealGraphPrinter::EdgeDescription::from() { -+ return _from; -+} -+ -+int IdealGraphPrinter::EdgeDescription::to() { -+ return _to; -+} -+ -+void IdealGraphPrinter::EdgeDescription::print_changed(IdealGraphPrinter *printer) { -+ -+ Properties properties; -+ properties.add(new Property(INDEX_PROPERTY, _index)); -+ properties.add(new Property(FROM_PROPERTY, _from)); -+ properties.add(new Property(TO_PROPERTY, _to)); -+ printer->simple_element(EDGE_ELEMENT, &properties); -+} -+ -+void IdealGraphPrinter::EdgeDescription::print_removed(IdealGraphPrinter *printer) { -+ -+ Properties properties; -+ properties.add(new Property(INDEX_PROPERTY, _index)); -+ properties.add(new Property(FROM_PROPERTY, _from)); -+ properties.add(new Property(TO_PROPERTY, _to)); -+ printer->simple_element(REMOVE_EDGE_ELEMENT, &properties); -+} -+ -+bool IdealGraphPrinter::EdgeDescription::equals(IdealGraphPrinter::EdgeDescription *desc) { -+ if (desc == NULL) return false; -+ return (_from == desc->_from && _to == desc->_to && _index == desc->_index); -+} -+ -+IdealGraphPrinter::Properties::Properties() : list(new (ResourceObj::C_HEAP) GrowableArray(2, 0, NULL, true)) { -+} -+ -+IdealGraphPrinter::Properties::~Properties() { -+ clean(); -+ delete list; -+} -+ -+void IdealGraphPrinter::Properties::add(Property *p) { -+ assert(p != NULL, "Property not NULL"); -+ list->append(p); -+} -+ -+void IdealGraphPrinter::Properties::print(IdealGraphPrinter *printer) { -+ printer->start_element(PROPERTIES_ELEMENT); -+ -+ for (int i = 0; i < list->length(); i++) { -+ list->at(i)->print(printer); -+ } -+ -+ printer->end_element(PROPERTIES_ELEMENT); -+} -+ -+void IdealGraphPrinter::Properties::clean() { -+ for (int i = 0; i < list->length(); i++) { -+ delete list->at(i); -+ list->at_put(i, NULL); -+ } -+ list->clear(); -+ assert(list->length() == 0, "List cleared"); -+} -+ -+void IdealGraphPrinter::Properties::remove(const char *name) { -+ for (int i = 0; i < list->length(); i++) { -+ if (strcmp(list->at(i)->name(), name) == 0) { -+ delete list->at(i); -+ list->remove_at(i); -+ i--; -+ } -+ } -+} -+ -+void IdealGraphPrinter::Properties::print_as_attributes(IdealGraphPrinter *printer) { -+ -+ for (int i = 0; i < list->length(); i++) { -+ assert(list->at(i) != NULL, "Property not null!"); -+ printer->output()->print(" "); -+ list->at(i)->print_as_attribute(printer); -+ } -+} -+ -+bool IdealGraphPrinter::Properties::equals(Properties* p) { -+ if (p->list->length() != this->list->length()) return false; -+ -+ for (int i = 0; i < list->length(); i++) { -+ assert(list->at(i) != NULL, "Property not null!"); -+ if (!list->at(i)->equals(p->list->at(i))) return false; -+ } -+ -+ return true; -+} -+ -+IdealGraphPrinter::Property::Property() { -+ _name = NULL; -+ _value = NULL; -+} -+ -+const char *IdealGraphPrinter::Property::name() { -+ return _name; -+} -+ -+IdealGraphPrinter::Property::Property(const Property* p) { -+ -+ this->_name = NULL; -+ this->_value = NULL; -+ -+ if (p->_name != NULL) { -+ _name = dup(p->_name); -+ } -+ -+ if (p->_value) { -+ _value = dup(p->_value); -+ } -+} -+ -+IdealGraphPrinter::Property::~Property() { -+ -+ clean(); -+} -+ -+IdealGraphPrinter::Property::Property(const char *name, const char *value) { -+ -+ assert(name, "Name must not be null!"); -+ assert(value, "Value must not be null!"); -+ -+ _name = dup(name); -+ _value = dup(value); -+} -+ -+IdealGraphPrinter::Property::Property(const char *name, int intValue) { -+ _name = dup(name); -+ -+ stringStream stream; -+ stream.print("%d", intValue); -+ _value = dup(stream.as_string()); -+} -+ -+void IdealGraphPrinter::Property::clean() { -+ if (_name) { -+ delete _name; -+ _name = NULL; -+ } -+ -+ if (_value) { -+ delete _value; -+ _value = NULL; -+ } -+} -+ -+ -+bool IdealGraphPrinter::Property::is_null() { -+ return _name == NULL; -+} -+ -+void IdealGraphPrinter::Property::print(IdealGraphPrinter *printer) { -+ -+ assert(!is_null(), "null properties cannot be printed!"); -+ Properties properties; -+ properties.add(new Property(PROPERTY_NAME_PROPERTY, _name)); -+ printer->start_element(PROPERTY_ELEMENT, &properties, false, false); -+ printer->print_xml(_value); -+ printer->end_element(PROPERTY_ELEMENT, false, true); -+} -+ -+void IdealGraphPrinter::Property::print_as_attribute(IdealGraphPrinter *printer) { -+ -+ printer->output()->print(_name); -+ printer->output()->print("=\""); -+ printer->print_xml(_value); -+ printer->output()->print("\""); -+} -+ -+ -+bool IdealGraphPrinter::Property::equals(Property* p) { -+ -+ if (is_null() && p->is_null()) return true; -+ if (is_null()) return false; -+ if (p->is_null()) return false; -+ -+ int cmp1 = strcmp(p->_name, _name); -+ if (cmp1 != 0) return false; -+ -+ int cmp2 = strcmp(p->_value, _value); -+ if (cmp2 != 0) return false; -+ -+ return true; -+} -+ -+void IdealGraphPrinter::print_xml(const char *value) { -+ size_t len = strlen(value); -+ -+ char buf[2]; -+ buf[1] = 0; -+ for (size_t i = 0; i < len; i++) { -+ char c = value[i]; -+ -+ switch(c) { -+ case '<': -+ output()->print("<"); -+ break; -+ -+ case '>': -+ output()->print(">"); -+ break; -+ -+ default: -+ buf[0] = c; -+ output()->print(buf); -+ break; -+ } -+ } -+} -+ -+#endif -diff -ruNb openjdk6/hotspot/src/share/vm/opto/idealGraphPrinter.hpp openjdk/hotspot/src/share/vm/opto/idealGraphPrinter.hpp ---- openjdk6/hotspot/src/share/vm/opto/idealGraphPrinter.hpp 1970-01-01 01:00:00.000000000 +0100 -+++ openjdk/hotspot/src/share/vm/opto/idealGraphPrinter.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -0,0 +1,323 @@ -+/* -+ * Copyright 2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, -+ * CA 95054 USA or visit www.sun.com if you need additional information or -+ * have any questions. -+ * -+ */ -+ -+#ifndef PRODUCT -+ -+class Compile; -+class PhaseIFG; -+class PhaseChaitin; -+class Matcher; -+class Node; -+class InlineTree; -+class ciMethod; -+ -+class IdealGraphPrinter -+{ -+private: -+ -+ enum State -+ { -+ Invalid, -+ Valid, -+ New -+ }; -+ -+private: -+ -+ static const char *INDENT; -+ static const char *TOP_ELEMENT; -+ static const char *GROUP_ELEMENT; -+ static const char *GRAPH_ELEMENT; -+ static const char *PROPERTIES_ELEMENT; -+ static const char *EDGES_ELEMENT; -+ static const char *PROPERTY_ELEMENT; -+ static const char *EDGE_ELEMENT; -+ static const char *NODE_ELEMENT; -+ static const char *NODES_ELEMENT; -+ static const char *CONTROL_FLOW_ELEMENT; -+ static const char *REMOVE_EDGE_ELEMENT; -+ static const char *REMOVE_NODE_ELEMENT; -+ static const char *METHOD_NAME_PROPERTY; -+ static const char *BLOCK_NAME_PROPERTY; -+ static const char *BLOCK_DOMINATOR_PROPERTY; -+ static const char *BLOCK_ELEMENT; -+ static const char *SUCCESSORS_ELEMENT; -+ static const char *SUCCESSOR_ELEMENT; -+ static const char *METHOD_IS_PUBLIC_PROPERTY; -+ static const char *METHOD_IS_STATIC_PROPERTY; -+ static const char *TRUE_VALUE; -+ static const char *NODE_NAME_PROPERTY; -+ static const char *EDGE_NAME_PROPERTY; -+ static const char *NODE_ID_PROPERTY; -+ static const char *FROM_PROPERTY; -+ static const char *TO_PROPERTY; -+ static const char *PROPERTY_NAME_PROPERTY; -+ static const char *GRAPH_NAME_PROPERTY; -+ static const char *INDEX_PROPERTY; -+ static const char *METHOD_ELEMENT; -+ static const char *INLINE_ELEMENT; -+ static const char *BYTECODES_ELEMENT; -+ static const char *METHOD_BCI_PROPERTY; -+ static const char *METHOD_SHORT_NAME_PROPERTY; -+ static const char *ASSEMBLY_ELEMENT; -+ -+ class Property { -+ -+ private: -+ -+ const char *_name; -+ const char *_value; -+ -+ public: -+ -+ Property(); -+ Property(const Property* p); -+ ~Property(); -+ Property(const char *name, const char *value); -+ Property(const char *name, int value); -+ bool equals(Property* p); -+ void print(IdealGraphPrinter *printer); -+ void print_as_attribute(IdealGraphPrinter *printer); -+ bool is_null(); -+ void clean(); -+ const char *name(); -+ -+ static const char* dup(const char *str) { -+ char * copy = new char[strlen(str)+1]; -+ strcpy(copy, str); -+ return copy; -+ } -+ -+ }; -+ -+ class Properties { -+ -+ private: -+ -+ GrowableArray *list; -+ -+ public: -+ -+ Properties(); -+ ~Properties(); -+ void add(Property *p); -+ void remove(const char *name); -+ bool equals(Properties* p); -+ void print(IdealGraphPrinter *printer); -+ void print_as_attributes(IdealGraphPrinter *printer); -+ void clean(); -+ -+ }; -+ -+ -+ class Description { -+ -+ private: -+ -+ State _state; -+ -+ public: -+ -+ Description(); -+ -+ State state(); -+ void set_state(State s); -+ void print(IdealGraphPrinter *printer); -+ virtual void print_changed(IdealGraphPrinter *printer) = 0; -+ virtual void print_removed(IdealGraphPrinter *printer) = 0; -+ -+ }; -+ -+ class NodeDescription : public Description{ -+ -+ public: -+ -+ static int count; -+ -+ private: -+ -+ GrowableArray _succs; -+ int _block_index; -+ uintptr_t _id; -+ Properties _properties; -+ Node* _node; -+ -+ public: -+ -+ NodeDescription(Node* node); -+ ~NodeDescription(); -+ Node* node(); -+ -+ // void set_node(Node* node); -+ GrowableArray* succs(); -+ void init_succs(); -+ void clear_succs(); -+ void add_succ(NodeDescription *desc); -+ int block_index(); -+ void set_block_index(int i); -+ Properties* properties(); -+ virtual void print_changed(IdealGraphPrinter *printer); -+ virtual void print_removed(IdealGraphPrinter *printer); -+ bool equals(NodeDescription *desc); -+ uint id(); -+ -+ }; -+ -+ class Block { -+ -+ private: -+ -+ NodeDescription *_start; -+ NodeDescription *_proj; -+ GrowableArray _succs; -+ GrowableArray _nodes; -+ GrowableArray _dominates; -+ GrowableArray _children; -+ int _semi; -+ int _parent; -+ GrowableArray _pred; -+ GrowableArray _bucket; -+ int _index; -+ int _dominator; -+ int _ancestor; -+ int _label; -+ -+ public: -+ -+ Block(); -+ Block(int index); -+ -+ void add_node(NodeDescription *n); -+ GrowableArray* nodes(); -+ GrowableArray* children(); -+ void add_child(int i); -+ void add_succ(int index); -+ GrowableArray* succs(); -+ GrowableArray* dominates(); -+ void add_dominates(int i); -+ NodeDescription *start(); -+ NodeDescription *proj(); -+ void set_start(NodeDescription *n); -+ void set_proj(NodeDescription *n); -+ -+ int label(); -+ void set_label(int i); -+ int ancestor(); -+ void set_ancestor(int i); -+ int index(); -+ int dominator(); -+ void set_dominator(int i); -+ int parent(); -+ void set_parent(int i); -+ int semi(); -+ GrowableArray* bucket(); -+ void add_to_bucket(int i); -+ void clear_bucket(); -+ GrowableArray* pred(); -+ void set_semi(int i); -+ void add_pred(int i); -+ -+ }; -+ -+ class EdgeDescription : public Description { -+ -+ private: -+ -+ int _from; -+ int _to; -+ int _index; -+ public: -+ -+ EdgeDescription(int from, int to, int index); -+ ~EdgeDescription(); -+ -+ virtual void print_changed(IdealGraphPrinter *printer); -+ virtual void print_removed(IdealGraphPrinter *printer); -+ bool equals(EdgeDescription *desc); -+ int from(); -+ int to(); -+ }; -+ -+ -+ static int _file_count; -+ networkStream *_stream; -+ outputStream *_output; -+ ciMethod *_current_method; -+ GrowableArray _nodes; -+ GrowableArray _edges; -+ int _depth; -+ Arena *_arena; -+ char buffer[128]; -+ bool _should_send_method; -+ PhaseChaitin* _chaitin; -+ bool _clear_nodes; -+ Matcher* _matcher; -+ bool _traverse_outs; -+ -+ void start_element_helper(const char *name, Properties *properties, bool endElement, bool print_indent = false, bool print_return = true); -+ NodeDescription *create_node_description(Node* node); -+ -+ static void pre_node(Node* node, void *env); -+ static void post_node(Node* node, void *env); -+ -+ void schedule_latest(int **common_dominator, GrowableArray* blocks); -+ void build_common_dominator(int **common_dominator, int index, GrowableArray* blocks); -+ void compress(int index, GrowableArray* blocks); -+ int eval(int index, GrowableArray* blocks); -+ void link(int index1, int index2, GrowableArray* blocks); -+ void build_dominators(GrowableArray* blocks); -+ void build_blocks(Node *node); -+ void walk(Node *n); -+ void start_element(const char *name, Properties *properties = NULL, bool print_indent = false, bool print_return = true); -+ void simple_element(const char *name, Properties *properties = NULL, bool print_indent = false); -+ void end_element(const char *name, bool print_indent = false, bool print_return = true); -+ void print_edge(int from, int to, int index); -+ void print_indent(); -+ void print_method(ciMethod *method, int bci, InlineTree *tree); -+ void print_inline_tree(InlineTree *tree); -+ void clear_nodes(); -+ -+ IdealGraphPrinter(); -+ ~IdealGraphPrinter(); -+ -+public: -+ -+ static void clean_up(); -+ static IdealGraphPrinter *printer(); -+ -+ bool traverse_outs(); -+ void set_traverse_outs(bool b); -+ void print_ifg(PhaseIFG* ifg); -+ outputStream *output(); -+ void print_inlining(Compile* compile); -+ void begin_method(Compile* compile); -+ void end_method(); -+ void print_method(Compile* compile, const char *name, int level=1, bool clear_nodes = false); -+ void print(Compile* compile, const char *name, Node *root, int level=1, bool clear_nodes = false); -+ void print_xml(const char *name); -+ -+ -+}; -+ -+#endif -diff -ruNb openjdk6/hotspot/src/share/vm/opto/idealKit.cpp openjdk/hotspot/src/share/vm/opto/idealKit.cpp ---- openjdk6/hotspot/src/share/vm/opto/idealKit.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/idealKit.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)idealKit.cpp 1.7 07/05/05 17:06:29 JVM" --#endif - /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -29,15 +26,23 @@ - #include "incls/_idealKit.cpp.incl" - - // Static initialization --const uint IdealKit::first_var = 1; -+ -+// This declares the position where vars are kept in the cvstate -+// For some degree of consistency we use the TypeFunc enum to -+// soak up spots in the inputs even though we only use early Control -+// and Memory slots. (So far.) -+const uint IdealKit::first_var = TypeFunc::Parms + 1; - - //----------------------------IdealKit----------------------------------------- --IdealKit::IdealKit(PhaseGVN &gvn, Node* control, bool delay_all_transforms) : -+IdealKit::IdealKit(PhaseGVN &gvn, Node* control, Node* mem, bool delay_all_transforms) : - _gvn(gvn), C(gvn.C) { - _initial_ctrl = control; -+ _initial_memory = mem; - _delay_all_transforms = delay_all_transforms; - _var_ct = 0; - _cvstate = NULL; -+ // We can go memory state free or else we need the entire memory state -+ assert(mem == NULL || mem->Opcode() == Op_MergeMem, "memory must be pre-split"); - int init_size = 5; - _pending_cvstates = new (C->node_arena()) GrowableArray(C->node_arena(), init_size, 0, 0); - _delay_transform = new (C->node_arena()) GrowableArray(C->node_arena(), init_size, 0, 0); -@@ -52,14 +57,25 @@ - void IdealKit::if_then(Node* left, BoolTest::mask relop, - Node* right, float prob, float cnt, bool push_new_state) { - assert((state() & (BlockS|LoopS|IfThenS|ElseS)), "bad state for new If"); -- Node* bol = Bool(CmpI(left, right), relop); -+ Node* bol; -+ if (left->bottom_type()->isa_ptr() == NULL) { -+ if (left->bottom_type()->isa_int() != NULL) { -+ bol = Bool(CmpI(left, right), relop); -+ } else { -+ assert(left->bottom_type()->isa_long() != NULL, "what else?"); -+ bol = Bool(CmpL(left, right), relop); -+ } -+ -+ } else { -+ bol = Bool(CmpP(left, right), relop); -+ } - // Delay gvn.tranform on if-nodes until construction is finished - // to prevent a constant bool input from discarding a control output. - IfNode* iff = delay_transform(new (C, 2) IfNode(ctrl(), bol, prob, cnt))->as_If(); - Node* then = IfTrue(iff); - Node* elsen = IfFalse(iff); - Node* else_cvstate = copy_cvstate(); -- else_cvstate->set_req(0, elsen); -+ else_cvstate->set_req(TypeFunc::Control, elsen); - _pending_cvstates->push(else_cvstate); - DEBUG_ONLY(if (push_new_state) _state->push(IfThenS)); - set_ctrl(then); -@@ -79,16 +95,42 @@ - } - - //-------------------------------end_if------------------------------------- --// Merge the "then" and "else" cvstates from an "if" via: --// create label, generate a goto from the current cvstate to the --// new label, pop the other cvstate from the if ("else" cvstate if --// no else_() and "then" cvstate if there was), and bind the label --// to the popped cvstate. -+// Merge the "then" and "else" cvstates. -+// -+// The if_then() pushed the current state for later use -+// as the initial state for a future "else" clause. The -+// current state then became the initial state for the -+// then clause. If an "else" clause was encountered, it will -+// pop the top state and use it for it's initial state. -+// It will also push the current state (the state at the end of -+// the "then" clause) for latter use at the end_if. -+// -+// At the endif, the states are: -+// 1) else exists a) current state is end of "else" clause -+// b) top stack state is end of "then" clause -+// -+// 2) no else: a) current state is end of "then" clause -+// b) top stack state is from the "if_then" which -+// would have been the initial state of the else. -+// -+// Merging the states is accomplished by: -+// 1) make a label for the merge -+// 2) terminate the current state with a goto to the label -+// 3) pop the top state from the stack and make it the -+// current state -+// 4) bind the label at the current state. Binding a label -+// terminates the current state with a goto to the -+// label and makes the label's state the current state. -+// - void IdealKit::end_if() { - assert(state() & (IfThenS|ElseS), "bad state for new Endif"); - Node* lab = make_label(1); -+ -+ // Node* join_state = _pending_cvstates->pop(); -+ /* merging, join */ - goto_(lab); - _cvstate = _pending_cvstates->pop(); -+ - bind(lab); - DEBUG_ONLY(_state->pop()); - } -@@ -115,7 +157,7 @@ - if_then(value(iv), relop, limit, prob, cnt, false /* no new state */); - DEBUG_ONLY(_state->push(LoopS)); - assert(ctrl()->is_IfTrue(), "true branch stays in loop"); -- assert(_pending_cvstates->top()->in(0)->is_IfFalse(), "false branch exits loop"); -+ assert(_pending_cvstates->top()->in(TypeFunc::Control)->is_IfFalse(), "false branch exits loop"); - } - - //-------------------------------end_loop------------------------------------- -@@ -141,7 +183,7 @@ - Node* lab = new_cvstate(); - int sz = 1 + goto_ct + 1 /* fall thru */; - Node* reg = delay_transform(new (C, sz) RegionNode(sz)); -- lab->init_req(0, reg); -+ lab->init_req(TypeFunc::Control, reg); - return lab; - } - -@@ -160,7 +202,7 @@ - // all live values have phis created. Used to create phis - // at loop-top regions. - void IdealKit::goto_(Node* lab, bool bind) { -- Node* reg = lab->in(0); -+ Node* reg = lab->in(TypeFunc::Control); - // find next empty slot in region - uint slot = 1; - while (slot < reg->req() && reg->in(slot) != NULL) slot++; -@@ -170,23 +212,40 @@ - reg->init_req(slot, ctrl()); - assert(first_var + _var_ct == _cvstate->req(), "bad _cvstate size"); - for (uint i = first_var; i < _cvstate->req(); i++) { -+ -+ // l is the value of var reaching the label. Could be a single value -+ // reaching the label, or a phi that merges multiples values reaching -+ // the label. The latter is true if the label's input: in(..) is -+ // a phi whose control input is the region node for the label. -+ - Node* l = lab->in(i); -+ // Get the current value of the var - Node* m = _cvstate->in(i); -+ // If the var went unused no need for a phi - if (m == NULL) { - continue; - } else if (l == NULL || m == l) { -+ // Only one unique value "m" is known to reach this label so a phi -+ // is not yet necessary unless: -+ // the label is being bound and all predecessors have not been seen, -+ // in which case "bind" will be true. - if (bind) { - m = promote_to_phi(m, reg); - } -+ // Record the phi/value used for this var in the label's cvstate - lab->set_req(i, m); - } else { -+ // More than one value for the variable reaches this label so -+ // a create a phi if one does not already exist. - if (!was_promoted_to_phi(l, reg)) { - l = promote_to_phi(l, reg); - lab->set_req(i, l); - } -+ // Record in the phi, the var's value from the current state - l->set_req(slot, m); - } - } -+ do_memory_merge(_cvstate, lab); - stop(); - } - -@@ -203,6 +262,7 @@ - void IdealKit::declares_done() { - _cvstate = new_cvstate(); // initialize current cvstate - set_ctrl(_initial_ctrl); // initialize control in current cvstate -+ set_all_memory(_initial_memory);// initialize memory in current cvstate - DEBUG_ONLY(_state->push(BlockS)); - } - -@@ -232,6 +292,8 @@ - Node* IdealKit::copy_cvstate() { - Node* ns = new_cvstate(); - for (uint i = 0; i < ns->req(); i++) ns->init_req(i, _cvstate->in(i)); -+ // We must clone memory since it will be updated as we do stores. -+ ns->set_req(TypeFunc::Memory, MergeMemNode::make(C, ns->in(TypeFunc::Memory))); - return ns; - } - -@@ -256,3 +318,186 @@ - k.declare(this); - } - -+Node* IdealKit::memory(uint alias_idx) { -+ MergeMemNode* mem = merged_memory(); -+ Node* p = mem->memory_at(alias_idx); -+ _gvn.set_type(p, Type::MEMORY); // must be mapped -+ return p; -+} -+ -+void IdealKit::set_memory(Node* mem, uint alias_idx) { -+ merged_memory()->set_memory_at(alias_idx, mem); -+} -+ -+//----------------------------- make_load ---------------------------- -+Node* IdealKit::load(Node* ctl, -+ Node* adr, -+ const Type* t, -+ BasicType bt, -+ int adr_idx, -+ bool require_atomic_access) { -+ -+ assert(adr_idx != Compile::AliasIdxTop, "use other make_load factory" ); -+ const TypePtr* adr_type = NULL; // debug-mode-only argument -+ debug_only(adr_type = C->get_adr_type(adr_idx)); -+ Node* mem = memory(adr_idx); -+ Node* ld; -+ if (require_atomic_access && bt == T_LONG) { -+ ld = LoadLNode::make_atomic(C, ctl, mem, adr, adr_type, t); -+ } else { -+ ld = LoadNode::make(C, ctl, mem, adr, adr_type, t, bt); -+ } -+ return transform(ld); -+} -+ -+Node* IdealKit::store(Node* ctl, Node* adr, Node *val, BasicType bt, -+ int adr_idx, -+ bool require_atomic_access) { -+ assert(adr_idx != Compile::AliasIdxTop, "use other store_to_memory factory" ); -+ const TypePtr* adr_type = NULL; -+ debug_only(adr_type = C->get_adr_type(adr_idx)); -+ Node *mem = memory(adr_idx); -+ Node* st; -+ if (require_atomic_access && bt == T_LONG) { -+ st = StoreLNode::make_atomic(C, ctl, mem, adr, adr_type, val); -+ } else { -+ st = StoreNode::make(C, ctl, mem, adr, adr_type, val, bt); -+ } -+ st = transform(st); -+ set_memory(st, adr_idx); -+ -+ return st; -+} -+ -+// Card mark store. Must be ordered so that it will come after the store of -+// the oop. -+Node* IdealKit::storeCM(Node* ctl, Node* adr, Node *val, Node* oop_store, -+ BasicType bt, -+ int adr_idx) { -+ assert(adr_idx != Compile::AliasIdxTop, "use other store_to_memory factory" ); -+ const TypePtr* adr_type = NULL; -+ debug_only(adr_type = C->get_adr_type(adr_idx)); -+ Node *mem = memory(adr_idx); -+ -+ // Add required edge to oop_store, optimizer does not support precedence edges. -+ // Convert required edge to precedence edge before allocation. -+ Node* st = new (C, 5) StoreCMNode(ctl, mem, adr, adr_type, val, oop_store); -+ -+ st = transform(st); -+ set_memory(st, adr_idx); -+ -+ return st; -+} -+ -+//---------------------------- do_memory_merge -------------------------------- -+// The memory from one merging cvstate needs to be merged with the memory for another -+// join cvstate. If the join cvstate doesn't have a merged memory yet then we -+// can just copy the state from the merging cvstate -+ -+// Merge one slow path into the rest of memory. -+void IdealKit::do_memory_merge(Node* merging, Node* join) { -+ -+ // Get the region for the join state -+ Node* join_region = join->in(TypeFunc::Control); -+ assert(join_region != NULL, "join region must exist"); -+ if (join->in(TypeFunc::Memory) == NULL ) { -+ join->set_req(TypeFunc::Memory, merging->in(TypeFunc::Memory)); -+ return; -+ } -+ -+ // The control flow for merging must have already been attached to the join region -+ // we need its index for the phis. -+ uint slot; -+ for (slot = 1; slot < join_region->req() ; slot ++ ) { -+ if (join_region->in(slot) == merging->in(TypeFunc::Control)) break; -+ } -+ assert(slot != join_region->req(), "edge must already exist"); -+ -+ MergeMemNode* join_m = join->in(TypeFunc::Memory)->as_MergeMem(); -+ MergeMemNode* merging_m = merging->in(TypeFunc::Memory)->as_MergeMem(); -+ -+ // join_m should be an ancestor mergemem of merging -+ // Slow path memory comes from the current map (which is from a slow call) -+ // Fast path/null path memory comes from the call's input -+ -+ // Merge the other fast-memory inputs with the new slow-default memory. -+ // for (MergeMemStream mms(merged_memory(), fast_mem->as_MergeMem()); mms.next_non_empty2(); ) { -+ for (MergeMemStream mms(join_m, merging_m); mms.next_non_empty2(); ) { -+ Node* join_slice = mms.force_memory(); -+ Node* merging_slice = mms.memory2(); -+ if (join_slice != merging_slice) { -+ PhiNode* phi; -+ // bool new_phi = false; -+ // Is the phi for this slice one that we created for this join region or simply -+ // one we copied? If it is ours then add -+ if (join_slice->is_Phi() && join_slice->as_Phi()->region() == join_region) { -+ phi = join_slice->as_Phi(); -+ } else { -+ // create the phi with join_slice filling supplying memory for all of the -+ // control edges to the join region -+ phi = PhiNode::make(join_region, join_slice, Type::MEMORY, mms.adr_type(C)); -+ phi = (PhiNode*) delay_transform(phi); -+ // gvn().set_type(phi, Type::MEMORY); -+ // new_phi = true; -+ } -+ // Now update the phi with the slice for the merging slice -+ phi->set_req(slot, merging_slice/* slow_path, slow_slice */); -+ // this updates join_m with the phi -+ mms.set_memory(phi); -+ } -+ } -+} -+ -+ -+//----------------------------- make_call ---------------------------- -+// Trivial runtime call -+void IdealKit::make_leaf_call(const TypeFunc *slow_call_type, -+ address slow_call, -+ const char *leaf_name, -+ Node* parm0, -+ Node* parm1, -+ Node* parm2) { -+ -+ // We only handle taking in RawMem and modifying RawMem -+ const TypePtr* adr_type = TypeRawPtr::BOTTOM; -+ uint adr_idx = C->get_alias_index(adr_type); -+ -+ // Clone initial memory -+ MergeMemNode* cloned_mem = MergeMemNode::make(C, merged_memory()); -+ -+ // Slow-path leaf call -+ int size = slow_call_type->domain()->cnt(); -+ CallNode *call = (CallNode*)new (C, size) CallLeafNode( slow_call_type, slow_call, leaf_name, adr_type); -+ -+ // Set fixed predefined input arguments -+ call->init_req( TypeFunc::Control, ctrl() ); -+ call->init_req( TypeFunc::I_O , top() ) ; // does no i/o -+ // Narrow memory as only memory input -+ call->init_req( TypeFunc::Memory , memory(adr_idx)); -+ call->init_req( TypeFunc::FramePtr, top() /* frameptr() */ ); -+ call->init_req( TypeFunc::ReturnAdr, top() ); -+ -+ if (parm0 != NULL) call->init_req(TypeFunc::Parms+0, parm0); -+ if (parm1 != NULL) call->init_req(TypeFunc::Parms+1, parm1); -+ if (parm2 != NULL) call->init_req(TypeFunc::Parms+2, parm2); -+ -+ // Node *c = _gvn.transform(call); -+ call = (CallNode *) _gvn.transform(call); -+ Node *c = call; // dbx gets confused with call call->dump() -+ -+ // Slow leaf call has no side-effects, sets few values -+ -+ set_ctrl(transform( new (C, 1) ProjNode(call,TypeFunc::Control) )); -+ -+ // Set the incoming clone of memory as current memory -+ set_all_memory(cloned_mem); -+ -+ // Make memory for the call -+ Node* mem = _gvn.transform( new (C, 1) ProjNode(call, TypeFunc::Memory) ); -+ -+ // Set the RawPtr memory state only. -+ set_memory(mem, adr_idx); -+ -+ assert(C->alias_type(call->adr_type()) == C->alias_type(adr_type), -+ "call node must be constructed correctly"); -+} -diff -ruNb openjdk6/hotspot/src/share/vm/opto/idealKit.hpp openjdk/hotspot/src/share/vm/opto/idealKit.hpp ---- openjdk6/hotspot/src/share/vm/opto/idealKit.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/idealKit.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)idealKit.hpp 1.7 07/05/05 17:06:17 JVM" --#endif - /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -93,17 +90,23 @@ - PhaseGVN &_gvn; - GrowableArray* _pending_cvstates; // stack of cvstates - GrowableArray* _delay_transform; // delay invoking gvn.transform until drain -- Node* _cvstate; // current cvstate (control and variables) -+ Node* _cvstate; // current cvstate (control, memory and variables) - uint _var_ct; // number of variables - bool _delay_all_transforms; // flag forcing all transforms to be delayed - Node* _initial_ctrl; // saves initial control until variables declared -+ Node* _initial_memory; // saves initial memory until variables declared - - PhaseGVN& gvn() const { return _gvn; } - // Create a new cvstate filled with nulls - Node* new_cvstate(); // Create a new cvstate - Node* cvstate() { return _cvstate; } // current cvstate - Node* copy_cvstate(); // copy current cvstate -- void set_ctrl(Node* ctrl) { _cvstate->set_req(0, ctrl); } -+ void set_ctrl(Node* ctrl) { _cvstate->set_req(TypeFunc::Control, ctrl); } -+ -+ // Should this assert this is a MergeMem??? -+ void set_all_memory(Node* mem){ _cvstate->set_req(TypeFunc::Memory, mem); } -+ void set_memory(Node* mem, uint alias_idx ); -+ void do_memory_merge(Node* merging, Node* join); - void clear(Node* m); // clear a cvstate - void stop() { clear(_cvstate); } // clear current cvstate - Node* delay_transform(Node* n); -@@ -113,7 +116,11 @@ - return (n->is_Phi() && n->in(0) == reg); - } - void declare(IdealVariable* v) { v->set_id(_var_ct++); } -- static const uint first_var; -+ // This declares the position where vars are kept in the cvstate -+ // For some degree of consistency we use the TypeFunc enum to -+ // soak up spots in the inputs even though we only use early Control -+ // and Memory slots. (So far.) -+ static const uint first_var; // = TypeFunc::Parms + 1; - - #ifdef ASSERT - enum State { NullS=0, BlockS=1, LoopS=2, IfThenS=4, ElseS=8, EndifS= 16 }; -@@ -121,14 +128,19 @@ - State state() { return (State)(_state->top()); } - #endif - -+ // Users should not care about slices only MergedMem so no access for them. -+ Node* memory(uint alias_idx); -+ - public: -- IdealKit(PhaseGVN &gvn, Node* control, bool delay_all_transforms = false); -+ IdealKit(PhaseGVN &gvn, Node* control, Node* memory, bool delay_all_transforms = false); - ~IdealKit() { - stop(); - drain_delay_transform(); - } - // Control -- Node* ctrl() { return _cvstate->in(0); } -+ Node* ctrl() { return _cvstate->in(TypeFunc::Control); } -+ Node* top() { return C->top(); } -+ MergeMemNode* merged_memory() { return _cvstate->in(TypeFunc::Memory)->as_MergeMem(); } - void set(IdealVariable& v, Node* rhs) { _cvstate->set_req(first_var + v.id(), rhs); } - Node* value(IdealVariable& v) { return _cvstate->in(first_var + v.id()); } - void dead(IdealVariable& v) { set(v, (Node*)NULL); } -@@ -145,10 +157,14 @@ - void goto_(Node* lab, bool bind = false); - void declares_done(); - void drain_delay_transform(); -+ - Node* IfTrue(IfNode* iff) { return transform(new (C,1) IfTrueNode(iff)); } - Node* IfFalse(IfNode* iff) { return transform(new (C,1) IfFalseNode(iff)); } -+ - // Data - Node* ConI(jint k) { return (Node*)gvn().intcon(k); } -+ Node* makecon(const Type *t) const { return _gvn.makecon(t); } -+ - Node* AddI(Node* l, Node* r) { return transform(new (C,3) AddINode(l, r)); } - Node* SubI(Node* l, Node* r) { return transform(new (C,3) SubINode(l, r)); } - Node* AndI(Node* l, Node* r) { return transform(new (C,3) AndINode(l, r)); } -@@ -158,4 +174,57 @@ - Node* Bool(Node* cmp, BoolTest::mask relop) { return transform(new (C,2) BoolNode(cmp, relop)); } - void increment(IdealVariable& v, Node* j) { set(v, AddI(value(v), j)); } - void decrement(IdealVariable& v, Node* j) { set(v, SubI(value(v), j)); } -+ -+ Node* CmpL(Node* l, Node* r) { return transform(new (C,3) CmpLNode(l, r)); } -+ -+ // TLS -+ Node* thread() { return gvn().transform(new (C, 1) ThreadLocalNode()); } -+ -+ // Pointers -+ Node* AddP(Node *base, Node *ptr, Node *off) { return transform(new (C,4) AddPNode(base, ptr, off)); } -+ Node* CmpP(Node* l, Node* r) { return transform(new (C,3) CmpPNode(l, r)); } -+#ifdef _LP64 -+ Node* XorX(Node* l, Node* r) { return transform(new (C,3) XorLNode(l, r)); } -+#else // _LP64 -+ Node* XorX(Node* l, Node* r) { return transform(new (C,3) XorINode(l, r)); } -+#endif // _LP64 -+ Node* URShiftX(Node* l, Node* r) { return transform(new (C,3) URShiftXNode(l, r)); } -+ Node* ConX(jint k) { return (Node*)gvn().MakeConX(k); } -+ Node* CastPX(Node* ctl, Node* p) { return transform(new (C,2) CastP2XNode(ctl, p)); } -+ // Add a fixed offset to a pointer -+ Node* basic_plus_adr(Node* base, Node* ptr, intptr_t offset); -+ -+ // Memory operations -+ -+ // This is the base version which is given an alias index. -+ Node* load(Node* ctl, -+ Node* adr, -+ const Type* t, -+ BasicType bt, -+ int adr_idx, -+ bool require_atomic_access = false); -+ -+ // Return the new StoreXNode -+ Node* store(Node* ctl, -+ Node* adr, -+ Node* val, -+ BasicType bt, -+ int adr_idx, -+ bool require_atomic_access = false); -+ -+ // Store a card mark ordered after store_oop -+ Node* storeCM(Node* ctl, -+ Node* adr, -+ Node* val, -+ Node* oop_store, -+ BasicType bt, -+ int adr_idx); -+ -+ // Trivial call -+ void make_leaf_call(const TypeFunc *slow_call_type, -+ address slow_call, -+ const char *leaf_name, -+ Node* parm0, -+ Node* parm1 = NULL, -+ Node* parm2 = NULL); - }; -diff -ruNb openjdk6/hotspot/src/share/vm/opto/ifg.cpp openjdk/hotspot/src/share/vm/opto/ifg.cpp ---- openjdk6/hotspot/src/share/vm/opto/ifg.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/ifg.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ifg.cpp 1.62 07/05/05 17:06:13 JVM" --#endif - /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -814,4 +811,3 @@ - - return must_spill; - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/ifnode.cpp openjdk/hotspot/src/share/vm/opto/ifnode.cpp ---- openjdk6/hotspot/src/share/vm/opto/ifnode.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/ifnode.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ifnode.cpp 1.60 07/05/17 17:43:44 JVM" --#endif - /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -364,13 +361,19 @@ - Node *u = (p->Opcode() == Op_IfTrue) ? region_s : region_f; - // Replace p with u - igvn->add_users_to_worklist(p); -- for (DUIterator_Last jmin, j = p->last_outs(jmin); j >= jmin; --j) { -- Node* x = p->last_out(j); -+ for (DUIterator_Last lmin, l = p->last_outs(lmin); l >= lmin;) { -+ Node* x = p->last_out(l); - igvn->hash_delete(x); -- for( uint j = 0; j < x->req(); j++ ) -- if( x->in(j) == p ) -- x->set_req_X(j,u,igvn); -+ uint uses_found = 0; -+ for( uint j = 0; j < x->req(); j++ ) { -+ if( x->in(j) == p ) { -+ x->set_req(j, u); -+ uses_found++; -+ } - } -+ l -= uses_found; // we deleted 1 or more copies of this edge -+ } -+ igvn->remove_dead_node(p); - } - - // Force the original merge dead -@@ -842,8 +845,8 @@ - - //------------------------------dump_spec-------------------------------------- - #ifndef PRODUCT --void IfNode::dump_spec() const { -- tty->print("P=%f, C=%f",_prob,_fcnt); -+void IfNode::dump_spec(outputStream *st) const { -+ st->print("P=%f, C=%f",_prob,_fcnt); - } - #endif - -@@ -917,4 +920,3 @@ - ? in(0)->in(0) // IfNode control - : this; // no progress - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/indexSet.cpp openjdk/hotspot/src/share/vm/opto/indexSet.cpp ---- openjdk6/hotspot/src/share/vm/opto/indexSet.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/indexSet.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)indexSet.cpp 1.24 07/05/05 17:06:16 JVM" --#endif - /* - * Copyright 1998-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/opto/indexSet.hpp openjdk/hotspot/src/share/vm/opto/indexSet.hpp ---- openjdk6/hotspot/src/share/vm/opto/indexSet.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/indexSet.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)indexSet.hpp 1.29 07/05/05 17:06:18 JVM" --#endif - /* - * Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/opto/lcm.cpp openjdk/hotspot/src/share/vm/opto/lcm.cpp ---- openjdk6/hotspot/src/share/vm/opto/lcm.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/lcm.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)lcm.cpp 1.102 07/05/17 15:58:55 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -935,7 +932,3 @@ - } - } - } -- -- -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/library_call.cpp openjdk/hotspot/src/share/vm/opto/library_call.cpp ---- openjdk6/hotspot/src/share/vm/opto/library_call.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/library_call.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)library_call.cpp 1.164 07/05/17 15:59:02 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -76,8 +73,12 @@ - Node* generate_guard(Node* test, RegionNode* region, float true_prob); - Node* generate_slow_guard(Node* test, RegionNode* region); - Node* generate_fair_guard(Node* test, RegionNode* region); -- Node* generate_negative_guard(Node* index, RegionNode* region); -- Node* generate_nonpositive_guard(Node* index, bool never_negative); -+ Node* generate_negative_guard(Node* index, RegionNode* region, -+ // resulting CastII of index: -+ Node* *pos_index = NULL); -+ Node* generate_nonpositive_guard(Node* index, bool never_negative, -+ // resulting CastII of index: -+ Node* *pos_index = NULL); - Node* generate_limit_guard(Node* offset, Node* subseq_length, - Node* array_length, - RegionNode* region); -@@ -181,7 +182,21 @@ - int nargs, // arguments on stack for debug info - bool disjoint_bases = false, - bool length_never_negative = false, -- Node* slow_region = NULL); -+ RegionNode* slow_region = NULL); -+ AllocateArrayNode* tightly_coupled_allocation(Node* ptr, -+ RegionNode* slow_region); -+ void generate_clear_array(const TypePtr* adr_type, -+ Node* dest, -+ BasicType basic_elem_type, -+ Node* slice_off, -+ Node* slice_len, -+ Node* slice_end); -+ bool generate_block_arraycopy(const TypePtr* adr_type, -+ BasicType basic_elem_type, -+ AllocateNode* alloc, -+ Node* src, Node* src_offset, -+ Node* dest, Node* dest_offset, -+ Node* dest_size); - void generate_slow_arraycopy(const TypePtr* adr_type, - Node* src, Node* src_offset, - Node* dest, Node* dest_offset, -@@ -196,8 +211,8 @@ - Node* src, Node* src_offset, - Node* dest, Node* dest_offset, - Node* copy_length, int nargs); -- void generate_unchecked_arraycopy(BasicType basic_elem_type, -- const TypePtr* adr_type, -+ void generate_unchecked_arraycopy(const TypePtr* adr_type, -+ BasicType basic_elem_type, - bool disjoint_bases, - Node* src, Node* src_offset, - Node* dest, Node* dest_offset, -@@ -631,6 +646,14 @@ - - //------------------------------generate_guard--------------------------- - // Helper function for generating guarded fast-slow graph structures. -+// The given 'test', if true, guards a slow path. If the test fails -+// then a fast path can be taken. (We generally hope it fails.) -+// In all cases, GraphKit::control() is updated to the fast path. -+// The returned value represents the control for the slow path. -+// The return value is never 'top'; it is either a valid control -+// or NULL if it is obvious that the slow path can never be taken. -+// Also, if region and the slow control are not NULL, the slow edge -+// is appended to the region. - Node* LibraryCallKit::generate_guard(Node* test, RegionNode* region, float true_prob) { - if (stopped()) { - // Already short circuited. -@@ -668,7 +691,8 @@ - return generate_guard(test, region, PROB_FAIR); - } - --inline Node* LibraryCallKit::generate_negative_guard(Node* index, RegionNode* region) { -+inline Node* LibraryCallKit::generate_negative_guard(Node* index, RegionNode* region, -+ Node* *pos_index) { - if (stopped()) - return NULL; // already stopped - if (_gvn.type(index)->higher_equal(TypeInt::POS)) // [0,maxint] -@@ -676,10 +700,17 @@ - Node* cmp_lt = _gvn.transform( new (C, 3) CmpINode(index, intcon(0)) ); - Node* bol_lt = _gvn.transform( new (C, 2) BoolNode(cmp_lt, BoolTest::lt) ); - Node* is_neg = generate_guard(bol_lt, region, PROB_MIN); -+ if (is_neg != NULL && pos_index != NULL) { -+ // Emulate effect of Parse::adjust_map_after_if. -+ Node* ccast = new (C, 2) CastIINode(index, TypeInt::POS); -+ ccast->set_req(0, control()); -+ (*pos_index) = _gvn.transform(ccast); -+ } - return is_neg; - } - --inline Node* LibraryCallKit::generate_nonpositive_guard(Node* index, bool never_negative) { -+inline Node* LibraryCallKit::generate_nonpositive_guard(Node* index, bool never_negative, -+ Node* *pos_index) { - if (stopped()) - return NULL; // already stopped - if (_gvn.type(index)->higher_equal(TypeInt::POS1)) // [1,maxint] -@@ -688,6 +719,12 @@ - BoolTest::mask le_or_eq = (never_negative ? BoolTest::eq : BoolTest::le); - Node* bol_le = _gvn.transform( new (C, 2) BoolNode(cmp_le, le_or_eq) ); - Node* is_notp = generate_guard(bol_le, NULL, PROB_MIN); -+ if (is_notp != NULL && pos_index != NULL) { -+ // Emulate effect of Parse::adjust_map_after_if. -+ Node* ccast = new (C, 2) CastIINode(index, TypeInt::POS1); -+ ccast->set_req(0, control()); -+ (*pos_index) = _gvn.transform(ccast); -+ } - return is_notp; - } - -@@ -711,10 +748,12 @@ - RegionNode* region) { - if (stopped()) - return NULL; // already stopped -- if (_gvn.type(offset) == TypeInt::ZERO && -- _gvn.eqv_uncast(subseq_length, array_length)) -+ bool zero_offset = _gvn.type(offset) == TypeInt::ZERO; -+ if (zero_offset && _gvn.eqv_uncast(subseq_length, array_length)) - return NULL; // common case of whole-array copy -- Node* last = _gvn.transform( new (C, 3) AddINode(offset, subseq_length)); -+ Node* last = subseq_length; -+ if (!zero_offset) // last += offset -+ last = _gvn.transform( new (C, 3) AddINode(last, offset)); - Node* cmp_lt = _gvn.transform( new (C, 3) CmpUNode(array_length, last) ); - Node* bol_lt = _gvn.transform( new (C, 2) BoolNode(cmp_lt, BoolTest::lt) ); - Node* is_over = generate_guard(bol_lt, region, PROB_MIN); -@@ -862,7 +901,7 @@ - const TypeAry* target_array_type = TypeAry::make(TypeInt::CHAR, TypeInt::make(0, target_length, Type::WidenMin)); - const TypeAryPtr* target_type = TypeAryPtr::make(TypePtr::BotPTR, target_array_type, target_array->klass(), true, Type::OffsetBot); - -- IdealKit kit(gvn(), control()); -+ IdealKit kit(gvn(), control(), merged_memory()); - #define __ kit. - Node* zero = __ ConI(0); - Node* one = __ ConI(1); -@@ -1582,6 +1621,8 @@ - - // Use a flow-free graph structure, to avoid creating excess control edges - // which could hinder other optimizations. -+ // Since Math.min/max is often used with arraycopy, we want -+ // tightly_coupled_allocation to be able to see beyond min/max expressions. - Node* cmov = CMoveNode::make(C, NULL, best_bol, - answer_if_false, answer_if_true, - TypeInt::make(lo, hi, widen)); -@@ -1732,6 +1773,7 @@ - Node* val; - debug_only(val = (Node*)(uintptr_t)-1); - -+ - if (is_store) { - // Get the value being stored. (Pop it first; it was pushed last.) - switch (type) { -@@ -1901,40 +1943,28 @@ - val = _gvn.transform( new (C, 2) CastX2PNode(val) ); - break; - } -- Node* store = store_to_memory(control(), adr, val, type, adr_type, is_volatile); - -- if (type == T_OBJECT -- && !_gvn.type(heap_base_oop)->higher_equal(TypePtr::NULL_PTR)) { -- if (!TypePtr::NULL_PTR->higher_equal(_gvn.type(heap_base_oop))) { -- store_barrier(store, T_CONFLICT, heap_base_oop, adr, val); -+ if (type != T_OBJECT ) { -+ (void) store_to_memory(control(), adr, val, type, adr_type, is_volatile); - } else { -- // Base pointer may or may not be null, so put out a conditional -- // store barrier. (Yech.) -- Node* oldctl = control(); -- Node* cmp = _gvn.transform( new (C, 3) CmpPNode(heap_base_oop, null()) ); -- Node* bol = _gvn.transform( new (C, 2) BoolNode(cmp, BoolTest::ne) ); -- IfNode* iff = create_and_map_if(oldctl, bol, PROB_MAX, COUNT_UNKNOWN); -- enum { -- heap_store_path = 1, -- null_base_path, -- num_paths -- }; -- RegionNode* rgn = new (C, num_paths) RegionNode(num_paths); -- // fall-through path (base is null, offset is memory address) -- rgn->init_req(null_base_path, _gvn.transform( new (C, 1) IfFalseNode(iff) )); -- Node* newrawmem = PhiNode::make(rgn, memory(Compile::AliasIdxRaw)); -- set_control(_gvn.transform( new (C, 1) IfTrueNode(iff) )); -- store_barrier(store, T_CONFLICT, heap_base_oop, adr, val); -- if (memory(Compile::AliasIdxRaw) == newrawmem->in(null_base_path)) { -- // The store barrier did nothing, after all. -- set_control(oldctl); -+ // Possibly an oop being stored to Java heap or native memory -+ if (!TypePtr::NULL_PTR->higher_equal(_gvn.type(heap_base_oop))) { -+ // oop to Java heap. -+ (void) store_oop_to_unknown(control(), heap_base_oop, adr, adr_type, val, val->bottom_type(), type); - } else { -- // Finish heap_store_path: -- rgn->init_req(heap_store_path, control()); -- set_control(_gvn.transform(rgn)); -- newrawmem->init_req(heap_store_path, memory(Compile::AliasIdxRaw)); -- set_memory(_gvn.transform(newrawmem), Compile::AliasIdxRaw); -- } -+ -+ // We can't tell at compile time if we are storing in the Java heap or outside -+ // of it. So we need to emit code to conditionally do the proper type of -+ // store. -+ -+ IdealKit kit(gvn(), control(), merged_memory()); -+ kit.declares_done(); -+ // QQQ who knows what probability is here?? -+ kit.if_then(heap_base_oop, BoolTest::ne, null(), PROB_UNLIKELY(0.999)); { -+ (void) store_oop_to_unknown(control(), heap_base_oop, adr, adr_type, val, val->bottom_type(), type); -+ } kit.else_(); { -+ (void) store_to_memory(control(), adr, val, type, adr_type, is_volatile); -+ } kit.end_if(); - } - } - } -@@ -2004,11 +2034,12 @@ - adr = make_unsafe_address(NULL, ptr); - } - -+ if (is_static) { - assert(saved_sp == _sp, "must have correct argument count"); -- -- if (!is_static) { -+ } else { - // Pop receiver last: it was pushed first. - Node *receiver = pop(); -+ assert(saved_sp == _sp, "must have correct argument count"); - - // Null check on self without removing any arguments. The argument - // null check technically happens in the wrong place, which can lead to -@@ -2133,10 +2164,11 @@ - cas = _gvn.transform(new (C, 5) CompareAndSwapLNode(control(), mem, adr, newval, oldval)); - break; - case T_OBJECT: -- cas = _gvn.transform(new (C, 5) CompareAndSwapPNode(control(), mem, adr, newval, oldval)); - // reference stores need a store barrier. - // (They don't if CAS fails, but it isn't worth checking.) -- store_barrier(cas, T_CONFLICT, base, adr, newval); -+ pre_barrier(control(), base, adr, alias_idx, newval, value_type, T_OBJECT); -+ cas = _gvn.transform(new (C, 5) CompareAndSwapPNode(control(), mem, adr, newval, oldval)); -+ post_barrier(control(), cas, base, adr, alias_idx, newval, T_OBJECT, true); - break; - default: - ShouldNotReachHere(); -@@ -2217,11 +2249,13 @@ - insert_mem_bar(Op_MemBarCPUOrder); - // Ensure that the store is atomic for longs: - bool require_atomic_access = true; -- Node* store = store_to_memory(control(), adr, val, type, adr_type, require_atomic_access); -+ Node* store; - if (type == T_OBJECT) // reference stores need a store barrier. -- store_barrier(store, T_CONFLICT, base, adr, val); -+ store = store_oop_to_unknown(control(), base, adr, adr_type, val, value_type, type); -+ else { -+ store = store_to_memory(control(), adr, val, type, adr_type, require_atomic_access); -+ } - insert_mem_bar(Op_MemBarCPUOrder); -- - return true; - } - -@@ -2931,8 +2965,8 @@ - } - - // Bail out if either start or end is negative. -- generate_negative_guard(start, bailout); -- generate_negative_guard(end, bailout); -+ generate_negative_guard(start, bailout, &start); -+ generate_negative_guard(end, bailout, &end); - - Node* length = end; - if (_gvn.type(start) != TypeInt::ZERO) { -@@ -2940,7 +2974,8 @@ - } - - // Bail out if length is negative. -- generate_negative_guard(length, bailout); -+ // ...Not needed, since the new_array will throw the right exception. -+ //generate_negative_guard(length, bailout, &length); - - if (bailout->req() > 1) { - PreserveJVMState pjvms(this); -@@ -3666,8 +3701,15 @@ - assert(obj_size != NULL, ""); - Node* raw_obj = alloc_obj->in(1); - assert(raw_obj->is_Proj() && raw_obj->in(0)->is_Allocate(), ""); -+ if (ReduceBulkZeroing) { -+ AllocateNode* alloc = AllocateNode::Ideal_allocation(alloc_obj, &_gvn); -+ if (alloc != NULL) { -+ // We will be completely responsible for initializing this object. -+ alloc->maybe_set_complete(&_gvn); -+ } -+ } - -- if (true) { // TO DO: check ReduceInitialCardMarks -+ if (!use_ReduceInitialCardMarks()) { - // If it is an oop array, it requires very special treatment, - // because card marking is required on each card of the array. - Node* is_obja = generate_objArray_guard(obj_klass, (RegionNode*)NULL); -@@ -3687,6 +3729,11 @@ - result_mem ->set_req(_objArray_path, reset_memory()); - } - } -+ // We can dispense with card marks if we know the allocation -+ // comes out of eden (TLAB)... In fact, ReduceInitialCardMarks -+ // causes the non-eden paths to simulate a fresh allocation, -+ // insofar that no further card marks are required to initialize -+ // the object. - - // Otherwise, there are no card marks to worry about. - alloc_val->init_req(_typeArray_alloc, raw_obj); -@@ -3731,7 +3778,12 @@ - assert(obj_size != NULL, ""); - Node* raw_obj = alloc_obj->in(1); - assert(raw_obj->is_Proj() && raw_obj->in(0)->is_Allocate(), ""); -- if (true) { // TO DO: check ReduceInitialCardMarks -+ if (ReduceBulkZeroing) { -+ AllocateNode* alloc = AllocateNode::Ideal_allocation(alloc_obj, &_gvn); -+ if (alloc != NULL && !alloc->maybe_set_complete(&_gvn)) -+ alloc = NULL; -+ } -+ if (!use_ReduceInitialCardMarks()) { - // Put in store barrier for any and all oops we are sticking - // into this object. (We could avoid this if we could prove - // that the object type contains no oop fields at all.) -@@ -3786,10 +3838,14 @@ - // The CopyArray instruction (if supported) can be optimized - // into a discrete set of scalar loads and stores. - bool disjoint_bases = true; -- generate_unchecked_arraycopy(T_LONG, raw_adr_type, disjoint_bases, -+ generate_unchecked_arraycopy(raw_adr_type, T_LONG, disjoint_bases, - src, NULL, dest, NULL, countx); - - // Now that the object is properly initialized, type it as an oop. -+ // Use a secondary InitializeNode memory barrier. -+ InitializeNode* init = insert_mem_bar_volatile(Op_Initialize, raw_adr_idx, -+ raw_obj)->as_Initialize(); -+ init->set_complete(&_gvn); // (there is no corresponding AllocateNode) - Node* new_obj = new(C, 2) CheckCastPPNode(control(), raw_obj, - TypeInstPtr::NOTNULL); - new_obj = _gvn.transform(new_obj); -@@ -3798,8 +3854,14 @@ - if (card_mark) { - Node* no_particular_value = NULL; - Node* no_particular_field = NULL; -- store_barrier(memory(raw_adr_type), T_OBJECT, new_obj, -- no_particular_field, no_particular_value); -+ post_barrier(control(), -+ memory(raw_adr_type), -+ new_obj, -+ no_particular_field, -+ raw_adr_idx, -+ no_particular_value, -+ T_OBJECT, -+ false); - } - // Present the results of the slow call. - result_reg->init_req(_fast_path, control()); -@@ -4085,13 +4147,59 @@ - int nargs, - bool disjoint_bases, - bool length_never_negative, -- Node* slow_control) { -+ RegionNode* slow_region) { -+ -+ if (slow_region == NULL) { -+ slow_region = new(C,1) RegionNode(1); -+ record_for_igvn(slow_region); -+ } -+ -+ Node* original_dest = dest; -+ AllocateArrayNode* alloc = NULL; // used for zeroing, if needed -+ Node* raw_dest = NULL; // used before zeroing, if needed -+ bool must_clear_dest = false; -+ -+ // See if this is the initialization of a newly-allocated array. -+ // If so, we will take responsibility here for initializing it to zero. -+ // (Note: Because tightly_coupled_allocation performs checks on the -+ // out-edges of the dest, we need to avoid making derived pointers -+ // from it until we have checked its uses.) -+ if (ReduceBulkZeroing -+ && !ZeroTLAB // pointless if already zeroed -+ && basic_elem_type != T_CONFLICT // avoid corner case -+ && !_gvn.eqv_uncast(src, dest) -+ && ((alloc = tightly_coupled_allocation(dest, slow_region)) -+ != NULL) -+ && alloc->maybe_set_complete(&_gvn)) { -+ // "You break it, you buy it." -+ InitializeNode* init = alloc->initialization(); -+ assert(init->is_complete(), "we just did this"); -+ assert(dest->Opcode() == Op_CheckCastPP, "sanity"); -+ assert(dest->in(0)->in(0) == init, "dest pinned"); -+ raw_dest = dest->in(1); // grab the raw pointer! -+ original_dest = dest; -+ dest = raw_dest; -+ adr_type = TypeRawPtr::BOTTOM; // all initializations are into raw memory -+ // Decouple the original InitializeNode, turning it into a simple membar. -+ // We will build a new one at the end of this routine. -+ init->set_req(InitializeNode::RawAddress, top()); -+ // From this point on, every exit path is responsible for -+ // initializing any non-copied parts of the object to zero. -+ must_clear_dest = true; -+ } else { -+ // No zeroing elimination here. -+ alloc = NULL; -+ //original_dest = dest; -+ //must_clear_dest = false; -+ } -+ - // Results are placed here: -- enum { fast_path = 1, -- checked_path = 2, -- slow_call_path = 3, -- zero_path = 4, -- PATH_LIMIT = 5 -+ enum { fast_path = 1, // normal void-returning assembly stub -+ checked_path = 2, // special assembly stub with cleanup -+ slow_call_path = 3, // something went wrong; call the VM -+ zero_path = 4, // bypass when length of copy is zero -+ bcopy_path = 5, // copy primitive array by 64-bit blocks -+ PATH_LIMIT = 6 - }; - RegionNode* result_region = new(C, PATH_LIMIT) RegionNode(PATH_LIMIT); - PhiNode* result_i_o = new(C, PATH_LIMIT) PhiNode(result_region, Type::ABIO); -@@ -4099,10 +4207,13 @@ - record_for_igvn(result_region); - _gvn.set_type_bottom(result_i_o); - _gvn.set_type_bottom(result_memory); -+ assert(adr_type != TypePtr::BOTTOM, "must be RawMem or a T[] slice"); - -- // Other parts of the slow_control edge: -+ // The slow_control path: -+ Node* slow_control; - Node* slow_i_o = i_o(); - Node* slow_mem = memory(adr_type); -+ debug_only(slow_control = (Node*) badAddress); - - // Checked control path: - Node* checked_control = top(); -@@ -4111,43 +4222,123 @@ - Node* checked_value = NULL; - - if (basic_elem_type == T_CONFLICT) { -- { PreserveJVMState pjvms(this); -+ assert(!must_clear_dest, ""); - Node* cv = generate_generic_arraycopy(adr_type, - src, src_offset, dest, dest_offset, - copy_length, nargs); - if (cv == NULL) cv = intcon(-1); // failure (no stub available) - checked_control = control(); - checked_i_o = i_o(); -- checked_mem = reset_memory(); -+ checked_mem = memory(adr_type); - checked_value = cv; -- } - set_control(top()); // no fast path - } - - Node* not_pos = generate_nonpositive_guard(copy_length, length_never_negative); - if (not_pos != NULL) { -- Node* fast_ctrl = control(); -- -+ PreserveJVMState pjvms(this); - set_control(not_pos); -+ - // (6) length must not be negative. - if (!length_never_negative) { -- if (slow_control == NULL) { -- slow_control = new(C,1) RegionNode(1); -- record_for_igvn(slow_control); -+ generate_negative_guard(copy_length, slow_region); -+ } -+ -+ if (!stopped() && must_clear_dest) { -+ Node* dest_length = alloc->in(AllocateNode::ALength); -+ if (_gvn.eqv_uncast(copy_length, dest_length) -+ || _gvn.find_int_con(dest_length, 1) <= 0) { -+ // There is no zeroing to do. -+ } else { -+ // Clear the whole thing since there are no source elements to copy. -+ generate_clear_array(adr_type, dest, basic_elem_type, -+ intcon(0), NULL, -+ alloc->in(AllocateNode::AllocSize)); - } -- generate_negative_guard(copy_length, slow_control->as_Region()); - } - - // Present the results of the fast call. - result_region->init_req(zero_path, control()); - result_i_o ->init_req(zero_path, i_o()); - result_memory->init_req(zero_path, memory(adr_type)); -+ } - -- set_control(fast_ctrl); -+ if (!stopped() && must_clear_dest) { -+ // We have to initialize the *uncopied* part of the array to zero. -+ // The copy destination is the slice dest[off..off+len]. The other slices -+ // are dest_head = dest[0..off] and dest_tail = dest[off+len..dest.length]. -+ Node* dest_size = alloc->in(AllocateNode::AllocSize); -+ Node* dest_length = alloc->in(AllocateNode::ALength); -+ Node* dest_tail = _gvn.transform( new(C,3) AddINode(dest_offset, -+ copy_length) ); -+ -+ // If there is a head section that needs zeroing, do it now. -+ if (find_int_con(dest_offset, -1) != 0) { -+ generate_clear_array(adr_type, dest, basic_elem_type, -+ intcon(0), dest_offset, -+ NULL); -+ } -+ -+ // Next, perform a dynamic check on the tail length. -+ // It is often zero, and we can win big if we prove this. -+ // There are two wins: Avoid generating the ClearArray -+ // with its attendant messy index arithmetic, and upgrade -+ // the copy to a more hardware-friendly word size of 64 bits. -+ Node* tail_ctl = NULL; -+ if (!stopped() && !_gvn.eqv_uncast(dest_tail, dest_length)) { -+ Node* cmp_lt = _gvn.transform( new(C,3) CmpINode(dest_tail, dest_length) ); -+ Node* bol_lt = _gvn.transform( new(C,2) BoolNode(cmp_lt, BoolTest::lt) ); -+ tail_ctl = generate_slow_guard(bol_lt, NULL); -+ assert(tail_ctl != NULL || !stopped(), "must be an outcome"); -+ } -+ -+ // At this point, let's assume there is no tail. -+ if (!stopped() && alloc != NULL && basic_elem_type != T_OBJECT) { -+ // There is no tail. Try an upgrade to a 64-bit copy. -+ bool didit = false; -+ { PreserveJVMState pjvms(this); -+ didit = generate_block_arraycopy(adr_type, basic_elem_type, alloc, -+ src, src_offset, dest, dest_offset, -+ dest_size); -+ if (didit) { -+ // Present the results of the block-copying fast call. -+ result_region->init_req(bcopy_path, control()); -+ result_i_o ->init_req(bcopy_path, i_o()); -+ result_memory->init_req(bcopy_path, memory(adr_type)); -+ } -+ } -+ if (didit) -+ set_control(top()); // no regular fast path -+ } -+ -+ // Clear the tail, if any. -+ if (tail_ctl != NULL) { -+ Node* notail_ctl = stopped() ? NULL : control(); -+ set_control(tail_ctl); -+ if (notail_ctl == NULL) { -+ generate_clear_array(adr_type, dest, basic_elem_type, -+ dest_tail, NULL, -+ dest_size); -+ } else { -+ // Make a local merge. -+ Node* done_ctl = new(C,3) RegionNode(3); -+ Node* done_mem = new(C,3) PhiNode(done_ctl, Type::MEMORY, adr_type); -+ done_ctl->init_req(1, notail_ctl); -+ done_mem->init_req(1, memory(adr_type)); -+ generate_clear_array(adr_type, dest, basic_elem_type, -+ dest_tail, NULL, -+ dest_size); -+ done_ctl->init_req(2, control()); -+ done_mem->init_req(2, memory(adr_type)); -+ set_control( _gvn.transform(done_ctl) ); -+ set_memory( _gvn.transform(done_mem), adr_type ); -+ } -+ } - } - -+ BasicType copy_type = basic_elem_type; - assert(basic_elem_type != T_ARRAY, "caller must fix this"); -- if (basic_elem_type == T_OBJECT) { -+ if (!stopped() && copy_type == T_OBJECT) { - // If src and dest have compatible element types, we can copy bits. - // Types S[] and D[] are compatible if D is a supertype of S. - // -@@ -4189,17 +4380,24 @@ - if (cv == NULL) cv = intcon(-1); // failure (no stub available) - checked_control = control(); - checked_i_o = i_o(); -- checked_mem = reset_memory(); -+ checked_mem = memory(adr_type); - checked_value = cv; - } - // At this point we know we do not need type checks on oop stores. -+ -+ // Let's see if we need card marks: -+ if (alloc != NULL && use_ReduceInitialCardMarks()) { -+ // If we do not need card marks, copy using the jint or jlong stub. -+ copy_type = LP64_ONLY(T_LONG) NOT_LP64(T_INT); -+ assert(type2aelembytes[basic_elem_type] == type2aelembytes[copy_type], -+ "sizes agree"); -+ } - } - - if (!stopped()) { - // Generate the fast path, if possible. - PreserveJVMState pjvms(this); -- -- generate_unchecked_arraycopy(basic_elem_type, adr_type, disjoint_bases, -+ generate_unchecked_arraycopy(adr_type, copy_type, disjoint_bases, - src, src_offset, dest, dest_offset, - ConvI2X(copy_length)); - -@@ -4210,8 +4408,10 @@ - } - - // Here are all the slow paths up to this point, in one bundle: -- if (slow_control == NULL) slow_control = top(); -- slow_control = _gvn.transform(slow_control); -+ slow_control = top(); -+ if (slow_region != NULL) -+ slow_control = _gvn.transform(slow_region); -+ debug_only(slow_region = (RegionNode*)badAddress); - - set_control(checked_control); - if (!stopped()) { -@@ -4241,16 +4441,21 @@ - slow_i_o2 ->init_req(2, i_o()); - slow_mem2 ->init_req(2, memory(adr_type)); - -+ slow_control = _gvn.transform(slow_reg2); -+ slow_i_o = _gvn.transform(slow_i_o2); -+ slow_mem = _gvn.transform(slow_mem2); -+ -+ if (alloc != NULL) { -+ // We'll restart from the very beginning, after zeroing the whole thing. -+ // This can cause double writes, but that's OK since dest is brand new. -+ // So we ignore the low 31 bits of the value returned from the stub. -+ } else { - // We must continue the copy exactly where it failed, or else - // another thread might see the wrong number of writes to dest. - Node* checked_offset = _gvn.transform( new(C, 3) XorINode(checked_value, intcon(-1)) ); - Node* slow_offset = new(C, 3) PhiNode(slow_reg2, TypeInt::INT); - slow_offset->init_req(1, intcon(0)); - slow_offset->init_req(2, checked_offset); -- -- slow_control = _gvn.transform(slow_reg2); -- slow_i_o = _gvn.transform(slow_i_o2); -- slow_mem = _gvn.transform(slow_mem2); - slow_offset = _gvn.transform(slow_offset); - - // Adjust the arguments by the conditionally incoming offset. -@@ -4263,11 +4468,33 @@ - dest_offset = dest_off_plus; - copy_length = length_minus; - } -+ } - - set_control(slow_control); - if (!stopped()) { - // Generate the slow path, if needed. -- PreserveJVMState pjvms(this); // (better safe than sorry) -+ PreserveJVMState pjvms(this); // replace_in_map may trash the map -+ -+ set_memory(slow_mem, adr_type); -+ set_i_o(slow_i_o); -+ -+ if (must_clear_dest) { -+ generate_clear_array(adr_type, dest, basic_elem_type, -+ intcon(0), NULL, -+ alloc->in(AllocateNode::AllocSize)); -+ } -+ -+ if (dest != original_dest) { -+ // Promote from rawptr to oop, so it looks right in the call's GC map. -+ dest = _gvn.transform( new(C,2) CheckCastPPNode(control(), dest, -+ TypeInstPtr::NOTNULL) ); -+ -+ // Edit the call's debug-info to avoid referring to original_dest. -+ // (The problem with original_dest is that it isn't ready until -+ // after the InitializeNode completes, but this stuff is before.) -+ // Substitute in the locally valid dest_oop. -+ replace_in_map(original_dest, dest); -+ } - - generate_slow_arraycopy(adr_type, - src, src_offset, dest, dest_offset, -@@ -4289,6 +4516,18 @@ - set_i_o( _gvn.transform(result_i_o) ); - set_memory( _gvn.transform(result_memory), adr_type ); - -+ if (dest != original_dest) { -+ // Pin the "finished" array node after the arraycopy/zeroing operations. -+ // Use a secondary InitializeNode memory barrier. -+ InitializeNode* init = insert_mem_bar_volatile(Op_Initialize, -+ Compile::AliasIdxRaw, -+ raw_dest)->as_Initialize(); -+ init->set_complete(&_gvn); // (there is no corresponding AllocateNode) -+ _gvn.hash_delete(original_dest); -+ original_dest->set_req(0, control()); -+ _gvn.hash_find_insert(original_dest); // put back into GVN table -+ } -+ - // The memory edges above are precise in order to model effects around - // array copyies accurately to allow value numbering of field loads around - // arraycopy. Such field loads, both before and after, are common in Java -@@ -4304,6 +4543,265 @@ - } - - -+// Helper function which determines if an arraycopy immediately follows -+// an allocation, with no intervening tests or other escapes for the object. -+AllocateArrayNode* -+LibraryCallKit::tightly_coupled_allocation(Node* ptr, -+ RegionNode* slow_region) { -+ if (stopped()) return NULL; // no fast path -+ if (C->AliasLevel() == 0) return NULL; // no MergeMems around -+ -+ AllocateArrayNode* alloc = AllocateArrayNode::Ideal_array_allocation(ptr, &_gvn); -+ if (alloc == NULL) return NULL; -+ -+ Node* rawmem = memory(Compile::AliasIdxRaw); -+ // Is the allocation's memory state untouched? -+ if (!(rawmem->is_Proj() && rawmem->in(0)->is_Initialize())) { -+ // Bail out if there have been raw-memory effects since the allocation. -+ // (Example: There might have been a call or safepoint.) -+ return NULL; -+ } -+ rawmem = rawmem->in(0)->as_Initialize()->memory(Compile::AliasIdxRaw); -+ if (!(rawmem->is_Proj() && rawmem->in(0) == alloc)) { -+ return NULL; -+ } -+ -+ // There must be no unexpected observers of this allocation. -+ for (DUIterator_Fast imax, i = ptr->fast_outs(imax); i < imax; i++) { -+ Node* obs = ptr->fast_out(i); -+ if (obs != this->map()) { -+ return NULL; -+ } -+ } -+ -+ // This arraycopy must unconditionally follow the allocation of the ptr. -+ Node* alloc_ctl = ptr->in(0); -+ assert(just_allocated_object(alloc_ctl) == ptr, "most recent allo"); -+ -+ Node* ctl = control(); -+ while (ctl != alloc_ctl) { -+ // There may be guards which feed into the slow_region. -+ // Any other control flow means that we might not get a chance -+ // to finish initializing the allocated object. -+ if ((ctl->is_IfFalse() || ctl->is_IfTrue()) && ctl->in(0)->is_If()) { -+ IfNode* iff = ctl->in(0)->as_If(); -+ Node* not_ctl = iff->proj_out(1 - ctl->as_Proj()->_con); -+ assert(not_ctl != NULL && not_ctl != ctl, "found alternate"); -+ if (slow_region != NULL && slow_region->find_edge(not_ctl) >= 1) { -+ ctl = iff->in(0); // This test feeds the known slow_region. -+ continue; -+ } -+ // One more try: Various low-level checks bottom out in -+ // uncommon traps. If the debug-info of the trap omits -+ // any reference to the allocation, as we've already -+ // observed, then there can be no objection to the trap. -+ bool found_trap = false; -+ for (DUIterator_Fast jmax, j = not_ctl->fast_outs(jmax); j < jmax; j++) { -+ Node* obs = not_ctl->fast_out(j); -+ if (obs->in(0) == not_ctl && obs->is_Call() && -+ (obs->as_Call()->entry_point() == -+ SharedRuntime::uncommon_trap_blob()->instructions_begin())) { -+ found_trap = true; break; -+ } -+ } -+ if (found_trap) { -+ ctl = iff->in(0); // This test feeds a harmless uncommon trap. -+ continue; -+ } -+ } -+ return NULL; -+ } -+ -+ // If we get this far, we have an allocation which immediately -+ // precedes the arraycopy, and we can take over zeroing the new object. -+ // The arraycopy will finish the initialization, and provide -+ // a new control state to which we will anchor the destination pointer. -+ -+ return alloc; -+} -+ -+// Helper for initialization of arrays, creating a ClearArray. -+// It writes zero bits in [start..end), within the body of an array object. -+// The memory effects are all chained onto the 'adr_type' alias category. -+// -+// Since the object is otherwise uninitialized, we are free -+// to put a little "slop" around the edges of the cleared area, -+// as long as it does not go back into the array's header, -+// or beyond the array end within the heap. -+// -+// The lower edge can be rounded down to the nearest jint and the -+// upper edge can be rounded up to the nearest MinObjAlignmentInBytes. -+// -+// Arguments: -+// adr_type memory slice where writes are generated -+// dest oop of the destination array -+// basic_elem_type element type of the destination -+// slice_idx array index of first element to store -+// slice_len number of elements to store (or NULL) -+// dest_size total size in bytes of the array object -+// -+// Exactly one of slice_len or dest_size must be non-NULL. -+// If dest_size is non-NULL, zeroing extends to the end of the object. -+// If slice_len is non-NULL, the slice_idx value must be a constant. -+void -+LibraryCallKit::generate_clear_array(const TypePtr* adr_type, -+ Node* dest, -+ BasicType basic_elem_type, -+ Node* slice_idx, -+ Node* slice_len, -+ Node* dest_size) { -+ // one or the other but not both of slice_len and dest_size: -+ assert((slice_len != NULL? 1: 0) + (dest_size != NULL? 1: 0) == 1, ""); -+ if (slice_len == NULL) slice_len = top(); -+ if (dest_size == NULL) dest_size = top(); -+ -+ // operate on this memory slice: -+ Node* mem = memory(adr_type); // memory slice to operate on -+ -+ // scaling and rounding of indexes: -+ int scale = exact_log2(type2aelembytes[basic_elem_type]); -+ int abase = arrayOopDesc::base_offset_in_bytes(basic_elem_type); -+ int clear_low = (-1 << scale) & (BytesPerInt - 1); -+ int bump_bit = (-1 << scale) & BytesPerInt; -+ -+ // determine constant starts and ends -+ const intptr_t BIG_NEG = -128; -+ assert(BIG_NEG + 2*abase < 0, "neg enough"); -+ intptr_t slice_idx_con = (intptr_t) find_int_con(slice_idx, BIG_NEG); -+ intptr_t slice_len_con = (intptr_t) find_int_con(slice_len, BIG_NEG); -+ if (slice_len_con == 0) { -+ return; // nothing to do here -+ } -+ intptr_t start_con = (abase + (slice_idx_con << scale)) & ~clear_low; -+ intptr_t end_con = find_intptr_t_con(dest_size, -1); -+ if (slice_idx_con >= 0 && slice_len_con >= 0) { -+ assert(end_con < 0, "not two cons"); -+ end_con = round_to(abase + ((slice_idx_con + slice_len_con) << scale), -+ BytesPerLong); -+ } -+ -+ if (start_con >= 0 && end_con >= 0) { -+ // Constant start and end. Simple. -+ mem = ClearArrayNode::clear_memory(control(), mem, dest, -+ start_con, end_con, &_gvn); -+ } else if (start_con >= 0 && dest_size != top()) { -+ // Constant start, pre-rounded end after the tail of the array. -+ Node* end = dest_size; -+ mem = ClearArrayNode::clear_memory(control(), mem, dest, -+ start_con, end, &_gvn); -+ } else if (start_con >= 0 && slice_len != top()) { -+ // Constant start, non-constant end. End needs rounding up. -+ // End offset = round_up(abase + ((slice_idx_con + slice_len) << scale), 8) -+ intptr_t end_base = abase + (slice_idx_con << scale); -+ int end_round = (-1 << scale) & (BytesPerLong - 1); -+ Node* end = ConvI2X(slice_len); -+ if (scale != 0) -+ end = _gvn.transform( new(C,3) LShiftXNode(end, intcon(scale) )); -+ end_base += end_round; -+ end = _gvn.transform( new(C,3) AddXNode(end, MakeConX(end_base)) ); -+ end = _gvn.transform( new(C,3) AndXNode(end, MakeConX(~end_round)) ); -+ mem = ClearArrayNode::clear_memory(control(), mem, dest, -+ start_con, end, &_gvn); -+ } else if (start_con < 0 && dest_size != top()) { -+ // Non-constant start, pre-rounded end after the tail of the array. -+ // This is almost certainly a "round-to-end" operation. -+ Node* start = slice_idx; -+ start = ConvI2X(start); -+ if (scale != 0) -+ start = _gvn.transform( new(C,3) LShiftXNode( start, intcon(scale) )); -+ start = _gvn.transform( new(C,3) AddXNode(start, MakeConX(abase)) ); -+ if ((bump_bit | clear_low) != 0) { -+ int to_clear = (bump_bit | clear_low); -+ // Align up mod 8, then store a jint zero unconditionally -+ // just before the mod-8 boundary. -+ // This would only fail if the first array element were immediately -+ // after the length field, and were also at an even offset mod 8. -+ assert(((abase + bump_bit) & ~to_clear) - BytesPerInt -+ >= arrayOopDesc::length_offset_in_bytes() + BytesPerInt, -+ "store must not trash length field"); -+ -+ // Bump 'start' up to (or past) the next jint boundary: -+ start = _gvn.transform( new(C,3) AddXNode(start, MakeConX(bump_bit)) ); -+ // Round bumped 'start' down to jlong boundary in body of array. -+ start = _gvn.transform( new(C,3) AndXNode(start, MakeConX(~to_clear)) ); -+ // Store a zero to the immediately preceding jint: -+ Node* x1 = _gvn.transform( new(C,3) AddXNode(start, MakeConX(-BytesPerInt)) ); -+ Node* p1 = basic_plus_adr(dest, x1); -+ mem = StoreNode::make(C, control(), mem, p1, adr_type, intcon(0), T_INT); -+ mem = _gvn.transform(mem); -+ } -+ -+ Node* end = dest_size; // pre-rounded -+ mem = ClearArrayNode::clear_memory(control(), mem, dest, -+ start, end, &_gvn); -+ } else { -+ // Non-constant start, unrounded non-constant end. -+ // (Nobody zeroes a random midsection of an array using this routine.) -+ ShouldNotReachHere(); // fix caller -+ } -+ -+ // Done. -+ set_memory(mem, adr_type); -+} -+ -+ -+bool -+LibraryCallKit::generate_block_arraycopy(const TypePtr* adr_type, -+ BasicType basic_elem_type, -+ AllocateNode* alloc, -+ Node* src, Node* src_offset, -+ Node* dest, Node* dest_offset, -+ Node* dest_size) { -+ // See if there is an advantage from block transfer. -+ int scale = exact_log2(type2aelembytes[basic_elem_type]); -+ if (scale >= LogBytesPerLong) -+ return false; // it is already a block transfer -+ -+ // Look at the alignment of the starting offsets. -+ int abase = arrayOopDesc::base_offset_in_bytes(basic_elem_type); -+ const intptr_t BIG_NEG = -128; -+ assert(BIG_NEG + 2*abase < 0, "neg enough"); -+ -+ intptr_t src_off = abase + ((intptr_t) find_int_con(src_offset, -1) << scale); -+ intptr_t dest_off = abase + ((intptr_t) find_int_con(dest_offset, -1) << scale); -+ if (src_off < 0 || dest_off < 0) -+ // At present, we can only understand constants. -+ return false; -+ -+ if (((src_off | dest_off) & (BytesPerLong-1)) != 0) { -+ // Non-aligned; too bad. -+ // One more chance: Pick off an initial 32-bit word. -+ // This is a common case, since abase can be odd mod 8. -+ if (((src_off | dest_off) & (BytesPerLong-1)) == BytesPerInt && -+ ((src_off ^ dest_off) & (BytesPerLong-1)) == 0) { -+ Node* sptr = basic_plus_adr(src, src_off); -+ Node* dptr = basic_plus_adr(dest, dest_off); -+ Node* sval = make_load(control(), sptr, TypeInt::INT, T_INT, adr_type); -+ store_to_memory(control(), dptr, sval, T_INT, adr_type); -+ src_off += BytesPerInt; -+ dest_off += BytesPerInt; -+ } else { -+ return false; -+ } -+ } -+ assert(src_off % BytesPerLong == 0, ""); -+ assert(dest_off % BytesPerLong == 0, ""); -+ -+ // Do this copy by giant steps. -+ Node* sptr = basic_plus_adr(src, src_off); -+ Node* dptr = basic_plus_adr(dest, dest_off); -+ Node* countx = dest_size; -+ countx = _gvn.transform( new (C, 3) SubXNode(countx, MakeConX(dest_off)) ); -+ countx = _gvn.transform( new (C, 3) URShiftXNode(countx, intcon(LogBytesPerLong)) ); -+ -+ bool disjoint_bases = true; // since alloc != NULL -+ generate_unchecked_arraycopy(adr_type, T_LONG, disjoint_bases, -+ sptr, NULL, dptr, NULL, countx); -+ -+ return true; -+} -+ -+ - // Helper function; generates code for the slow case. - // We make a call to a runtime method which emulates the native method, - // but without the native wrapper overhead. -@@ -4391,11 +4889,10 @@ - return _gvn.transform(new (C, 1) ProjNode(call, TypeFunc::Parms)); - } - -- - // Helper function; generates the fast out-of-line call to an arraycopy stub. - void --LibraryCallKit::generate_unchecked_arraycopy(BasicType basic_elem_type, -- const TypePtr* adr_type, -+LibraryCallKit::generate_unchecked_arraycopy(const TypePtr* adr_type, -+ BasicType basic_elem_type, - bool disjoint_bases, - Node* src, Node* src_offset, - Node* dest, Node* dest_offset, -@@ -4422,4 +4919,3 @@ - copyfunc_addr, copyfunc_name, adr_type, - src_start, dest_start, copy_length XTOP); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/live.cpp openjdk/hotspot/src/share/vm/opto/live.cpp ---- openjdk6/hotspot/src/share/vm/opto/live.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/live.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)live.cpp 1.70 07/05/17 17:44:00 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/opto/live.hpp openjdk/hotspot/src/share/vm/opto/live.hpp ---- openjdk6/hotspot/src/share/vm/opto/live.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/live.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)live.hpp 1.43 07/05/05 17:06:19 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/opto/locknode.cpp openjdk/hotspot/src/share/vm/opto/locknode.cpp ---- openjdk6/hotspot/src/share/vm/opto/locknode.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/locknode.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)locknode.cpp 1.49 07/05/17 15:59:05 JVM" --#endif - /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -123,6 +120,3 @@ - // for a null check on Unlock. - shared_unlock(map()->peek_monitor_box(), map()->peek_monitor_obj()); - } -- -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/locknode.hpp openjdk/hotspot/src/share/vm/opto/locknode.hpp ---- openjdk6/hotspot/src/share/vm/opto/locknode.hpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/locknode.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)locknode.hpp 1.39 07/05/17 15:59:09 JVM" --#endif - /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -46,8 +43,8 @@ - static OptoReg::Name stack_slot(Node* box_node); - - #ifndef PRODUCT -- virtual void format( PhaseRegAlloc * ) const; -- virtual void dump_spec() const { tty->print(" Lock %d",_slot); } -+ virtual void format( PhaseRegAlloc *, outputStream *st ) const; -+ virtual void dump_spec(outputStream *st) const { st->print(" Lock %d",_slot); } - #endif - }; - -@@ -98,4 +95,3 @@ - const Type *sub(const Type *t1, const Type *t2) const { return TypeInt::CC;} - - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/loopTransform.cpp openjdk/hotspot/src/share/vm/opto/loopTransform.cpp ---- openjdk6/hotspot/src/share/vm/opto/loopTransform.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/loopTransform.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)loopTransform.cpp 1.116 07/06/01 11:35:03 JVM" --#endif - /* - * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/opto/loopUnswitch.cpp openjdk/hotspot/src/share/vm/opto/loopUnswitch.cpp ---- openjdk6/hotspot/src/share/vm/opto/loopUnswitch.cpp 2008-07-10 22:04:33.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/loopUnswitch.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)loopUnswitch.cpp 1.6 07/06/29 13:39:53 JVM" --#endif - /* - * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/opto/loopnode.cpp openjdk/hotspot/src/share/vm/opto/loopnode.cpp ---- openjdk6/hotspot/src/share/vm/opto/loopnode.cpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/loopnode.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)loopnode.cpp 1.258 07/05/17 17:44:08 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -29,13 +26,27 @@ - #include "incls/_loopnode.cpp.incl" - - //============================================================================= -+//------------------------------is_loop_iv------------------------------------- -+// Determine if a node is Counted loop induction variable. -+// The method is declared in node.hpp. -+const Node* Node::is_loop_iv() const { -+ if (this->is_Phi() && !this->as_Phi()->is_copy() && -+ this->as_Phi()->region()->is_CountedLoop() && -+ this->as_Phi()->region()->as_CountedLoop()->phi() == this) { -+ return this; -+ } else { -+ return NULL; -+ } -+} -+ -+//============================================================================= - //------------------------------dump_spec-------------------------------------- - // Dump special per-node info - #ifndef PRODUCT --void LoopNode::dump_spec() const { -- if( is_inner_loop () ) tty->print( "inner " ); -- if( is_partial_peel_loop () ) tty->print( "partial_peel " ); -- if( partial_peel_has_failed () ) tty->print( "partial_peel_failed " ); -+void LoopNode::dump_spec(outputStream *st) const { -+ if( is_inner_loop () ) st->print( "inner " ); -+ if( is_partial_peel_loop () ) st->print( "partial_peel " ); -+ if( partial_peel_has_failed () ) st->print( "partial_peel_failed " ); - } - #endif - -@@ -267,9 +278,11 @@ - // '>' for count-down loops. If the condition is inverted and we will - // be rolling through MININT to MAXINT, then bail out. - -+ C->print_method("Before CountedLoop", 3); -+ - // Check for SafePoint on backedge and remove - Node *sfpt = x->in(LoopNode::LoopBackControl); -- if( sfpt->Opcode() == Op_SafePoint ) { -+ if( sfpt->Opcode() == Op_SafePoint && is_deleteable_safept(sfpt)) { - lazy_replace( sfpt, iftrue ); - loop->_tail = iftrue; - } -@@ -460,11 +473,14 @@ - - // Check for immediately preceeding SafePoint and remove - Node *sfpt2 = le->in(0); -- if( sfpt2->Opcode() == Op_SafePoint ) -+ if( sfpt2->Opcode() == Op_SafePoint && is_deleteable_safept(sfpt2)) - lazy_replace( sfpt2, sfpt2->in(TypeFunc::Control)); - - // Free up intermediate goo - _igvn.remove_dead_node(hook); -+ -+ C->print_method("After CountedLoop", 3); -+ - // Return trip counter - return trip_count; - } -@@ -492,16 +508,16 @@ - //------------------------------dump_spec-------------------------------------- - // Dump special per-node info - #ifndef PRODUCT --void CountedLoopNode::dump_spec() const { -- LoopNode::dump_spec(); -+void CountedLoopNode::dump_spec(outputStream *st) const { -+ LoopNode::dump_spec(st); - if( stride_is_con() ) { -- tty->print("stride: %d ",stride_con()); -+ st->print("stride: %d ",stride_con()); - } else { -- tty->print("stride: not constant "); -+ st->print("stride: not constant "); - } -- if( is_pre_loop () ) tty->print("pre of N%d" , _main_idx ); -- if( is_main_loop() ) tty->print("main of N%d", _idx ); -- if( is_post_loop() ) tty->print("post of N%d", _main_idx ); -+ if( is_pre_loop () ) st->print("pre of N%d" , _main_idx ); -+ if( is_main_loop() ) st->print("main of N%d", _idx ); -+ if( is_post_loop() ) st->print("post of N%d", _main_idx ); - } - #endif - -@@ -714,16 +730,16 @@ - //------------------------------dump_spec-------------------------------------- - // Dump special per-node info - #ifndef PRODUCT --void CountedLoopEndNode::dump_spec() const { -+void CountedLoopEndNode::dump_spec(outputStream *st) const { - if( in(TestValue)->is_Bool() ) { - BoolTest bt( test_trip()); // Added this for g++. - -- tty->print("["); -- bt.dump(); -- tty->print("]"); -+ st->print("["); -+ bt.dump_on(st); -+ st->print("]"); - } -- tty->print(" "); -- IfNode::dump_spec(); -+ st->print(" "); -+ IfNode::dump_spec(st); - } - #endif - -@@ -1044,6 +1060,8 @@ - // Cache parts in locals for easy - PhaseIterGVN &igvn = phase->_igvn; - -+ phase->C->print_method("Before beautify loops", 3); -+ - igvn.hash_delete(_head); // Yank from hash before hacking edges - - // Check for multiple fall-in paths. Peel off a landing pad if need be. -@@ -1107,36 +1125,180 @@ - phase->_igvn.add_users_to_worklist(l->fast_out(i)); - } - -+ phase->C->print_method("After beautify loops", 3); -+ - // Now recursively beautify nested loops - if( _child ) result |= _child->beautify_loops( phase ); - if( _next ) result |= _next ->beautify_loops( phase ); - return result; - } - --//------------------------------check_inner_safepts---------------------------- --// Given dominators, try to find inner loops with calls that must always be --// executed (call dominates loop tail). These loops do not need a seperate --// safepoint. --void IdealLoopTree::check_inner_safepts( PhaseIdealLoop *phase ) { -- -- // No safepoints found yet? Not irreducible? -- if( !_has_sfpt && !_irreducible && -- // Inner loop, or at least a short trip count to walk the loop? -- (!_child || -- (phase->dom_depth(tail()) - phase->dom_depth(_head)) < 20 ) ) { -- // Look for a dominating call -- for (Node* n = tail(); n != _head; n = phase->idom(n)) { -- if( n->is_Call() && // Found a call on idom chain? -- n->as_Call()->guaranteed_safepoint() ) { -+//------------------------------allpaths_check_safepts---------------------------- -+// Allpaths backwards scan from loop tail, terminating each path at first safepoint -+// encountered. Helper for check_safepts. -+void IdealLoopTree::allpaths_check_safepts(VectorSet &visited, Node_List &stack) { -+ assert(stack.size() == 0, "empty stack"); -+ stack.push(_tail); -+ visited.Clear(); -+ visited.set(_tail->_idx); -+ while (stack.size() > 0) { -+ Node* n = stack.pop(); -+ if (n->is_Call() && n->as_Call()->guaranteed_safepoint()) { -+ // Terminate this path -+ } else if (n->Opcode() == Op_SafePoint) { -+ if (_phase->get_loop(n) != this) { -+ if (_required_safept == NULL) _required_safept = new Node_List(); -+ _required_safept->push(n); // save the one closest to the tail -+ } -+ // Terminate this path -+ } else { -+ uint start = n->is_Region() ? 1 : 0; -+ uint end = n->is_Region() && !n->is_Loop() ? n->req() : start + 1; -+ for (uint i = start; i < end; i++) { -+ Node* in = n->in(i); -+ assert(in->is_CFG(), "must be"); -+ if (!visited.test_set(in->_idx) && is_member(_phase->get_loop(in))) { -+ stack.push(in); -+ } -+ } -+ } -+ } -+} -+ -+//------------------------------check_safepts---------------------------- -+// Given dominators, try to find loops with calls that must always be -+// executed (call dominates loop tail). These loops do not need non-call -+// safepoints (ncsfpt). -+// -+// A complication is that a safepoint in a inner loop may be needed -+// by an outer loop. In the following, the inner loop sees it has a -+// call (block 3) on every path from the head (block 2) to the -+// backedge (arc 3->2). So it deletes the ncsfpt (non-call safepoint) -+// in block 2, _but_ this leaves the outer loop without a safepoint. -+// -+// entry 0 -+// | -+// v -+// outer 1,2 +->1 -+// | | -+// | v -+// | 2<---+ ncsfpt in 2 -+// |_/|\ | -+// | v | -+// inner 2,3 / 3 | call in 3 -+// / | | -+// v +--+ -+// exit 4 -+// -+// -+// This method creates a list (_required_safept) of ncsfpt nodes that must -+// be protected is created for each loop. When a ncsfpt maybe deleted, it -+// is first looked for in the lists for the outer loops of the current loop. -+// -+// The insights into the problem: -+// A) counted loops are okay -+// B) innermost loops are okay (only an inner loop can delete -+// a ncsfpt needed by an outer loop) -+// C) a loop is immune from an inner loop deleting a safepoint -+// if the loop has a call on the idom-path -+// D) a loop is also immune if it has a ncsfpt (non-call safepoint) on the -+// idom-path that is not in a nested loop -+// E) otherwise, an ncsfpt on the idom-path that is nested in an inner -+// loop needs to be prevented from deletion by an inner loop -+// -+// There are two analyses: -+// 1) The first, and cheaper one, scans the loop body from -+// tail to head following the idom (immediate dominator) -+// chain, looking for the cases (C,D,E) above. -+// Since inner loops are scanned before outer loops, there is summary -+// information about inner loops. Inner loops can be skipped over -+// when the tail of an inner loop is encountered. -+// -+// 2) The second, invoked if the first fails to find a call or ncsfpt on -+// the idom path (which is rare), scans all predecessor control paths -+// from the tail to the head, terminating a path when a call or sfpt -+// is encountered, to find the ncsfpt's that are closest to the tail. -+// -+void IdealLoopTree::check_safepts(VectorSet &visited, Node_List &stack) { -+ // Bottom up traversal -+ IdealLoopTree* ch = _child; -+ while (ch != NULL) { -+ ch->check_safepts(visited, stack); -+ ch = ch->_next; -+ } -+ -+ if (!_head->is_CountedLoop() && !_has_sfpt && _parent != NULL && !_irreducible) { -+ bool has_call = false; // call on dom-path -+ bool has_local_ncsfpt = false; // ncsfpt on dom-path at this loop depth -+ Node* nonlocal_ncsfpt = NULL; // ncsfpt on dom-path at a deeper depth -+ // Scan the dom-path nodes from tail to head -+ for (Node* n = tail(); n != _head; n = _phase->idom(n)) { -+ if (n->is_Call() && n->as_Call()->guaranteed_safepoint()) { -+ has_call = true; - _has_sfpt = 1; // Then no need for a safept! - break; -+ } else if (n->Opcode() == Op_SafePoint) { -+ if (_phase->get_loop(n) == this) { -+ has_local_ncsfpt = true; -+ break; - } -+ if (nonlocal_ncsfpt == NULL) { -+ nonlocal_ncsfpt = n; // save the one closest to the tail - } -+ } else { -+ IdealLoopTree* nlpt = _phase->get_loop(n); -+ if (this != nlpt) { -+ // If at an inner loop tail, see if the inner loop has already -+ // recorded seeing a call on the dom-path (and stop.) If not, -+ // jump to the head of the inner loop. -+ assert(is_member(nlpt), "nested loop"); -+ Node* tail = nlpt->_tail; -+ if (tail->in(0)->is_If()) tail = tail->in(0); -+ if (n == tail) { -+ // If inner loop has call on dom-path, so does outer loop -+ if (nlpt->_has_sfpt) { -+ has_call = true; -+ _has_sfpt = 1; -+ break; -+ } -+ // Skip to head of inner loop -+ assert(_phase->is_dominator(_head, nlpt->_head), "inner head dominated by outer head"); -+ n = nlpt->_head; -+ } -+ } -+ } -+ } -+ // Record safept's that this loop needs preserved when an -+ // inner loop attempts to delete it's safepoints. -+ if (_child != NULL && !has_call && !has_local_ncsfpt) { -+ if (nonlocal_ncsfpt != NULL) { -+ if (_required_safept == NULL) _required_safept = new Node_List(); -+ _required_safept->push(nonlocal_ncsfpt); -+ } else { -+ // Failed to find a suitable safept on the dom-path. Now use -+ // an all paths walk from tail to head, looking for safepoints to preserve. -+ allpaths_check_safepts(visited, stack); - } -+ } -+ } -+} - -- // Recursively -- if( _child ) _child->check_inner_safepts( phase ); -- if( _next ) _next ->check_inner_safepts( phase ); -+//---------------------------is_deleteable_safept---------------------------- -+// Is safept not required by an outer loop? -+bool PhaseIdealLoop::is_deleteable_safept(Node* sfpt) { -+ assert(sfpt->Opcode() == Op_SafePoint, ""); -+ IdealLoopTree* lp = get_loop(sfpt)->_parent; -+ while (lp != NULL) { -+ Node_List* sfpts = lp->_required_safept; -+ if (sfpts != NULL) { -+ for (uint i = 0; i < sfpts->size(); i++) { -+ if (sfpt == sfpts->at(i)) -+ return false; -+ } -+ } -+ lp = lp->_parent; -+ } -+ return true; - } - - //------------------------------counted_loop----------------------------------- -@@ -1154,7 +1316,8 @@ - - // Look for a safepoint to remove - for (Node* n = tail(); n != _head; n = phase->idom(n)) -- if( n->Opcode() == Op_SafePoint ) // Found a safept? -+ if (n->Opcode() == Op_SafePoint && phase->get_loop(n) == this && -+ phase->is_deleteable_safept(n)) - phase->lazy_replace(n,n->in(TypeFunc::Control)); - - CountedLoopNode *cl = _head->as_CountedLoop(); -@@ -1230,6 +1393,21 @@ - continue; - } - } -+ } else if (_parent != NULL && !_irreducible) { -+ // Not a counted loop. -+ // Look for a safepoint on the idom-path to remove, preserving the first one -+ bool found = false; -+ Node* n = tail(); -+ for (; n != _head && !found; n = phase->idom(n)) { -+ if (n->Opcode() == Op_SafePoint && phase->get_loop(n) == this) -+ found = true; // Found one -+ } -+ // Skip past it and delete the others -+ for (; n != _head; n = phase->idom(n)) { -+ if (n->Opcode() == Op_SafePoint && phase->get_loop(n) == this && -+ phase->is_deleteable_safept(n)) -+ phase->lazy_replace(n,n->in(TypeFunc::Control)); -+ } - } - - // Recursively -@@ -1374,7 +1552,8 @@ - // Given dominators, try to find inner loops with calls that must - // always be executed (call dominates loop tail). These loops do - // not need a seperate safepoint. -- _ltree_root->check_inner_safepts( this ); -+ Node_List cisstack(a); -+ _ltree_root->check_safepts(visited, cisstack); - - // Walk the DATA nodes and place into loops. Find earliest control - // node. For CFG nodes, the _nodes array starts out and remains -@@ -2119,7 +2298,8 @@ - // (the old code here would yank a 2nd safepoint after seeing a - // first one, even though the 1st did not dominate in the loop body - // and thus could be avoided indefinitely) -- if( !verify_me && ilt->_has_sfpt && n->Opcode() == Op_SafePoint ) { -+ if( !verify_me && ilt->_has_sfpt && n->Opcode() == Op_SafePoint && -+ is_deleteable_safept(n)) { - Node *in = n->in(TypeFunc::Control); - lazy_replace(n,in); // Pull safepoint now - // Carry on with the recursion "as if" we are walking -@@ -2704,4 +2884,3 @@ - } - } - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/loopnode.hpp openjdk/hotspot/src/share/vm/opto/loopnode.hpp ---- openjdk6/hotspot/src/share/vm/opto/loopnode.hpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/loopnode.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)loopnode.hpp 1.143 07/06/29 13:39:53 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -87,7 +84,7 @@ - in(2) != NULL && phase->type(in(2)) != Type::TOP; - } - #ifndef PRODUCT -- virtual void dump_spec() const; -+ virtual void dump_spec(outputStream *st) const; - #endif - }; - -@@ -214,7 +211,7 @@ - int node_count_before_unroll() { return _node_count_before_unroll; } - - #ifndef PRODUCT -- virtual void dump_spec() const; -+ virtual void dump_spec(outputStream *st) const; - #endif - }; - -@@ -246,7 +243,7 @@ - return (CountedLoopNode*)ln; } - - #ifndef PRODUCT -- virtual void dump_spec() const; -+ virtual void dump_spec(outputStream *st) const; - #endif - }; - -@@ -292,10 +289,13 @@ - _has_sfpt:1, // True if has non-call safepoint - _rce_candidate:1; // True if candidate for range check elimination - -+ Node_List* _required_safept; // A inner loop cannot delete these safepts; -+ - IdealLoopTree( PhaseIdealLoop* phase, Node *head, Node *tail ) - : _parent(0), _next(0), _child(0), - _head(head), _tail(tail), - _phase(phase), -+ _required_safept(NULL), - _nest(0), _irreducible(0), _has_call(0), _has_sfpt(0), _rce_candidate(0) - { } - -@@ -328,10 +328,14 @@ - // Driver for various flavors of iteration splitting - void iteration_split_impl( PhaseIdealLoop *phase, Node_List &old_new ); - -- // Given dominators, try to find inner loops with calls that must -- // always be executed (call dominates loop tail). These loops do -- // not need a seperate safepoint. -- void check_inner_safepts( PhaseIdealLoop *phase ); -+ // Given dominators, try to find loops with calls that must always be -+ // executed (call dominates loop tail). These loops do not need non-call -+ // safepoints (ncsfpt). -+ void check_safepts(VectorSet &visited, Node_List &stack); -+ -+ // Allpaths backwards scan from loop tail, terminating each path at first safepoint -+ // encountered. -+ void allpaths_check_safepts(VectorSet &visited, Node_List &stack); - - // Convert to counted loops where possible - void counted_loop( PhaseIdealLoop *phase ); -@@ -649,6 +653,9 @@ - // Recompute dom_depth - void recompute_dom_depth(); - -+ // Is safept not required by an outer loop? -+ bool is_deleteable_safept(Node* sfpt); -+ - public: - // Dominators for the sea of nodes - void Dominators(); -@@ -910,4 +917,3 @@ - - IdealLoopTree* current() { return _curnt; } // Return current value of iterator. - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/loopopts.cpp openjdk/hotspot/src/share/vm/opto/loopopts.cpp ---- openjdk6/hotspot/src/share/vm/opto/loopopts.cpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/loopopts.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)loopopts.cpp 1.221 08/06/19 12:08:11 JVM" --#endif - /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -32,11 +29,6 @@ - //------------------------------split_thru_phi--------------------------------- - // Split Node 'n' through merge point if there is enough win. - Node *PhaseIdealLoop::split_thru_phi( Node *n, Node *region, int policy ) { -- if (n->Opcode() == Op_ConvI2L && n->bottom_type() != TypeLong::LONG) { -- // ConvI2L may have type information on it which is unsafe to push up -- // so disable this for now -- return NULL; -- } - int wins = 0; - assert( !n->is_CFG(), "" ); - assert( region->is_Region(), "" ); -@@ -608,6 +600,9 @@ - } - } - -+ // Use same limit as split_if_with_blocks_post -+ if( C->unique() > 35000 ) return n; // Method too big -+ - // Split 'n' through the merge point if it is profitable - Node *phi = split_thru_phi( n, n_blk, policy ); - if( !phi ) return n; -@@ -1243,20 +1238,26 @@ - assert( dd_r >= dom_depth(dom_lca(newuse,use)), "" ); - - // The original user of 'use' uses 'r' instead. -- for (DUIterator_Last lmin, l = use->last_outs(lmin); l >= lmin; --l) { -+ for (DUIterator_Last lmin, l = use->last_outs(lmin); l >= lmin;) { - Node* useuse = use->last_out(l); - _igvn.hash_delete(useuse); - _igvn._worklist.push(useuse); -+ uint uses_found = 0; - if( useuse->in(0) == use ) { - useuse->set_req(0, r); -+ uses_found++; - if( useuse->is_CFG() ) { - assert( dom_depth(useuse) > dd_r, "" ); - set_idom(useuse, r, dom_depth(useuse)); - } - } -- for( uint k = 1; k < useuse->req(); k++ ) -- if( useuse->in(k) == use ) -+ for( uint k = 1; k < useuse->req(); k++ ) { -+ if( useuse->in(k) == use ) { - useuse->set_req(k, r); -+ uses_found++; -+ } -+ } -+ l -= uses_found; // we deleted 1 or more copies of this edge - } - - // Now finish up 'r' -@@ -2674,4 +2675,3 @@ - } - - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/machnode.cpp openjdk/hotspot/src/share/vm/opto/machnode.cpp ---- openjdk6/hotspot/src/share/vm/opto/machnode.cpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/machnode.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)machnode.cpp 1.199 07/05/05 17:06:21 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -81,7 +78,7 @@ - //------------------------------dump_spec-------------------------------------- - // Print any per-operand special info - #ifndef PRODUCT --void MachOper::dump_spec() const { } -+void MachOper::dump_spec(outputStream *st) const { } - #endif - - //------------------------------hash------------------------------------------- -@@ -444,35 +441,35 @@ - #ifndef PRODUCT - //------------------------------dump_spec-------------------------------------- - // Print any per-operand special info --void MachNode::dump_spec() const { -+void MachNode::dump_spec(outputStream *st) const { - uint cnt = num_opnds(); - for( uint i=0; idump_spec(); -+ _opnds[i]->dump_spec(st); - const TypePtr *t = adr_type(); - if( t ) { - Compile* C = Compile::current(); - if( C->alias_type(t)->is_volatile() ) -- tty->print(" Volatile!"); -+ st->print(" Volatile!"); - } - } - - //------------------------------dump_format------------------------------------ - // access to virtual --void MachNode::dump_format(PhaseRegAlloc *ra) const { -- format(ra); // access to virtual -+void MachNode::dump_format(PhaseRegAlloc *ra, outputStream *st) const { -+ format(ra, st); // access to virtual - } - #endif - - //============================================================================= - #ifndef PRODUCT --void MachTypeNode::dump_spec() const { -- _bottom_type->dump(); -+void MachTypeNode::dump_spec(outputStream *st) const { -+ _bottom_type->dump_on(st); - } - #endif - - //============================================================================= - #ifndef PRODUCT --void MachNullCheckNode::format( PhaseRegAlloc *ra_ ) const { -+void MachNullCheckNode::format( PhaseRegAlloc *ra_, outputStream *st ) const { - int reg = ra_->get_reg_first(in(1)->in(_vidx)); - tty->print("%s %s", Name(), Matcher::regName[reg]); - } -@@ -517,19 +514,19 @@ - } - - #ifndef PRODUCT --void MachProjNode::dump_spec() const { -- ProjNode::dump_spec(); -+void MachProjNode::dump_spec(outputStream *st) const { -+ ProjNode::dump_spec(st); - switch (_ideal_reg) { -- case unmatched_proj: tty->print("/unmatched"); break; -- case fat_proj: tty->print("/fat"); if (WizardMode) _rout.dump(); break; -+ case unmatched_proj: st->print("/unmatched"); break; -+ case fat_proj: st->print("/fat"); if (WizardMode) _rout.dump(); break; - } - } - #endif - - //============================================================================= - #ifndef PRODUCT --void MachIfNode::dump_spec() const { -- tty->print("P=%f, C=%f",_prob, _fcnt); -+void MachIfNode::dump_spec(outputStream *st) const { -+ st->print("P=%f, C=%f",_prob, _fcnt); - } - #endif - -@@ -575,11 +572,11 @@ - const Type *MachCallNode::Value(PhaseTransform *phase) const { return tf()->range(); } - - #ifndef PRODUCT --void MachCallNode::dump_spec() const { -- tty->print("# "); -- tf()->dump(); -- if (_cnt != COUNT_UNKNOWN) tty->print(" C=%f",_cnt); -- if (jvms() != NULL) jvms()->dump_spec(); -+void MachCallNode::dump_spec(outputStream *st) const { -+ st->print("# "); -+ tf()->dump_on(st); -+ if (_cnt != COUNT_UNKNOWN) st->print(" C=%f",_cnt); -+ if (jvms() != NULL) jvms()->dump_spec(st); - } - #endif - -@@ -618,12 +615,12 @@ - return MachCallNode::cmp(call) && _method->equals(call._method); - } - #ifndef PRODUCT --void MachCallJavaNode::dump_spec() const { -+void MachCallJavaNode::dump_spec(outputStream *st) const { - if( _method ) { -- _method->print_short_name(); -- tty->print(" "); -+ _method->print_short_name(st); -+ st->print(" "); - } -- MachCallNode::dump_spec(); -+ MachCallNode::dump_spec(st); - } - #endif - -@@ -645,32 +642,32 @@ - - #ifndef PRODUCT - // Helper for summarizing uncommon_trap arguments. --void MachCallStaticJavaNode::dump_trap_args() const { -+void MachCallStaticJavaNode::dump_trap_args(outputStream *st) const { - int trap_req = uncommon_trap_request(); - if (trap_req != 0) { - char buf[100]; -- tty->print("(%s)", -+ st->print("(%s)", - Deoptimization::format_trap_request(buf, sizeof(buf), - trap_req)); - } - } - --void MachCallStaticJavaNode::dump_spec() const { -- tty->print("Static "); -+void MachCallStaticJavaNode::dump_spec(outputStream *st) const { -+ st->print("Static "); - if (_name != NULL) { -- tty->print("wrapper for: %s", _name ); -- dump_trap_args(); -- tty->print(" "); -+ st->print("wrapper for: %s", _name ); -+ dump_trap_args(st); -+ st->print(" "); - } -- MachCallJavaNode::dump_spec(); -+ MachCallJavaNode::dump_spec(st); - } - #endif - - //============================================================================= - #ifndef PRODUCT --void MachCallDynamicJavaNode::dump_spec() const { -- tty->print("Dynamic "); -- MachCallJavaNode::dump_spec(); -+void MachCallDynamicJavaNode::dump_spec(outputStream *st) const { -+ st->print("Dynamic "); -+ MachCallJavaNode::dump_spec(st); - } - #endif - //============================================================================= -@@ -680,9 +677,9 @@ - return MachCallNode::cmp(call) && !strcmp(_name,call._name); - } - #ifndef PRODUCT --void MachCallRuntimeNode::dump_spec() const { -- tty->print("%s ",_name); -- MachCallNode::dump_spec(); -+void MachCallRuntimeNode::dump_spec(outputStream *st) const { -+ st->print("%s ",_name); -+ MachCallNode::dump_spec(st); - } - #endif - //============================================================================= -@@ -697,14 +694,14 @@ - - //============================================================================= - #ifndef PRODUCT --void labelOper::int_format(PhaseRegAlloc *ra, const MachNode *node) const { -- tty->print("B%d", _block_num); -+void labelOper::int_format(PhaseRegAlloc *ra, const MachNode *node, outputStream *st) const { -+ st->print("B%d", _block_num); - } - #endif // PRODUCT - - //============================================================================= - #ifndef PRODUCT --void methodOper::int_format(PhaseRegAlloc *ra, const MachNode *node) const { -- tty->print(INTPTR_FORMAT, _method); -+void methodOper::int_format(PhaseRegAlloc *ra, const MachNode *node, outputStream *st) const { -+ st->print(INTPTR_FORMAT, _method); - } - #endif // PRODUCT -diff -ruNb openjdk6/hotspot/src/share/vm/opto/machnode.hpp openjdk/hotspot/src/share/vm/opto/machnode.hpp ---- openjdk6/hotspot/src/share/vm/opto/machnode.hpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/machnode.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)machnode.hpp 1.202 07/05/17 15:59:11 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -88,7 +85,7 @@ - return ::as_FloatRegister(reg(ra_, node, idx)); - } - --#if defined(IA32) -+#if defined(IA32) || defined(AMD64) - XMMRegister as_XMMRegister(PhaseRegAlloc *ra_, const Node *node) const { - return ::as_XMMRegister(reg(ra_, node)); - } -@@ -145,10 +142,10 @@ - virtual const char *Name() const { return "???";} - - // Methods to output the text version of the operand -- virtual void int_format(PhaseRegAlloc *,const MachNode *node) const = 0; -- virtual void ext_format(PhaseRegAlloc *,const MachNode *node,int idx) const=0; -+ virtual void int_format(PhaseRegAlloc *,const MachNode *node, outputStream *st) const = 0; -+ virtual void ext_format(PhaseRegAlloc *,const MachNode *node,int idx, outputStream *st) const=0; - -- virtual void dump_spec() const; // Print per-operand info -+ virtual void dump_spec(outputStream *st) const; // Print per-operand info - #endif - }; - -@@ -296,8 +293,8 @@ - - #ifndef PRODUCT - virtual const char *Name() const = 0; // Machine-specific name -- virtual void dump_spec() const; // Print per-node info -- void dump_format(PhaseRegAlloc *ra) const; // access to virtual -+ virtual void dump_spec(outputStream *st) const; // Print per-node info -+ void dump_format(PhaseRegAlloc *ra, outputStream *st) const; // access to virtual - #endif - }; - -@@ -324,7 +321,7 @@ - - virtual const class Type *bottom_type() const { return _bottom_type; } - #ifndef PRODUCT -- virtual void dump_spec() const; -+ virtual void dump_spec(outputStream *st) const; - #endif - }; - -@@ -338,7 +335,7 @@ - - #ifndef PRODUCT - virtual const char *Name() const { return "Breakpoint"; } -- virtual void format( PhaseRegAlloc * ) const; -+ virtual void format( PhaseRegAlloc *, outputStream *st ) const; - #endif - }; - -@@ -352,7 +349,7 @@ - - #ifndef PRODUCT - virtual const char *Name() const { return "Unvalidated-Entry-Point"; } -- virtual void format( PhaseRegAlloc * ) const; -+ virtual void format( PhaseRegAlloc *, outputStream *st ) const; - #endif - }; - -@@ -364,11 +361,10 @@ - virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const; - virtual uint size(PhaseRegAlloc *ra_) const; - virtual int reloc() const; -- uint implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size ) const; - - #ifndef PRODUCT - virtual const char *Name() const { return "Prolog"; } -- virtual void format( PhaseRegAlloc * ) const; -+ virtual void format( PhaseRegAlloc *, outputStream *st ) const; - #endif - }; - -@@ -393,7 +389,7 @@ - - #ifndef PRODUCT - virtual const char *Name() const { return "Epilog"; } -- virtual void format( PhaseRegAlloc * ) const; -+ virtual void format( PhaseRegAlloc *, outputStream *st ) const; - #endif - }; - -@@ -414,8 +410,8 @@ - virtual const Pipeline *pipeline() const; - #ifndef PRODUCT - virtual const char *Name() const { return "Nop"; } -- virtual void format( PhaseRegAlloc * ) const; -- virtual void dump_spec() const { } // No per-operand info -+ virtual void format( PhaseRegAlloc *, outputStream *st ) const; -+ virtual void dump_spec(outputStream *st) const { } // No per-operand info - #endif - }; - -@@ -442,14 +438,14 @@ - virtual const class Type *bottom_type() const { return _type; } - virtual uint ideal_reg() const { return Matcher::base2reg[_type->base()]; } - virtual uint oper_input_base() const { return 1; } -- uint implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size ) const; -+ uint implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const; - - virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const; - virtual uint size(PhaseRegAlloc *ra_) const; - - #ifndef PRODUCT - virtual const char *Name() const { return "MachSpillCopy"; } -- virtual void format( PhaseRegAlloc * ) const; -+ virtual void format( PhaseRegAlloc *, outputStream *st ) const; - #endif - }; - -@@ -478,7 +474,7 @@ - virtual const RegMask &out_RegMask() const { return RegMask::Empty; } - #ifndef PRODUCT - virtual const char *Name() const { return "NullCheck"; } -- virtual void format( PhaseRegAlloc * ) const; -+ virtual void format( PhaseRegAlloc *, outputStream *st ) const; - #endif - }; - -@@ -508,7 +504,7 @@ - // Need size_of() for virtual ProjNode::clone() - virtual uint size_of() const { return sizeof(MachProjNode); } - #ifndef PRODUCT -- virtual void dump_spec() const; -+ virtual void dump_spec(outputStream *st) const; - #endif - }; - -@@ -523,7 +519,7 @@ - init_class_id(Class_MachIf); - } - #ifndef PRODUCT -- virtual void dump_spec() const; -+ virtual void dump_spec(outputStream *st) const; - #endif - }; - -@@ -652,7 +648,7 @@ - bool returns_long() const { return tf()->return_type() == T_LONG; } - bool return_value_is_used() const; - #ifndef PRODUCT -- virtual void dump_spec() const; -+ virtual void dump_spec(outputStream *st) const; - #endif - }; - -@@ -670,7 +666,7 @@ - init_class_id(Class_MachCallJava); - } - #ifndef PRODUCT -- virtual void dump_spec() const; -+ virtual void dump_spec(outputStream *st) const; - #endif - }; - -@@ -690,8 +686,8 @@ - - virtual int ret_addr_offset(); - #ifndef PRODUCT -- virtual void dump_spec() const; -- void dump_trap_args() const; -+ virtual void dump_spec(outputStream *st) const; -+ void dump_trap_args(outputStream *st) const; - #endif - }; - -@@ -706,7 +702,7 @@ - } - virtual int ret_addr_offset(); - #ifndef PRODUCT -- virtual void dump_spec() const; -+ virtual void dump_spec(outputStream *st) const; - #endif - }; - -@@ -722,7 +718,7 @@ - } - virtual int ret_addr_offset(); - #ifndef PRODUCT -- virtual void dump_spec() const; -+ virtual void dump_spec(outputStream *st) const; - #endif - }; - -@@ -762,7 +758,7 @@ - virtual uint size_of() const { return sizeof(MachTempNode); } - - #ifndef PRODUCT -- virtual void format(PhaseRegAlloc *ra) const {} -+ virtual void format(PhaseRegAlloc *, outputStream *st ) const {} - virtual const char *Name() const { return "MachTemp";} - #endif - }; -@@ -797,8 +793,8 @@ - #ifndef PRODUCT - virtual const char *Name() const { return "Label";} - -- virtual void int_format(PhaseRegAlloc *ra, const MachNode *node) const; -- virtual void ext_format(PhaseRegAlloc *ra, const MachNode *node, int idx) const { int_format( ra, node ); } -+ virtual void int_format(PhaseRegAlloc *ra, const MachNode *node, outputStream *st) const; -+ virtual void ext_format(PhaseRegAlloc *ra, const MachNode *node, int idx, outputStream *st) const { int_format( ra, node, st ); } - #endif - }; - -@@ -824,7 +820,7 @@ - #ifndef PRODUCT - virtual const char *Name() const { return "Method";} - -- virtual void int_format(PhaseRegAlloc *ra, const MachNode *node) const; -- virtual void ext_format(PhaseRegAlloc *ra, const MachNode *node, int idx) const { int_format( ra, node ); } -+ virtual void int_format(PhaseRegAlloc *ra, const MachNode *node, outputStream *st) const; -+ virtual void ext_format(PhaseRegAlloc *ra, const MachNode *node, int idx, outputStream *st) const { int_format( ra, node, st ); } - #endif - }; -diff -ruNb openjdk6/hotspot/src/share/vm/opto/macro.cpp openjdk/hotspot/src/share/vm/opto/macro.cpp ---- openjdk6/hotspot/src/share/vm/opto/macro.cpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/macro.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)macro.cpp 1.31 07/07/10 21:32:44 JVM" --#endif - /* - * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -71,14 +68,14 @@ - } - - Node* PhaseMacroExpand::opt_iff(Node* region, Node* iff) { -- IfNode *opt_iff = _igvn.register_new_node_with_optimizer(iff)->as_If(); -+ IfNode *opt_iff = transform_later(iff)->as_If(); - - // Fast path taken; set region slot 2 -- Node *fast_taken = _igvn.register_new_node_with_optimizer( new (C, 1) IfFalseNode(opt_iff) ); -+ Node *fast_taken = transform_later( new (C, 1) IfFalseNode(opt_iff) ); - region->init_req(2,fast_taken); // Capture fast-control - - // Fast path not-taken, i.e. slow path -- Node *slow_taken = _igvn.register_new_node_with_optimizer( new (C, 1) IfTrueNode(opt_iff) ); -+ Node *slow_taken = transform_later( new (C, 1) IfTrueNode(opt_iff) ); - return slow_taken; - } - -@@ -109,7 +106,7 @@ - call->set_cnt(PROB_UNLIKELY_MAG(4)); // Same effect as RC_UNCOMMON. - _igvn.hash_delete(oldcall); - _igvn.subsume_node(oldcall, call); -- _igvn.register_new_node_with_optimizer(call); -+ transform_later(call); - - return call; - } -@@ -170,11 +167,29 @@ - } - - -+//---------------------------set_eden_pointers------------------------- -+void PhaseMacroExpand::set_eden_pointers(Node* &eden_top_adr, Node* &eden_end_adr) { -+ if (UseTLAB) { // Private allocation: load from TLS -+ Node* thread = transform_later(new (C, 1) ThreadLocalNode()); -+ int tlab_top_offset = in_bytes(JavaThread::tlab_top_offset()); -+ int tlab_end_offset = in_bytes(JavaThread::tlab_end_offset()); -+ eden_top_adr = basic_plus_adr(top()/*not oop*/, thread, tlab_top_offset); -+ eden_end_adr = basic_plus_adr(top()/*not oop*/, thread, tlab_end_offset); -+ } else { // Shared allocation: load from globals -+ CollectedHeap* ch = Universe::heap(); -+ address top_adr = (address)ch->top_addr(); -+ address end_adr = (address)ch->end_addr(); -+ eden_top_adr = makecon(TypeRawPtr::make(top_adr)); -+ eden_end_adr = basic_plus_adr(eden_top_adr, end_adr - top_adr); -+ } -+} -+ -+ - Node* PhaseMacroExpand::make_load(Node* ctl, Node* mem, Node* base, int offset, const Type* value_type, BasicType bt) { - Node* adr = basic_plus_adr(base, offset); - const TypePtr* adr_type = TypeRawPtr::BOTTOM; - Node* value = LoadNode::make(C, ctl, mem, adr, adr_type, value_type, bt); -- _igvn.register_new_node_with_optimizer(value); -+ transform_later(value); - return value; - } - -@@ -182,7 +197,7 @@ - Node* PhaseMacroExpand::make_store(Node* ctl, Node* mem, Node* base, int offset, Node* value, BasicType bt) { - Node* adr = basic_plus_adr(base, offset); - mem = StoreNode::make(C, ctl, mem, adr, NULL, value, bt); -- _igvn.register_new_node_with_optimizer(mem); -+ transform_later(mem); - return mem; - } - -@@ -254,8 +269,10 @@ - Node* size_in_bytes = alloc->in(AllocateNode::AllocSize); - Node* klass_node = alloc->in(AllocateNode::KlassNode); - Node* initial_slow_test = alloc->in(AllocateNode::InitialTest); -- Node* eden_top_adr = alloc->in(AllocateNode::EdenTop); -- Node* eden_end_adr = alloc->in(AllocateNode::EdenEnd); -+ -+ Node* eden_top_adr; -+ Node* eden_end_adr; -+ set_eden_pointers(eden_top_adr, eden_end_adr); - - uint raw_idx = C->get_alias_index(TypeRawPtr::BOTTOM); - assert(ctrl != NULL, "must have control"); -@@ -310,13 +327,13 @@ - // might be a TRUE for finalizers or a fancy class check for - // newInstance0. - IfNode *toobig_iff = new (C, 2) IfNode(ctrl, initial_slow_test, PROB_MIN, COUNT_UNKNOWN); -- _igvn.register_new_node_with_optimizer(toobig_iff); -+ transform_later(toobig_iff); - // Plug the failing-too-big test into the slow-path region - Node *toobig_true = new (C, 1) IfTrueNode( toobig_iff ); -- _igvn.register_new_node_with_optimizer(toobig_true); -+ transform_later(toobig_true); - slow_region ->init_req( too_big_or_final_path, toobig_true ); - toobig_false = new (C, 1) IfFalseNode( toobig_iff ); -- _igvn.register_new_node_with_optimizer(toobig_false); -+ transform_later(toobig_false); - } else { // No initial test, just fall into next case - toobig_false = ctrl; - debug_only(slow_region = NodeSentinel); -@@ -345,8 +362,8 @@ - // loop-back merge point. - contended_region ->init_req( fall_in_path, toobig_false ); - contended_phi_rawmem->init_req( fall_in_path, mem ); -- _igvn.register_new_node_with_optimizer(contended_region); -- _igvn.register_new_node_with_optimizer(contended_phi_rawmem); -+ transform_later(contended_region); -+ transform_later(contended_phi_rawmem); - } - - // Load(-locked) the heap top. -@@ -355,32 +372,32 @@ - ? new (C, 3) LoadPNode ( ctrl, contended_phi_rawmem, eden_top_adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM ) - : new (C, 3) LoadPLockedNode( contended_region, contended_phi_rawmem, eden_top_adr ); - -- _igvn.register_new_node_with_optimizer(old_eden_top); -+ transform_later(old_eden_top); - // Add to heap top to get a new heap top - Node *new_eden_top = new (C, 4) AddPNode( top(), old_eden_top, size_in_bytes ); -- _igvn.register_new_node_with_optimizer(new_eden_top); -+ transform_later(new_eden_top); - // Check for needing a GC; compare against heap end - Node *needgc_cmp = new (C, 3) CmpPNode( new_eden_top, eden_end ); -- _igvn.register_new_node_with_optimizer(needgc_cmp); -+ transform_later(needgc_cmp); - Node *needgc_bol = new (C, 2) BoolNode( needgc_cmp, BoolTest::ge ); -- _igvn.register_new_node_with_optimizer(needgc_bol); -+ transform_later(needgc_bol); - IfNode *needgc_iff = new (C, 2) IfNode(contended_region, needgc_bol, PROB_UNLIKELY_MAG(4), COUNT_UNKNOWN ); -- _igvn.register_new_node_with_optimizer(needgc_iff); -+ transform_later(needgc_iff); - - // Plug the failing-heap-space-need-gc test into the slow-path region - Node *needgc_true = new (C, 1) IfTrueNode( needgc_iff ); -- _igvn.register_new_node_with_optimizer(needgc_true); -+ transform_later(needgc_true); - if( initial_slow_test ) { - slow_region ->init_req( need_gc_path, needgc_true ); - // This completes all paths into the slow merge point -- _igvn.register_new_node_with_optimizer(slow_region); -+ transform_later(slow_region); - } else { // No initial slow path needed! - // Just fall from the need-GC path straight into the VM call. - slow_region = needgc_true; - } - // No need for a GC. Setup for the Store-Conditional - Node *needgc_false = new (C, 1) IfFalseNode( needgc_iff ); -- _igvn.register_new_node_with_optimizer(needgc_false); -+ transform_later(needgc_false); - - // Grab regular I/O before optional prefetch may change it. - // Slow-path does no I/O so just set it to the original I/O. -@@ -396,28 +413,28 @@ - Node *fast_oop_ctrl; - if( UseTLAB ) { - store_eden_top = new (C, 4) StorePNode( needgc_false, contended_phi_rawmem, eden_top_adr, TypeRawPtr::BOTTOM, new_eden_top ); -- _igvn.register_new_node_with_optimizer(store_eden_top); -+ transform_later(store_eden_top); - fast_oop_ctrl = needgc_false; // No contention, so this is the fast path - } else { - store_eden_top = new (C, 5) StorePConditionalNode( needgc_false, contended_phi_rawmem, eden_top_adr, new_eden_top, old_eden_top ); -- _igvn.register_new_node_with_optimizer(store_eden_top); -+ transform_later(store_eden_top); - Node *contention_check = new (C, 2) BoolNode( store_eden_top, BoolTest::ne ); -- _igvn.register_new_node_with_optimizer(contention_check); -+ transform_later(contention_check); - store_eden_top = new (C, 1) SCMemProjNode(store_eden_top); -- _igvn.register_new_node_with_optimizer(store_eden_top); -+ transform_later(store_eden_top); - - // If not using TLABs, check to see if there was contention. - IfNode *contention_iff = new (C, 2) IfNode ( needgc_false, contention_check, PROB_MIN, COUNT_UNKNOWN ); -- _igvn.register_new_node_with_optimizer(contention_iff); -+ transform_later(contention_iff); - Node *contention_true = new (C, 1) IfTrueNode( contention_iff ); -- _igvn.register_new_node_with_optimizer(contention_true); -+ transform_later(contention_true); - // If contention, loopback and try again. - contended_region->init_req( contended_loopback_path, contention_true ); - contended_phi_rawmem->init_req( contended_loopback_path, store_eden_top ); - - // Fast-path succeeded with no contention! - Node *contention_false = new (C, 1) IfFalseNode( contention_iff ); -- _igvn.register_new_node_with_optimizer(contention_false); -+ transform_later(contention_false); - fast_oop_ctrl = contention_false; - } - -@@ -438,7 +455,7 @@ - - // Get base of thread-local storage area - Node* thread = new (C, 1) ThreadLocalNode(); -- _igvn.register_new_node_with_optimizer(thread); -+ transform_later(thread); - - call->init_req(TypeFunc::Parms+0, thread); - call->init_req(TypeFunc::Parms+1, fast_oop); -@@ -447,11 +464,11 @@ - call->init_req( TypeFunc::Memory , fast_oop_rawmem ); - call->init_req( TypeFunc::ReturnAdr, alloc->in(TypeFunc::ReturnAdr) ); - call->init_req( TypeFunc::FramePtr, alloc->in(TypeFunc::FramePtr) ); -- _igvn.register_new_node_with_optimizer(call); -+ transform_later(call); - fast_oop_ctrl = new (C, 1) ProjNode(call,TypeFunc::Control); -- _igvn.register_new_node_with_optimizer(fast_oop_ctrl); -+ transform_later(fast_oop_ctrl); - fast_oop_rawmem = new (C, 1) ProjNode(call,TypeFunc::Memory); -- _igvn.register_new_node_with_optimizer(fast_oop_rawmem); -+ transform_later(fast_oop_rawmem); - } - - // Plug in the successful fast-path into the result merge point -@@ -476,8 +493,9 @@ - call->init_req( TypeFunc::FramePtr, alloc->in(TypeFunc::FramePtr) ); - - call->init_req(TypeFunc::Parms+0, klass_node); -- if (length != NULL) -+ if (length != NULL) { - call->init_req(TypeFunc::Parms+1, length); -+ } - - // Copy debug information and adjust JVMState information, then replace - // allocate node with the call -@@ -487,7 +505,7 @@ - } - _igvn.hash_delete(alloc); - _igvn.subsume_node(alloc, call); -- _igvn.register_new_node_with_optimizer(call); -+ transform_later(call); - - // Identify the output projections from the allocate node and - // adjust any references to them. -@@ -518,7 +536,7 @@ - if (_memproj_catchall != NULL ) { - if (_memproj_fallthrough == NULL) { - _memproj_fallthrough = new (C, 1) ProjNode(call, TypeFunc::Memory); -- _igvn.register_new_node_with_optimizer(_memproj_fallthrough); -+ transform_later(_memproj_fallthrough); - } - for (DUIterator_Fast imax, i = _memproj_catchall->fast_outs(imax); i < imax; i++) { - Node *use = _memproj_catchall->fast_out(i); -@@ -536,7 +554,7 @@ - // Replace uses of the control i_o projection with result_phi_i_o (unless we are only generating a slow call) - if (_ioproj_fallthrough == NULL) { - _ioproj_fallthrough = new (C, 1) ProjNode(call, TypeFunc::I_O); -- _igvn.register_new_node_with_optimizer(_ioproj_fallthrough); -+ transform_later(_ioproj_fallthrough); - } else if (!always_slow) { - for (DUIterator_Fast imax, i = _ioproj_fallthrough->fast_outs(imax); i < imax; i++) { - Node *use = _ioproj_fallthrough->fast_out(i); -@@ -568,7 +586,7 @@ - - if (_fallthroughcatchproj != NULL) { - ctrl = _fallthroughcatchproj->clone(); -- _igvn.register_new_node_with_optimizer(ctrl); -+ transform_later(ctrl); - _igvn.hash_delete(_fallthroughcatchproj); - _igvn.subsume_node(_fallthroughcatchproj, result_region); - } else { -@@ -580,7 +598,7 @@ - slow_result = top(); - } else { - slow_result = _resproj->clone(); -- _igvn.register_new_node_with_optimizer(slow_result); -+ transform_later(slow_result); - _igvn.hash_delete(_resproj); - _igvn.subsume_node(_resproj, result_phi_rawoop); - } -@@ -589,13 +607,14 @@ - result_region ->init_req( slow_result_path, ctrl ); - result_phi_rawoop->init_req( slow_result_path, slow_result); - result_phi_rawmem->init_req( slow_result_path, _memproj_fallthrough ); -- _igvn.register_new_node_with_optimizer(result_region); -- _igvn.register_new_node_with_optimizer(result_phi_rawoop); -- _igvn.register_new_node_with_optimizer(result_phi_rawmem); -- _igvn.register_new_node_with_optimizer(result_phi_i_o); -+ transform_later(result_region); -+ transform_later(result_phi_rawoop); -+ transform_later(result_phi_rawmem); -+ transform_later(result_phi_i_o); - // This completes all paths into the result merge point - } - -+ - // Helper for PhaseMacroExpand::expand_allocate_common. - // Initializes the newly-allocated storage. - Node* -@@ -603,6 +622,7 @@ - Node* control, Node* rawmem, Node* object, - Node* klass_node, Node* length, - Node* size_in_bytes) { -+ InitializeNode* init = alloc->initialization(); - // Store the klass & mark bits - Node* mark_node = NULL; - // For now only enable fast locking for non-array types -@@ -625,13 +645,34 @@ - header_size = Klass::layout_helper_header_size(k->layout_helper()); - } - -- // Now bulk-clear the object body. There may be a padding word after the -- // length, but it doesn't need to be initialized. Optimizer will expand -- // this to a series of Stores if it's short and fixed size. -- if (!ZeroTLAB) { -+ // Clear the object body, if necessary. -+ if (init == NULL) { -+ // The init has somehow disappeared; be cautious and clear everything. -+ // -+ // This can happen if a node is allocated but an uncommon trap occurs -+ // immediately. In this case, the Initialize gets associated with the -+ // trap, and may be placed in a different (outer) loop, if the Allocate -+ // is in a loop. If (this is rare) the inner loop gets unrolled, then -+ // there can be two Allocates to one Initialize. The answer in all these -+ // edge cases is safety first. It is always safe to clear immediately -+ // within an Allocate, and then (maybe or maybe not) clear some more later. -+ if (!ZeroTLAB) - rawmem = ClearArrayNode::clear_memory(control, rawmem, object, - header_size, size_in_bytes, - &_igvn); -+ } else { -+ if (!init->is_complete()) { -+ // Try to win by zeroing only what the init does not store. -+ // We can also try to do some peephole optimizations, -+ // such as combining some adjacent subword stores. -+ rawmem = init->complete_stores(control, rawmem, object, -+ header_size, size_in_bytes, &_igvn); -+ } -+ -+ // We have no more use for this link, since the AllocateNode goes away: -+ init->set_req(InitializeNode::RawAddress, top()); -+ // (If we keep the link, it just confuses the register allocator, -+ // who thinks he sees a real use of the address by the membar.) - } - - return rawmem; -@@ -655,42 +696,42 @@ - Node *pf_phi_abio = new (C, 3) PhiNode( pf_region, Type::ABIO ); - - Node *thread = new (C, 1) ThreadLocalNode(); -- _igvn.register_new_node_with_optimizer(thread); -+ transform_later(thread); - - Node *eden_pf_adr = new (C, 4) AddPNode( top()/*not oop*/, thread, - _igvn.MakeConX(in_bytes(JavaThread::tlab_pf_top_offset())) ); -- _igvn.register_new_node_with_optimizer(eden_pf_adr); -+ transform_later(eden_pf_adr); - - Node *old_pf_wm = new (C, 3) LoadPNode( needgc_false, - contended_phi_rawmem, eden_pf_adr, - TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM ); -- _igvn.register_new_node_with_optimizer(old_pf_wm); -+ transform_later(old_pf_wm); - - // check against new_eden_top - Node *need_pf_cmp = new (C, 3) CmpPNode( new_eden_top, old_pf_wm ); -- _igvn.register_new_node_with_optimizer(need_pf_cmp); -+ transform_later(need_pf_cmp); - Node *need_pf_bol = new (C, 2) BoolNode( need_pf_cmp, BoolTest::ge ); -- _igvn.register_new_node_with_optimizer(need_pf_bol); -+ transform_later(need_pf_bol); - IfNode *need_pf_iff = new (C, 2) IfNode( needgc_false, need_pf_bol, - PROB_UNLIKELY_MAG(4), COUNT_UNKNOWN ); -- _igvn.register_new_node_with_optimizer(need_pf_iff); -+ transform_later(need_pf_iff); - - // true node, add prefetchdistance - Node *need_pf_true = new (C, 1) IfTrueNode( need_pf_iff ); -- _igvn.register_new_node_with_optimizer(need_pf_true); -+ transform_later(need_pf_true); - - Node *need_pf_false = new (C, 1) IfFalseNode( need_pf_iff ); -- _igvn.register_new_node_with_optimizer(need_pf_false); -+ transform_later(need_pf_false); - - Node *new_pf_wmt = new (C, 4) AddPNode( top(), old_pf_wm, - _igvn.MakeConX(AllocatePrefetchDistance) ); -- _igvn.register_new_node_with_optimizer(new_pf_wmt ); -+ transform_later(new_pf_wmt ); - new_pf_wmt->set_req(0, need_pf_true); - - Node *store_new_wmt = new (C, 4) StorePNode( need_pf_true, - contended_phi_rawmem, eden_pf_adr, - TypeRawPtr::BOTTOM, new_pf_wmt ); -- _igvn.register_new_node_with_optimizer(store_new_wmt); -+ transform_later(store_new_wmt); - - // adding prefetches - pf_phi_abio->init_req( fall_in_path, i_o ); -@@ -704,9 +745,9 @@ - for ( uint i = 0; i < lines; i++ ) { - prefetch_adr = new (C, 4) AddPNode( old_pf_wm, new_pf_wmt, - _igvn.MakeConX(distance) ); -- _igvn.register_new_node_with_optimizer(prefetch_adr); -+ transform_later(prefetch_adr); - prefetch = new (C, 3) PrefetchWriteNode( i_o, prefetch_adr ); -- _igvn.register_new_node_with_optimizer(prefetch); -+ transform_later(prefetch); - distance += step_size; - i_o = prefetch; - } -@@ -718,9 +759,9 @@ - pf_phi_rawmem->init_req( fall_in_path, contended_phi_rawmem ); - pf_phi_rawmem->init_req( pf_path, store_new_wmt ); - -- _igvn.register_new_node_with_optimizer(pf_region); -- _igvn.register_new_node_with_optimizer(pf_phi_rawmem); -- _igvn.register_new_node_with_optimizer(pf_phi_abio); -+ transform_later(pf_region); -+ transform_later(pf_phi_rawmem); -+ transform_later(pf_phi_abio); - - needgc_false = pf_region; - contended_phi_rawmem = pf_phi_rawmem; -@@ -736,14 +777,14 @@ - for ( uint i = 0; i < lines; i++ ) { - prefetch_adr = new (C, 4) AddPNode( old_eden_top, new_eden_top, - _igvn.MakeConX(distance) ); -- _igvn.register_new_node_with_optimizer(prefetch_adr); -+ transform_later(prefetch_adr); - prefetch = new (C, 3) PrefetchWriteNode( i_o, prefetch_adr ); - // Do not let it float too high, since if eden_top == eden_end, - // both might be null. - if( i == 0 ) { // Set control for first prefetch, next follows it - prefetch->init_req(0, needgc_false); - } -- _igvn.register_new_node_with_optimizer(prefetch); -+ transform_later(prefetch); - distance += step_size; - i_o = prefetch; - } -@@ -813,7 +854,7 @@ - // Make the merge point - Node *region = new (C, 3) RegionNode(3); - -- Node *bol = _igvn.register_new_node_with_optimizer(new (C, 2) BoolNode(flock,BoolTest::ne)); -+ Node *bol = transform_later(new (C, 2) BoolNode(flock,BoolTest::ne)); - Node *iff = new (C, 2) IfNode( ctrl, bol, PROB_MIN, COUNT_UNKNOWN ); - // Optimize test; set region slot 2 - Node *slow_path = opt_iff(region,iff); -@@ -834,20 +875,20 @@ - // disconnect fall-through projection from call and create a new one - // hook up users of fall-through projection to region - Node *slow_ctrl = _fallthroughproj->clone(); -- _igvn.register_new_node_with_optimizer(slow_ctrl); -+ transform_later(slow_ctrl); - _igvn.hash_delete(_fallthroughproj); - _fallthroughproj->disconnect_inputs(NULL); - region->init_req(1, slow_ctrl); - // region inputs are now complete -- _igvn.register_new_node_with_optimizer(region); -+ transform_later(region); - _igvn.subsume_node(_fallthroughproj, region); - - // create a Phi for the memory state - Node *mem_phi = new (C, 3) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM); -- Node *memproj = _igvn.register_new_node_with_optimizer( new (C, 1) ProjNode(call, TypeFunc::Memory) ); -+ Node *memproj = transform_later( new (C, 1) ProjNode(call, TypeFunc::Memory) ); - mem_phi->init_req(1, memproj ); - mem_phi->init_req(2, mem); -- _igvn.register_new_node_with_optimizer(mem_phi); -+ transform_later(mem_phi); - _igvn.hash_delete(_memproj_fallthrough); - _igvn.subsume_node(_memproj_fallthrough, mem_phi); - -@@ -874,8 +915,8 @@ - RegionNode *region = new (C, 3) RegionNode(3); - - FastUnlockNode *funlock = new (C, 3) FastUnlockNode( ctrl, obj, box ); -- funlock = _igvn.register_new_node_with_optimizer( funlock )->as_FastUnlock(); -- Node *bol = _igvn.register_new_node_with_optimizer(new (C, 2) BoolNode(funlock,BoolTest::ne)); -+ funlock = transform_later( funlock )->as_FastUnlock(); -+ Node *bol = transform_later(new (C, 2) BoolNode(funlock,BoolTest::ne)); - Node *iff = new (C, 2) IfNode( ctrl, bol, PROB_MIN, COUNT_UNKNOWN ); - // Optimize test; set region slot 2 - Node *slow_path = opt_iff(region,iff); -@@ -892,20 +933,20 @@ - // disconnect fall-through projection from call and create a new one - // hook up users of fall-through projection to region - Node *slow_ctrl = _fallthroughproj->clone(); -- _igvn.register_new_node_with_optimizer(slow_ctrl); -+ transform_later(slow_ctrl); - _igvn.hash_delete(_fallthroughproj); - _fallthroughproj->disconnect_inputs(NULL); - region->init_req(1, slow_ctrl); - // region inputs are now complete -- _igvn.register_new_node_with_optimizer(region); -+ transform_later(region); - _igvn.subsume_node(_fallthroughproj, region); - - // create a Phi for the memory state - Node *mem_phi = new (C, 3) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM); -- Node *memproj = _igvn.register_new_node_with_optimizer( new(C, 1) ProjNode(call, TypeFunc::Memory) ); -+ Node *memproj = transform_later( new(C, 1) ProjNode(call, TypeFunc::Memory) ); - mem_phi->init_req(1, memproj ); - mem_phi->init_req(2, mem); -- _igvn.register_new_node_with_optimizer(mem_phi); -+ transform_later(mem_phi); - _igvn.hash_delete(_memproj_fallthrough); - _igvn.subsume_node(_memproj_fallthrough, mem_phi); - -@@ -952,4 +993,3 @@ - _igvn.optimize(); - return false; - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/macro.hpp openjdk/hotspot/src/share/vm/opto/macro.hpp ---- openjdk6/hotspot/src/share/vm/opto/macro.hpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/macro.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)macro.hpp 1.10 07/07/02 18:45:21 JVM" --#endif - /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -43,11 +40,22 @@ - Node* basic_plus_adr(Node* base, int offset) { - return (offset == 0)? base: basic_plus_adr(base, MakeConX(offset)); - } -+ Node* basic_plus_adr(Node* base, Node* ptr, int offset) { -+ return (offset == 0)? ptr: basic_plus_adr(base, ptr, MakeConX(offset)); -+ } - Node* basic_plus_adr(Node* base, Node* offset) { -- Node* adr = new (C, 4) AddPNode(base, base, offset); -- _igvn.register_new_node_with_optimizer(adr); -- return adr; -+ return basic_plus_adr(base, base, offset); -+ } -+ Node* basic_plus_adr(Node* base, Node* ptr, Node* offset) { -+ Node* adr = new (C, 4) AddPNode(base, ptr, offset); -+ return transform_later(adr); -+ } -+ Node* transform_later(Node* n) { -+ // equivalent to _gvn.transform in GraphKit, Ideal, etc. -+ _igvn.register_new_node_with_optimizer(n); -+ return n; - } -+ void set_eden_pointers(Node* &eden_top_adr, Node* &eden_end_adr); - Node* make_load( Node* ctl, Node* mem, Node* base, int offset, - const Type* value_type, BasicType bt); - Node* make_store(Node* ctl, Node* mem, Node* base, int offset, -diff -ruNb openjdk6/hotspot/src/share/vm/opto/matcher.cpp openjdk/hotspot/src/share/vm/opto/matcher.cpp ---- openjdk6/hotspot/src/share/vm/opto/matcher.cpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/matcher.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)matcher.cpp 1.386 07/05/05 17:06:19 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -272,6 +269,8 @@ - find_shared( C->root() ); - find_shared( C->top() ); - -+ C->print_method("Before Matching", 2); -+ - // Swap out to old-space; emptying new-space - Arena *old = C->node_arena()->move_contents(C->old_arena()); - -@@ -1803,6 +1802,16 @@ - shift->in(2)->get_int() <= 3 ) { - set_visited(shift); // Flag as visited now - mstack.push(shift->in(2), Visit); -+#ifdef _LP64 -+ // Allow Matcher to match the rule which bypass -+ // ConvI2L operation for an array index on LP64 -+ // if the index value is positive. -+ if( shift->in(1)->Opcode() == Op_ConvI2L && -+ shift->in(1)->as_Type()->type()->is_long()->_lo >= 0 ) { -+ set_visited(shift->in(1)); // Flag as visited now -+ mstack.push(shift->in(1)->in(1), Pre_Visit); -+ } else -+#endif - mstack.push(shift->in(1), Pre_Visit); - } else { - mstack.push(shift, Pre_Visit); -@@ -2112,4 +2121,3 @@ - _kids[i]->dump(depth+1); - } - #endif -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/matcher.hpp openjdk/hotspot/src/share/vm/opto/matcher.hpp ---- openjdk6/hotspot/src/share/vm/opto/matcher.hpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/matcher.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)matcher.hpp 1.187 07/05/05 17:06:19 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -234,6 +231,11 @@ - // Vector ideal reg - static const uint vector_ideal_reg(void); - -+ // Used to determine a "low complexity" 64-bit constant. (Zero is simple.) -+ // The standard of comparison is one (StoreL ConL) vs. two (StoreI ConI). -+ // Depends on the details of 64-bit constant generation on the CPU. -+ static const bool isSimpleConstant64(jlong con); -+ - // These calls are all generated by the ADLC - - // TRUE - grows up, FALSE - grows down (Intel) -@@ -321,6 +323,13 @@ - // Is this branch offset small enough to be addressed by a short branch? - bool is_short_branch_offset(int offset); - -+ // Optional scaling for the parameter to the ClearArray/CopyArray node. -+ static const bool init_array_count_is_in_bytes; -+ -+ // Threshold small size (in bytes) for a ClearArray/CopyArray node. -+ // Anything this size or smaller may get converted to discrete scalar stores. -+ static const int init_array_short_size; -+ - // Should the Matcher clone shifts on addressing modes, expecting them to - // be subsumed into complex addressing expressions or compute them into - // registers? True for Intel but false for most RISCs -diff -ruNb openjdk6/hotspot/src/share/vm/opto/memnode.cpp openjdk/hotspot/src/share/vm/opto/memnode.cpp ---- openjdk6/hotspot/src/share/vm/opto/memnode.cpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/memnode.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)memnode.cpp 1.238 08/06/19 10:10:54 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -43,7 +40,7 @@ - } - - #ifndef PRODUCT --void MemNode::dump_spec() const { -+void MemNode::dump_spec(outputStream *st) const { - if (in(Address) == NULL) return; // node is dead - #ifndef ASSERT - // fake the missing field -@@ -51,37 +48,37 @@ - if (in(Address) != NULL) - _adr_type = in(Address)->bottom_type()->isa_ptr(); - #endif -- dump_adr_type(this, _adr_type); -+ dump_adr_type(this, _adr_type, st); - - Compile* C = Compile::current(); - if( C->alias_type(_adr_type)->is_volatile() ) -- tty->print(" Volatile!"); -+ st->print(" Volatile!"); - } - --void MemNode::dump_adr_type(const Node* mem, const TypePtr* adr_type) { -- tty->print(" @"); -+void MemNode::dump_adr_type(const Node* mem, const TypePtr* adr_type, outputStream *st) { -+ st->print(" @"); - if (adr_type == NULL) { -- tty->print("NULL"); -+ st->print("NULL"); - } else { -- adr_type->dump(); -+ adr_type->dump_on(st); - Compile* C = Compile::current(); - Compile::AliasType* atp = NULL; - if (C->have_alias_type(adr_type)) atp = C->alias_type(adr_type); - if (atp == NULL) -- tty->print(", idx=?\?;"); -+ st->print(", idx=?\?;"); - else if (atp->index() == Compile::AliasIdxBot) -- tty->print(", idx=Bot;"); -+ st->print(", idx=Bot;"); - else if (atp->index() == Compile::AliasIdxTop) -- tty->print(", idx=Top;"); -+ st->print(", idx=Top;"); - else if (atp->index() == Compile::AliasIdxRaw) -- tty->print(", idx=Raw;"); -+ st->print(", idx=Raw;"); - else { - ciField* field = atp->field(); - if (field) { -- tty->print(", name="); -- field->print_name_on(tty); -+ st->print(", name="); -+ field->print_name_on(st); - } -- tty->print(", idx=%d;", atp->index()); -+ st->print(", idx=%d;", atp->index()); - } - } - } -@@ -111,6 +108,20 @@ - // Avoid independent memory operations - Node* old_mem = mem; - -+ if (mem->is_Proj() && mem->in(0)->is_Initialize()) { -+ InitializeNode* init = mem->in(0)->as_Initialize(); -+ if (init->is_complete()) { // i.e., after macro expansion -+ const TypePtr* tp = t_adr->is_ptr(); -+ uint alias_idx = phase->C->get_alias_index(tp); -+ // Free this slice from the init. It was hooked, temporarily, -+ // by GraphKit::set_output_for_allocation. -+ if (alias_idx > Compile::AliasIdxRaw) { -+ mem = init->memory(alias_idx); -+ // ...but not with the raw-pointer slice. -+ } -+ } -+ } -+ - if (mem->is_MergeMem()) { - MergeMemNode* mmem = mem->as_MergeMem(); - const TypePtr *tp = t_adr->is_ptr(); -@@ -167,6 +178,65 @@ - return NULL; - } - -+// Helper function for proving some simple control dominations. -+// Attempt to prove that control input 'dom' dominates (or equals) 'sub'. -+// Already assumes that 'dom' is available at 'sub', and that 'sub' -+// is not a constant (dominated by the method's StartNode). -+// Used by MemNode::find_previous_store to prove that the -+// control input of a memory operation predates (dominates) -+// an allocation it wants to look past. -+bool MemNode::detect_dominating_control(Node* dom, Node* sub) { -+ if (dom == NULL) return false; -+ if (dom->is_Proj()) dom = dom->in(0); -+ if (dom->is_Start()) return true; // anything inside the method -+ if (dom->is_Root()) return true; // dom 'controls' a constant -+ int cnt = 20; // detect cycle or too much effort -+ while (sub != NULL) { // walk 'sub' up the chain to 'dom' -+ if (--cnt < 0) return false; // in a cycle or too complex -+ if (sub == dom) return true; -+ if (sub->is_Start()) return false; -+ if (sub->is_Root()) return false; -+ Node* up = sub->in(0); -+ if (sub == up && sub->is_Region()) { -+ for (uint i = 1; i < sub->req(); i++) { -+ Node* in = sub->in(i); -+ if (in != NULL && !in->is_top() && in != sub) { -+ up = in; break; // take any path on the way up to 'dom' -+ } -+ } -+ } -+ if (sub == up) return false; // some kind of tight cycle -+ sub = up; -+ } -+ return false; -+} -+ -+//---------------------detect_ptr_independence--------------------------------- -+// Used by MemNode::find_previous_store to prove that two base -+// pointers are never equal. -+// The pointers are accompanied by their associated allocations, -+// if any, which have been previously discovered by the caller. -+bool MemNode::detect_ptr_independence(Node* p1, AllocateNode* a1, -+ Node* p2, AllocateNode* a2, -+ PhaseTransform* phase) { -+ // Attempt to prove that these two pointers cannot be aliased. -+ // They may both manifestly be allocations, and they should differ. -+ // Or, if they are not both allocations, they can be distinct constants. -+ // Otherwise, one is an allocation and the other a pre-existing value. -+ if (a1 == NULL && a2 == NULL) { // neither an allocation -+ return (p1 != p2) && p1->is_Con() && p2->is_Con(); -+ } else if (a1 != NULL && a2 != NULL) { // both allocations -+ return (a1 != a2); -+ } else if (a1 != NULL) { // one allocation a1 -+ // (Note: p2->is_Con implies p2->in(0)->is_Root, which dominates.) -+ return detect_dominating_control(p2->in(0), a1->in(0)); -+ } else { //(a2 != NULL) // one allocation a2 -+ return detect_dominating_control(p1->in(0), a2->in(0)); -+ } -+ return false; -+} -+ -+ - // The logic for reordering loads and stores uses four steps: - // (a) Walk carefully past stores and initializations which we - // can prove are independent of this load. -@@ -218,6 +288,15 @@ - continue; // (a) advance through independent store memory - } - } -+ if (st_base != base && -+ detect_ptr_independence(base, alloc, -+ st_base, -+ AllocateNode::Ideal_allocation(st_base, phase), -+ phase)) { -+ // Success: The bases are provably independent. -+ mem = mem->in(MemNode::Memory); -+ continue; // (a) advance through independent store memory -+ } - - // (b) At this point, if the bases or offsets do not agree, we lose, - // since we have not managed to prove 'this' and 'mem' independent. -@@ -225,6 +304,41 @@ - return mem; // let caller handle steps (c), (d) - } - -+ } else if (mem->is_Proj() && mem->in(0)->is_Initialize()) { -+ InitializeNode* st_init = mem->in(0)->as_Initialize(); -+ AllocateNode* st_alloc = st_init->allocation(); -+ if (st_alloc == NULL) -+ break; // something degenerated -+ bool known_identical = false; -+ bool known_independent = false; -+ if (alloc == st_alloc) -+ known_identical = true; -+ else if (alloc != NULL) -+ known_independent = true; -+ else if (ctrl != NULL && -+ detect_dominating_control(ctrl, st_alloc->in(0))) -+ known_independent = true; -+ -+ if (known_independent) { -+ // The bases are provably independent: Either they are -+ // manifestly distinct allocations, or else the control -+ // of this load dominates the store's allocation. -+ int alias_idx = phase->C->get_alias_index(adr_type()); -+ if (alias_idx == Compile::AliasIdxRaw) { -+ mem = st_alloc->in(TypeFunc::Memory); -+ } else { -+ mem = st_init->memory(alias_idx); -+ } -+ continue; // (a) advance through independent store memory -+ } -+ -+ // (b) at this point, if we are not looking at a store initializing -+ // the same allocation we are loading from, we lose. -+ if (known_identical) { -+ // From caller, can_see_stored_value will consult find_captured_store. -+ return mem; // let caller handle steps (c), (d) -+ } -+ - } - - // Unless there is an explicit 'continue', we must bail out here, -@@ -460,11 +574,11 @@ - } - - #ifndef PRODUCT --void LoadNode::dump_spec() const { -- MemNode::dump_spec(); -+void LoadNode::dump_spec(outputStream *st) const { -+ MemNode::dump_spec(st); - if( !Verbose && !WizardMode ) { - // standard dump does this in Verbose and WizardMode -- tty->print(" #"); _type->dump(); -+ st->print(" #"); _type->dump_on(st); - } - } - #endif -@@ -520,18 +634,67 @@ - Node* MemNode::can_see_stored_value(Node* st, PhaseTransform* phase) const { - Node* ld_adr = in(MemNode::Address); - -+ // Loop around twice in the case Load -> Initialize -> Store. -+ // (See PhaseIterGVN::add_users_to_worklist, which knows about this case.) -+ for (int trip = 0; trip <= 1; trip++) { -+ - if (st->is_Store()) { - Node* st_adr = st->in(MemNode::Address); - if (!phase->eqv(st_adr, ld_adr)) { -- return NULL; -+ // Try harder before giving up... Match raw and non-raw pointers. -+ intptr_t st_off = 0; -+ AllocateNode* alloc = AllocateNode::Ideal_allocation(st_adr, phase, st_off); -+ if (alloc == NULL) return NULL; -+ intptr_t ld_off = 0; -+ AllocateNode* allo2 = AllocateNode::Ideal_allocation(ld_adr, phase, ld_off); -+ if (alloc != allo2) return NULL; -+ if (ld_off != st_off) return NULL; -+ // At this point we have proven something like this setup: -+ // A = Allocate(...) -+ // L = LoadQ(, AddP(CastPP(, A.Parm),, #Off)) -+ // S = StoreQ(, AddP(, A.Parm , #Off), V) -+ // (Actually, we haven't yet proven the Q's are the same.) -+ // In other words, we are loading from a casted version of -+ // the same pointer-and-offset that we stored to. -+ // Thus, we are able to replace L by V. - } - // Now prove that we have a LoadQ matched to a StoreQ, for some Q. -- if (store_Opcode() != st->Opcode()) { -+ if (store_Opcode() != st->Opcode()) - return NULL; -- } - return st->in(MemNode::ValueIn); - } - -+ intptr_t offset = 0; // scratch -+ -+ // A load from a freshly-created object always returns zero. -+ // (This can happen after LoadNode::Ideal resets the load's memory input -+ // to find_captured_store, which returned InitializeNode::zero_memory.) -+ if (st->is_Proj() && st->in(0)->is_Allocate() && -+ st->in(0) == AllocateNode::Ideal_allocation(ld_adr, phase, offset) && -+ offset >= st->in(0)->as_Allocate()->minimum_header_size()) { -+ // return a zero value for the load's basic type -+ // (This is one of the few places where a generic PhaseTransform -+ // can create new nodes. Think of it as lazily manifesting -+ // virtually pre-existing constants.) -+ return phase->zerocon(memory_type()); -+ } -+ -+ // A load from an initialization barrier can match a captured store. -+ if (st->is_Proj() && st->in(0)->is_Initialize()) { -+ InitializeNode* init = st->in(0)->as_Initialize(); -+ AllocateNode* alloc = init->allocation(); -+ if (alloc != NULL && -+ alloc == AllocateNode::Ideal_allocation(ld_adr, phase, offset)) { -+ // examine a captured store value -+ st = init->find_captured_store(offset, memory_size(), phase); -+ if (st != NULL) -+ continue; // take one more trip around -+ } -+ } -+ -+ break; -+ } -+ - return NULL; - } - -@@ -563,6 +726,8 @@ - //------------------------------Ideal------------------------------------------ - // If the load is from Field memory and the pointer is non-null, we can - // zero out the control input. -+// If the offset is constant and the base is an object allocation, -+// try to hook me up to the exact initializing store. - Node *LoadNode::Ideal(PhaseGVN *phase, bool can_reshape) { - Node* p = MemNode::Ideal_common(phase, can_reshape); - if (p) return (p == NodeSentinel) ? NULL : p; -@@ -578,16 +743,19 @@ - set_req(MemNode::Control,ctrl); - } - -- // Check for useless memory edge in some common special cases -- if( in(MemNode::Control) ) { -- Node *adr = address->is_AddP() ? address->in(AddPNode::Base) : address; -- if( adr->is_Proj() && adr->as_Proj()->_con == TypeFunc::Parms && -- adr->in(0)->is_Start() && phase->type(adr)->is_ptr()->_ptr == TypePtr::NotNull ) { -+ // Check for useless control edge in some common special cases -+ if (in(MemNode::Control) != NULL) { -+ intptr_t ignore = 0; -+ Node* base = AddPNode::Ideal_base_and_offset(address, phase, ignore); -+ if (base != NULL -+ && phase->type(base)->higher_equal(TypePtr::NOTNULL) -+ && detect_dominating_control(base->in(0), phase->C->start())) { -+ // A method-invariant, non-null address (constant or 'this' argument). - set_req(MemNode::Control, NULL); - } - } - -- // Check for prior array store with a different offset; make Load -+ // Check for prior store with a different base or offset; make Load - // independent. Skip through any number of them. Bail out if the stores - // are in an endless dead cycle and report no progress. This is a key - // transform for Reflection. However, if after skipping through the Stores -@@ -794,7 +962,14 @@ - } - } - -- // (If loading from a freshly-allocated object, could produce zero here.) -+ // If we are loading from a freshly-allocated object, produce a zero, -+ // if the load is provably beyond the header of the object. -+ // (Also allow a variable load from a fresh array to produce zero.) -+ if (ReduceFieldZeroing) { -+ Node* value = can_see_stored_value(mem,phase); -+ if (value != NULL && value->is_Con()) -+ return value->bottom_type(); -+ } - - return _type; - } -@@ -974,6 +1149,13 @@ - // according to the element type's subclassing. - return TypeKlassPtr::make(tkls->ptr(), elem, 0/*offset*/); - } -+ if( klass->is_instance_klass() && tkls->klass_is_exact() && -+ (uint)tkls->offset() == Klass::super_offset_in_bytes() + sizeof(oopDesc)) { -+ ciKlass* sup = klass->as_instance_klass()->super(); -+ // The field is Klass::_super. Return its (constant) value. -+ // (Folds up the 2nd indirection in aClassConstant.getSuperClass().) -+ return sup ? TypeKlassPtr::make(sup) : TypePtr::NULL_PTR; -+ } - } - - // Bailout case -@@ -1082,8 +1264,8 @@ - } - - return this; --} - -+} - //============================================================================= - //---------------------------StoreNode::make----------------------------------- - // Polymorphic factory method: -@@ -1126,6 +1308,8 @@ - - //------------------------------Ideal------------------------------------------ - // Change back-to-back Store(, p, x) -> Store(m, p, y) to Store(m, p, x). -+// When a store immediately follows a relevant allocation/initialization, -+// try to capture it into the initialization, or hoist it above. - Node *StoreNode::Ideal(PhaseGVN *phase, bool can_reshape) { - Node* p = MemNode::Ideal_common(phase, can_reshape); - if (p) return (p == NodeSentinel) ? NULL : p; -@@ -1135,7 +1319,7 @@ - - // Back-to-back stores to same address? Fold em up. - // Generally unsafe if I have intervening uses... -- if (can_reshape && mem->is_Store() && phase->eqv( mem->in(MemNode::Address), address )) { -+ if (mem->is_Store() && phase->eqv_uncast(mem->in(MemNode::Address), address)) { - // Looking at a dead closed cycle of memory? - assert(mem != mem->in(MemNode::Memory), "dead loop in StoreNode::Ideal"); - -@@ -1163,6 +1347,24 @@ - } - } - -+ // Capture an unaliased, unconditional, simple store into an initializer. -+ // Or, if it is independent of the allocation, hoist it above the allocation. -+ if (ReduceFieldZeroing && /*can_reshape &&*/ -+ mem->is_Proj() && mem->in(0)->is_Initialize()) { -+ InitializeNode* init = mem->in(0)->as_Initialize(); -+ intptr_t offset = init->can_capture_store(this, phase); -+ if (offset > 0) { -+ Node* moved = init->capture_store(this, offset, phase); -+ // If the InitializeNode captured me, it made a raw copy of me, -+ // and I need to disappear. -+ if (moved != NULL) { -+ // %%% hack to ensure that Ideal returns a new node: -+ mem = MergeMemNode::make(phase->C, mem); -+ return mem; // fold me away -+ } -+ } -+ } -+ - return NULL; // No further progress - } - -@@ -1181,6 +1383,7 @@ - //------------------------------Identity--------------------------------------- - // Remove redundant stores: - // Store(m, p, Load(m, p)) changes to m. -+// Store(, p, x) -> Store(m, p, x) changes to Store(m, p, x). - Node *StoreNode::Identity( PhaseTransform *phase ) { - Node* mem = in(MemNode::Memory); - Node* adr = in(MemNode::Address); -@@ -1188,12 +1391,42 @@ - - // Load then Store? Then the Store is useless - if (val->is_Load() && -- val->as_Load()->memory_size() == this->memory_size() && -- phase->eqv( val->in(MemNode::Address), adr ) && -- phase->eqv( val->in(MemNode::Memory ), mem )) { -+ phase->eqv_uncast( val->in(MemNode::Address), adr ) && -+ phase->eqv_uncast( val->in(MemNode::Memory ), mem ) && -+ val->as_Load()->store_Opcode() == Opcode()) { -+ return mem; -+ } -+ -+ // Two stores in a row of the same value? -+ if (mem->is_Store() && -+ phase->eqv_uncast( mem->in(MemNode::Address), adr ) && -+ phase->eqv_uncast( mem->in(MemNode::ValueIn), val ) && -+ mem->Opcode() == Opcode()) { -+ return mem; -+ } -+ -+ // Store of zero anywhere into a freshly-allocated object? -+ // Then the store is useless. -+ // (It must already have been captured by the InitializeNode.) -+ if (ReduceFieldZeroing && phase->type(val)->is_zero_type()) { -+ // a newly allocated object is already all-zeroes everywhere -+ if (mem->is_Proj() && mem->in(0)->is_Allocate()) { - return mem; - } - -+ // the store may also apply to zero-bits in an earlier object -+ Node* prev_mem = find_previous_store(phase); -+ // Steps (a), (b): Walk past independent stores to find an exact match. -+ if (prev_mem != NULL) { -+ Node* prev_val = can_see_stored_value(prev_mem, phase); -+ if (prev_val != NULL && phase->eqv(prev_val, val)) { -+ // prev_val and val might differ by a cast; it would be good -+ // to keep the more informative of the two. -+ return mem; -+ } -+ } -+ } -+ - return this; - } - -@@ -1320,16 +1553,9 @@ - - //------------------------------Value----------------------------------------- - const Type *StoreCMNode::Value( PhaseTransform *phase ) const { -- // Either input is TOP ==> the result is TOP -- const Type *t = phase->type( in(MemNode::Memory) ); -- if( t == Type::TOP ) return Type::TOP; -- t = phase->type( in(MemNode::Address) ); -- if( t == Type::TOP ) return Type::TOP; -- t = phase->type( in(MemNode::ValueIn) ); -- if( t == Type::TOP ) return Type::TOP; - // If extra input is TOP ==> the result is TOP -- t = phase->type( in(MemNode::OopStore) ); -- if( t == Type::TOP ) return Type::TOP; -+ const Type *t1 = phase->type( in(MemNode::OopStore) ); -+ if( t1 == Type::TOP ) return Type::TOP; - - return StoreNode::Value( phase ); - } -@@ -1376,16 +1602,20 @@ - //------------------------------Idealize--------------------------------------- - // Clearing a short array is faster with stores - Node *ClearArrayNode::Ideal(PhaseGVN *phase, bool can_reshape){ -- const TypeInt *t = phase->type(in(2))->isa_int(); -- if( !t ) return NULL; -- if( !t->is_con() ) return NULL; -- int con = t->get_con(); // Length is in doublewords -- // Length too long; use fast hardware clear -- if( con > 8 ) return NULL; -+ const int unit = BytesPerLong; -+ const TypeX* t = phase->type(in(2))->isa_intptr_t(); -+ if (!t) return NULL; -+ if (!t->is_con()) return NULL; -+ intptr_t raw_count = t->get_con(); -+ intptr_t size = raw_count; -+ if (!Matcher::init_array_count_is_in_bytes) size *= unit; - // Clearing nothing uses the Identity call. - // Negative clears are possible on dead ClearArrays - // (see jck test stmt114.stmt11402.val). -- if( con <= 0 ) return NULL; -+ if (size <= 0 || size % unit != 0) return NULL; -+ intptr_t count = size / unit; -+ // Length too long; use fast hardware clear -+ if (size > Matcher::init_array_short_size) return NULL; - Node *mem = in(1); - if( phase->type(mem)==Type::TOP ) return NULL; - Node *adr = in(3); -@@ -1402,8 +1632,8 @@ - Node *zero = phase->makecon(TypeLong::ZERO); - Node *off = phase->MakeConX(BytesPerLong); - mem = new (phase->C, 4) StoreLNode(in(0),mem,adr,atp,zero); -- con--; -- while( con-- ) { -+ count--; -+ while( count-- ) { - mem = phase->transform(mem); - adr = phase->transform(new (phase->C, 4) AddPNode(base,adr,off)); - mem = new (phase->C, 4) StoreLNode(in(0),mem,adr,atp,zero); -@@ -1421,8 +1651,7 @@ - intptr_t offset = start_offset; - - int unit = BytesPerLong; -- -- if (unit == BytesPerLong && (offset % BytesPerLong) != 0) { -+ if ((offset % unit) != 0) { - Node* adr = new (C, 4) AddPNode(dest, dest, phase->MakeConX(offset)); - adr = phase->transform(adr); - const TypePtr* atp = TypeRawPtr::BOTTOM; -@@ -1433,20 +1662,60 @@ - assert((offset % unit) == 0, ""); - - // Initialize the remaining stuff, if any, with a ClearArray. -- Node* zbase = phase->MakeConX(offset); -- Node* zsize = phase->transform( new (C, 3) SubXNode(end_offset, zbase) ); -- Node* zinit = phase->zerocon((unit == BytesPerLong) ? T_LONG : T_INT); -+ return clear_memory(ctl, mem, dest, phase->MakeConX(offset), end_offset, phase); -+} -+ -+Node* ClearArrayNode::clear_memory(Node* ctl, Node* mem, Node* dest, -+ Node* start_offset, -+ Node* end_offset, -+ PhaseGVN* phase) { -+ Compile* C = phase->C; -+ int unit = BytesPerLong; -+ Node* zbase = start_offset; -+ Node* zend = end_offset; - - // Scale to the unit required by the CPU: -+ if (!Matcher::init_array_count_is_in_bytes) { - Node* shift = phase->intcon(exact_log2(unit)); -- zsize = phase->transform( new (C, 3) URShiftXNode(zsize, shift) ); -+ zbase = phase->transform( new(C,3) URShiftXNode(zbase, shift) ); -+ zend = phase->transform( new(C,3) URShiftXNode(zend, shift) ); -+ } -+ -+ Node* zsize = phase->transform( new(C,3) SubXNode(zend, zbase) ); -+ Node* zinit = phase->zerocon((unit == BytesPerLong) ? T_LONG : T_INT); - - // Bulk clear double-words -- Node* adr = phase->transform( new (C, 4) AddPNode(dest, dest, zbase) ); -+ Node* adr = phase->transform( new(C,4) AddPNode(dest, dest, start_offset) ); - mem = new (C, 4) ClearArrayNode(ctl, mem, zsize, adr); - return phase->transform(mem); - } - -+Node* ClearArrayNode::clear_memory(Node* ctl, Node* mem, Node* dest, -+ intptr_t start_offset, -+ intptr_t end_offset, -+ PhaseGVN* phase) { -+ Compile* C = phase->C; -+ assert((end_offset % BytesPerInt) == 0, "odd end offset"); -+ intptr_t done_offset = end_offset; -+ if ((done_offset % BytesPerLong) != 0) { -+ done_offset -= BytesPerInt; -+ } -+ if (done_offset > start_offset) { -+ mem = clear_memory(ctl, mem, dest, -+ start_offset, phase->MakeConX(done_offset), phase); -+ } -+ if (done_offset < end_offset) { // emit the final 32-bit store -+ Node* adr = new (C, 4) AddPNode(dest, dest, phase->MakeConX(done_offset)); -+ adr = phase->transform(adr); -+ const TypePtr* atp = TypeRawPtr::BOTTOM; -+ mem = StoreNode::make(C, ctl, mem, adr, atp, phase->zerocon(T_INT), T_INT); -+ mem = phase->transform(mem); -+ done_offset += BytesPerInt; -+ } -+ assert(done_offset == end_offset, ""); -+ return mem; -+} -+ - //============================================================================= - // Do we match on this edge? No memory edges - uint StrCompNode::match_edge(uint idx) const { -@@ -1489,6 +1758,7 @@ - case Op_MemBarRelease: return new(C, len) MemBarReleaseNode(C, atp, pn); - case Op_MemBarVolatile: return new(C, len) MemBarVolatileNode(C, atp, pn); - case Op_MemBarCPUOrder: return new(C, len) MemBarCPUOrderNode(C, atp, pn); -+ case Op_Initialize: return new(C, len) InitializeNode(C, atp, pn); - default: ShouldNotReachHere(); return NULL; - } - } -@@ -1521,7 +1791,900 @@ - return NULL; - } - --//============================================================================= -+//===========================InitializeNode==================================== -+// SUMMARY: -+// This node acts as a memory barrier on raw memory, after some raw stores. -+// The 'cooked' oop value feeds from the Initialize, not the Allocation. -+// The Initialize can 'capture' suitably constrained stores as raw inits. -+// It can coalesce related raw stores into larger units (called 'tiles'). -+// It can avoid zeroing new storage for memory units which have raw inits. -+// At macro-expansion, it is marked 'complete', and does not optimize further. -+// -+// EXAMPLE: -+// The object 'new short[2]' occupies 16 bytes in a 32-bit machine. -+// ctl = incoming control; mem* = incoming memory -+// (Note: A star * on a memory edge denotes I/O and other standard edges.) -+// First allocate uninitialized memory and fill in the header: -+// alloc = (Allocate ctl mem* 16 #short[].klass ...) -+// ctl := alloc.Control; mem* := alloc.Memory* -+// rawmem = alloc.Memory; rawoop = alloc.RawAddress -+// Then initialize to zero the non-header parts of the raw memory block: -+// init = (Initialize alloc.Control alloc.Memory* alloc.RawAddress) -+// ctl := init.Control; mem.SLICE(#short[*]) := init.Memory -+// After the initialize node executes, the object is ready for service: -+// oop := (CheckCastPP init.Control alloc.RawAddress #short[]) -+// Suppose its body is immediately initialized as {1,2}: -+// store1 = (StoreC init.Control init.Memory (+ oop 12) 1) -+// store2 = (StoreC init.Control store1 (+ oop 14) 2) -+// mem.SLICE(#short[*]) := store2 -+// -+// DETAILS: -+// An InitializeNode collects and isolates object initialization after -+// an AllocateNode and before the next possible safepoint. As a -+// memory barrier (MemBarNode), it keeps critical stores from drifting -+// down past any safepoint or any publication of the allocation. -+// Before this barrier, a newly-allocated object may have uninitialized bits. -+// After this barrier, it may be treated as a real oop, and GC is allowed. -+// -+// The semantics of the InitializeNode include an implicit zeroing of -+// the new object from object header to the end of the object. -+// (The object header and end are determined by the AllocateNode.) -+// -+// Certain stores may be added as direct inputs to the InitializeNode. -+// These stores must update raw memory, and they must be to addresses -+// derived from the raw address produced by AllocateNode, and with -+// a constant offset. They must be ordered by increasing offset. -+// The first one is at in(RawStores), the last at in(req()-1). -+// Unlike most memory operations, they are not linked in a chain, -+// but are displayed in parallel as users of the rawmem output of -+// the allocation. -+// -+// (See comments in InitializeNode::capture_store, which continue -+// the example given above.) -+// -+// When the associated Allocate is macro-expanded, the InitializeNode -+// may be rewritten to optimize collected stores. A ClearArrayNode -+// may also be created at that point to represent any required zeroing. -+// The InitializeNode is then marked 'complete', prohibiting further -+// capturing of nearby memory operations. -+// -+// During macro-expansion, all captured initializations which store -+// constant values of 32 bits or smaller are coalesced (if advantagous) -+// into larger 'tiles' 32 or 64 bits. This allows an object to be -+// initialized in fewer memory operations. Memory words which are -+// covered by neither tiles nor non-constant stores are pre-zeroed -+// by explicit stores of zero. (The code shape happens to do all -+// zeroing first, then all other stores, with both sequences occurring -+// in order of ascending offsets.) -+// -+// Alternatively, code may be inserted between an AllocateNode and its -+// InitializeNode, to perform arbitrary initialization of the new object. -+// E.g., the object copying intrinsics insert complex data transfers here. -+// The initialization must then be marked as 'complete' disable the -+// built-in zeroing semantics and the collection of initializing stores. -+// -+// While an InitializeNode is incomplete, reads from the memory state -+// produced by it are optimizable if they match the control edge and -+// new oop address associated with the allocation/initialization. -+// They return a stored value (if the offset matches) or else zero. -+// A write to the memory state, if it matches control and address, -+// and if it is to a constant offset, may be 'captured' by the -+// InitializeNode. It is cloned as a raw memory operation and rewired -+// inside the initialization, to the raw oop produced by the allocation. -+// Operations on addresses which are provably distinct (e.g., to -+// other AllocateNodes) are allowed to bypass the initialization. -+// -+// The effect of all this is to consolidate object initialization -+// (both arrays and non-arrays, both piecewise and bulk) into a -+// single location, where it can be optimized as a unit. -+// -+// Only stores with an offset less than TrackedInitializationLimit words -+// will be considered for capture by an InitializeNode. This puts a -+// reasonable limit on the complexity of optimized initializations. -+ -+//---------------------------InitializeNode------------------------------------ -+InitializeNode::InitializeNode(Compile* C, int adr_type, Node* rawoop) -+ : _is_complete(false), -+ MemBarNode(C, adr_type, rawoop) -+{ -+ init_class_id(Class_Initialize); -+ -+ assert(adr_type == Compile::AliasIdxRaw, "only valid atp"); -+ assert(in(RawAddress) == rawoop, "proper init"); -+ // Note: allocation() can be NULL, for secondary initialization barriers -+} -+ -+// Since this node is not matched, it will be processed by the -+// register allocator. Declare that there are no constraints -+// on the allocation of the RawAddress edge. -+const RegMask &InitializeNode::in_RegMask(uint idx) const { -+ // This edge should be set to top, by the set_complete. But be conservative. -+ if (idx == InitializeNode::RawAddress) -+ return *(Compile::current()->matcher()->idealreg2spillmask[in(idx)->ideal_reg()]); -+ return RegMask::Empty; -+} -+ -+Node* InitializeNode::memory(uint alias_idx) { -+ Node* mem = in(Memory); -+ if (mem->is_MergeMem()) { -+ return mem->as_MergeMem()->memory_at(alias_idx); -+ } else { -+ // incoming raw memory is not split -+ return mem; -+ } -+} -+ -+bool InitializeNode::is_non_zero() { -+ if (is_complete()) return false; -+ remove_extra_zeroes(); -+ return (req() > RawStores); -+} -+ -+void InitializeNode::set_complete(PhaseGVN* phase) { -+ assert(!is_complete(), "caller responsibility"); -+ _is_complete = true; -+ -+ // After this node is complete, it contains a bunch of -+ // raw-memory initializations. There is no need for -+ // it to have anything to do with non-raw memory effects. -+ // Therefore, tell all non-raw users to re-optimize themselves, -+ // after skipping the memory effects of this initialization. -+ PhaseIterGVN* igvn = phase->is_IterGVN(); -+ if (igvn) igvn->add_users_to_worklist(this); -+} -+ -+// convenience function -+// return false if the init contains any stores already -+bool AllocateNode::maybe_set_complete(PhaseGVN* phase) { -+ InitializeNode* init = initialization(); -+ if (init == NULL || init->is_complete()) return false; -+ init->remove_extra_zeroes(); -+ // for now, if this allocation has already collected any inits, bail: -+ if (init->is_non_zero()) return false; -+ init->set_complete(phase); -+ return true; -+} -+ -+void InitializeNode::remove_extra_zeroes() { -+ if (req() == RawStores) return; -+ Node* zmem = zero_memory(); -+ uint fill = RawStores; -+ for (uint i = fill; i < req(); i++) { -+ Node* n = in(i); -+ if (n->is_top() || n == zmem) continue; // skip -+ if (fill < i) set_req(fill, n); // compact -+ ++fill; -+ } -+ // delete any empty spaces created: -+ while (fill < req()) { -+ del_req(fill); -+ } -+} -+ -+// Helper for remembering which stores go with which offsets. -+intptr_t InitializeNode::get_store_offset(Node* st, PhaseTransform* phase) { -+ if (!st->is_Store()) return -1; // can happen to dead code via subsume_node -+ intptr_t offset = -1; -+ Node* base = AddPNode::Ideal_base_and_offset(st->in(MemNode::Address), -+ phase, offset); -+ if (base == NULL) return -1; // something is dead, -+ if (offset < 0) return -1; // dead, dead -+ return offset; -+} -+ -+// Helper for proving that an initialization expression is -+// "simple enough" to be folded into an object initialization. -+// Attempts to prove that a store's initial value 'n' can be captured -+// within the initialization without creating a vicious cycle, such as: -+// { Foo p = new Foo(); p.next = p; } -+// True for constants and parameters and small combinations thereof. -+bool InitializeNode::detect_init_independence(Node* n, -+ bool st_is_pinned, -+ int& count) { -+ if (n == NULL) return true; // (can this really happen?) -+ if (n->is_Proj()) n = n->in(0); -+ if (n == this) return false; // found a cycle -+ if (n->is_Con()) return true; -+ if (n->is_Start()) return true; // params, etc., are OK -+ if (n->is_Root()) return true; // even better -+ -+ Node* ctl = n->in(0); -+ if (ctl != NULL && !ctl->is_top()) { -+ if (ctl->is_Proj()) ctl = ctl->in(0); -+ if (ctl == this) return false; -+ -+ // If we already know that the enclosing memory op is pinned right after -+ // the init, then any control flow that the store has picked up -+ // must have preceded the init, or else be equal to the init. -+ // Even after loop optimizations (which might change control edges) -+ // a store is never pinned *before* the availability of its inputs. -+ if (!MemNode::detect_dominating_control(ctl, this->in(0))) -+ return false; // failed to prove a good control -+ -+ } -+ -+ // Check data edges for possible dependencies on 'this'. -+ if ((count += 1) > 20) return false; // complexity limit -+ for (uint i = 1; i < n->req(); i++) { -+ Node* m = n->in(i); -+ if (m == NULL || m == n || m->is_top()) continue; -+ uint first_i = n->find_edge(m); -+ if (i != first_i) continue; // process duplicate edge just once -+ if (!detect_init_independence(m, st_is_pinned, count)) { -+ return false; -+ } -+ } -+ -+ return true; -+} -+ -+// Here are all the checks a Store must pass before it can be moved into -+// an initialization. Returns zero if a check fails. -+// On success, returns the (constant) offset to which the store applies, -+// within the initialized memory. -+intptr_t InitializeNode::can_capture_store(StoreNode* st, PhaseTransform* phase) { -+ const int FAIL = 0; -+ if (st->req() != MemNode::ValueIn + 1) -+ return FAIL; // an inscrutable StoreNode (card mark?) -+ Node* ctl = st->in(MemNode::Control); -+ if (!(ctl != NULL && ctl->is_Proj() && ctl->in(0) == this)) -+ return FAIL; // must be unconditional after the initialization -+ Node* mem = st->in(MemNode::Memory); -+ if (!(mem->is_Proj() && mem->in(0) == this)) -+ return FAIL; // must not be preceded by other stores -+ Node* adr = st->in(MemNode::Address); -+ intptr_t offset; -+ AllocateNode* alloc = AllocateNode::Ideal_allocation(adr, phase, offset); -+ if (alloc == NULL) -+ return FAIL; // inscrutable address -+ if (alloc != allocation()) -+ return FAIL; // wrong allocation! (store needs to float up) -+ Node* val = st->in(MemNode::ValueIn); -+ int complexity_count = 0; -+ if (!detect_init_independence(val, true, complexity_count)) -+ return FAIL; // stored value must be 'simple enough' -+ -+ return offset; // success -+} -+ -+// Find the captured store in(i) which corresponds to the range -+// [start..start+size) in the initialized object. -+// If there is one, return its index i. If there isn't, return the -+// negative of the index where it should be inserted. -+// Return 0 if the queried range overlaps an initialization boundary -+// or if dead code is encountered. -+// If size_in_bytes is zero, do not bother with overlap checks. -+int InitializeNode::captured_store_insertion_point(intptr_t start, -+ int size_in_bytes, -+ PhaseTransform* phase) { -+ const int FAIL = 0, MAX_STORE = BytesPerLong; -+ -+ if (is_complete()) -+ return FAIL; // arraycopy got here first; punt -+ -+ assert(allocation() != NULL, "must be present"); -+ -+ // no negatives, no header fields: -+ if (start < (intptr_t) sizeof(oopDesc)) return FAIL; -+ if (start < (intptr_t) sizeof(arrayOopDesc) && -+ start < (intptr_t) allocation()->minimum_header_size()) return FAIL; -+ -+ // after a certain size, we bail out on tracking all the stores: -+ intptr_t ti_limit = (TrackedInitializationLimit * HeapWordSize); -+ if (start >= ti_limit) return FAIL; -+ -+ for (uint i = InitializeNode::RawStores, limit = req(); ; ) { -+ if (i >= limit) return -(int)i; // not found; here is where to put it -+ -+ Node* st = in(i); -+ intptr_t st_off = get_store_offset(st, phase); -+ if (st_off < 0) { -+ if (st != zero_memory()) { -+ return FAIL; // bail out if there is dead garbage -+ } -+ } else if (st_off > start) { -+ // ...we are done, since stores are ordered -+ if (st_off < start + size_in_bytes) { -+ return FAIL; // the next store overlaps -+ } -+ return -(int)i; // not found; here is where to put it -+ } else if (st_off < start) { -+ if (size_in_bytes != 0 && -+ start < st_off + MAX_STORE && -+ start < st_off + st->as_Store()->memory_size()) { -+ return FAIL; // the previous store overlaps -+ } -+ } else { -+ if (size_in_bytes != 0 && -+ st->as_Store()->memory_size() != size_in_bytes) { -+ return FAIL; // mismatched store size -+ } -+ return i; -+ } -+ -+ ++i; -+ } -+} -+ -+// Look for a captured store which initializes at the offset 'start' -+// with the given size. If there is no such store, and no other -+// initialization interferes, then return zero_memory (the memory -+// projection of the AllocateNode). -+Node* InitializeNode::find_captured_store(intptr_t start, int size_in_bytes, -+ PhaseTransform* phase) { -+ assert(stores_are_sane(phase), ""); -+ int i = captured_store_insertion_point(start, size_in_bytes, phase); -+ if (i == 0) { -+ return NULL; // something is dead -+ } else if (i < 0) { -+ return zero_memory(); // just primordial zero bits here -+ } else { -+ Node* st = in(i); // here is the store at this position -+ assert(get_store_offset(st->as_Store(), phase) == start, "sanity"); -+ return st; -+ } -+} -+ -+// Create, as a raw pointer, an address within my new object at 'offset'. -+Node* InitializeNode::make_raw_address(intptr_t offset, -+ PhaseTransform* phase) { -+ Node* addr = in(RawAddress); -+ if (offset != 0) { -+ Compile* C = phase->C; -+ addr = phase->transform( new (C, 4) AddPNode(C->top(), addr, -+ phase->MakeConX(offset)) ); -+ } -+ return addr; -+} -+ -+// Clone the given store, converting it into a raw store -+// initializing a field or element of my new object. -+// Caller is responsible for retiring the original store, -+// with subsume_node or the like. -+// -+// From the example above InitializeNode::InitializeNode, -+// here are the old stores to be captured: -+// store1 = (StoreC init.Control init.Memory (+ oop 12) 1) -+// store2 = (StoreC init.Control store1 (+ oop 14) 2) -+// -+// Here is the changed code; note the extra edges on init: -+// alloc = (Allocate ...) -+// rawoop = alloc.RawAddress -+// rawstore1 = (StoreC alloc.Control alloc.Memory (+ rawoop 12) 1) -+// rawstore2 = (StoreC alloc.Control alloc.Memory (+ rawoop 14) 2) -+// init = (Initialize alloc.Control alloc.Memory rawoop -+// rawstore1 rawstore2) -+// -+Node* InitializeNode::capture_store(StoreNode* st, intptr_t start, -+ PhaseTransform* phase) { -+ assert(stores_are_sane(phase), ""); -+ -+ if (start < 0) return NULL; -+ assert(can_capture_store(st, phase) == start, "sanity"); -+ -+ Compile* C = phase->C; -+ int size_in_bytes = st->memory_size(); -+ int i = captured_store_insertion_point(start, size_in_bytes, phase); -+ if (i == 0) return NULL; // bail out -+ Node* prev_mem = NULL; // raw memory for the captured store -+ if (i > 0) { -+ prev_mem = in(i); // there is a pre-existing store under this one -+ set_req(i, C->top()); // temporarily disconnect it -+ // See StoreNode::Ideal 'st->outcnt() == 1' for the reason to disconnect. -+ } else { -+ i = -i; // no pre-existing store -+ prev_mem = zero_memory(); // a slice of the newly allocated object -+ if (i > InitializeNode::RawStores && in(i-1) == prev_mem) -+ set_req(--i, C->top()); // reuse this edge; it has been folded away -+ else -+ ins_req(i, C->top()); // build a new edge -+ } -+ Node* new_st = st->clone(); -+ new_st->set_req(MemNode::Control, in(Control)); -+ new_st->set_req(MemNode::Memory, prev_mem); -+ new_st->set_req(MemNode::Address, make_raw_address(start, phase)); -+ new_st = phase->transform(new_st); -+ -+ // At this point, new_st might have swallowed a pre-existing store -+ // at the same offset, or perhaps new_st might have disappeared, -+ // if it redundantly stored the same value (or zero to fresh memory). -+ -+ // In any case, wire it in: -+ set_req(i, new_st); -+ -+ // The caller may now kill the old guy. -+ DEBUG_ONLY(Node* check_st = find_captured_store(start, size_in_bytes, phase)); -+ assert(check_st == new_st || check_st == NULL, "must be findable"); -+ assert(!is_complete(), ""); -+ return new_st; -+} -+ -+static bool store_constant(jlong* tiles, int num_tiles, -+ intptr_t st_off, int st_size, -+ jlong con) { -+ if ((st_off & (st_size-1)) != 0) -+ return false; // strange store offset (assume size==2**N) -+ address addr = (address)tiles + st_off; -+ assert(st_off >= 0 && addr+st_size <= (address)&tiles[num_tiles], "oob"); -+ switch (st_size) { -+ case sizeof(jbyte): *(jbyte*) addr = (jbyte) con; break; -+ case sizeof(jchar): *(jchar*) addr = (jchar) con; break; -+ case sizeof(jint): *(jint*) addr = (jint) con; break; -+ case sizeof(jlong): *(jlong*) addr = (jlong) con; break; -+ default: return false; // strange store size (detect size!=2**N here) -+ } -+ return true; // return success to caller -+} -+ -+// Coalesce subword constants into int constants and possibly -+// into long constants. The goal, if the CPU permits, -+// is to initialize the object with a small number of 64-bit tiles. -+// Also, convert floating-point constants to bit patterns. -+// Non-constants are not relevant to this pass. -+// -+// In terms of the running example on InitializeNode::InitializeNode -+// and InitializeNode::capture_store, here is the transformation -+// of rawstore1 and rawstore2 into rawstore12: -+// alloc = (Allocate ...) -+// rawoop = alloc.RawAddress -+// tile12 = 0x00010002 -+// rawstore12 = (StoreI alloc.Control alloc.Memory (+ rawoop 12) tile12) -+// init = (Initialize alloc.Control alloc.Memory rawoop rawstore12) -+// -+void -+InitializeNode::coalesce_subword_stores(intptr_t header_size, -+ Node* size_in_bytes, -+ PhaseGVN* phase) { -+ Compile* C = phase->C; -+ -+ assert(stores_are_sane(phase), ""); -+ // Note: After this pass, they are not completely sane, -+ // since there may be some overlaps. -+ -+ int old_subword = 0, old_long = 0, new_int = 0, new_long = 0; -+ -+ intptr_t ti_limit = (TrackedInitializationLimit * HeapWordSize); -+ intptr_t size_limit = phase->find_intptr_t_con(size_in_bytes, ti_limit); -+ size_limit = MIN2(size_limit, ti_limit); -+ size_limit = align_size_up(size_limit, BytesPerLong); -+ int num_tiles = size_limit / BytesPerLong; -+ -+ // allocate space for the tile map: -+ const int small_len = DEBUG_ONLY(true ? 3 :) 30; // keep stack frames small -+ jlong tiles_buf[small_len]; -+ Node* nodes_buf[small_len]; -+ jlong inits_buf[small_len]; -+ jlong* tiles = ((num_tiles <= small_len) ? &tiles_buf[0] -+ : NEW_RESOURCE_ARRAY(jlong, num_tiles)); -+ Node** nodes = ((num_tiles <= small_len) ? &nodes_buf[0] -+ : NEW_RESOURCE_ARRAY(Node*, num_tiles)); -+ jlong* inits = ((num_tiles <= small_len) ? &inits_buf[0] -+ : NEW_RESOURCE_ARRAY(jlong, num_tiles)); -+ // tiles: exact bitwise model of all primitive constants -+ // nodes: last constant-storing node subsumed into the tiles model -+ // inits: which bytes (in each tile) are touched by any initializations -+ -+ //// Pass A: Fill in the tile model with any relevant stores. -+ -+ Copy::zero_to_bytes(tiles, sizeof(tiles[0]) * num_tiles); -+ Copy::zero_to_bytes(nodes, sizeof(nodes[0]) * num_tiles); -+ Copy::zero_to_bytes(inits, sizeof(inits[0]) * num_tiles); -+ Node* zmem = zero_memory(); // initially zero memory state -+ for (uint i = InitializeNode::RawStores, limit = req(); i < limit; i++) { -+ Node* st = in(i); -+ intptr_t st_off = get_store_offset(st, phase); -+ -+ // Figure out the store's offset and constant value: -+ if (st_off < header_size) continue; //skip (ignore header) -+ if (st->in(MemNode::Memory) != zmem) continue; //skip (odd store chain) -+ int st_size = st->as_Store()->memory_size(); -+ if (st_off + st_size > size_limit) break; -+ -+ // Record which bytes are touched, whether by constant or not. -+ if (!store_constant(inits, num_tiles, st_off, st_size, (jlong) -1)) -+ continue; // skip (strange store size) -+ -+ const Type* val = phase->type(st->in(MemNode::ValueIn)); -+ if (!val->singleton()) continue; //skip (non-con store) -+ BasicType type = val->basic_type(); -+ -+ jlong con = 0; -+ switch (type) { -+ case T_INT: con = val->is_int()->get_con(); break; -+ case T_LONG: con = val->is_long()->get_con(); break; -+ case T_FLOAT: con = jint_cast(val->getf()); break; -+ case T_DOUBLE: con = jlong_cast(val->getd()); break; -+ default: continue; //skip (odd store type) -+ } -+ -+ if (type == T_LONG && Matcher::isSimpleConstant64(con) && -+ st->Opcode() == Op_StoreL) { -+ continue; // This StoreL is already optimal. -+ } -+ -+ // Store down the constant. -+ store_constant(tiles, num_tiles, st_off, st_size, con); -+ -+ intptr_t j = st_off >> LogBytesPerLong; -+ -+ if (type == T_INT && st_size == BytesPerInt -+ && (st_off & BytesPerInt) == BytesPerInt) { -+ jlong lcon = tiles[j]; -+ if (!Matcher::isSimpleConstant64(lcon) && -+ st->Opcode() == Op_StoreI) { -+ // This StoreI is already optimal by itself. -+ jint* intcon = (jint*) &tiles[j]; -+ intcon[1] = 0; // undo the store_constant() -+ -+ // If the previous store is also optimal by itself, back up and -+ // undo the action of the previous loop iteration... if we can. -+ // But if we can't, just let the previous half take care of itself. -+ st = nodes[j]; -+ st_off -= BytesPerInt; -+ con = intcon[0]; -+ if (con != 0 && st != NULL && st->Opcode() == Op_StoreI) { -+ assert(st_off >= header_size, "still ignoring header"); -+ assert(get_store_offset(st, phase) == st_off, "must be"); -+ assert(in(i-1) == zmem, "must be"); -+ DEBUG_ONLY(const Type* tcon = phase->type(st->in(MemNode::ValueIn))); -+ assert(con == tcon->is_int()->get_con(), "must be"); -+ // Undo the effects of the previous loop trip, which swallowed st: -+ intcon[0] = 0; // undo store_constant() -+ set_req(i-1, st); // undo set_req(i, zmem) -+ nodes[j] = NULL; // undo nodes[j] = st -+ --old_subword; // undo ++old_subword -+ } -+ continue; // This StoreI is already optimal. -+ } -+ } -+ -+ // This store is not needed. -+ set_req(i, zmem); -+ nodes[j] = st; // record for the moment -+ if (st_size < BytesPerLong) // something has changed -+ ++old_subword; // includes int/float, but who's counting... -+ else ++old_long; -+ } -+ -+ if ((old_subword + old_long) == 0) -+ return; // nothing more to do -+ -+ //// Pass B: Convert any non-zero tiles into optimal constant stores. -+ // Be sure to insert them before overlapping non-constant stores. -+ // (E.g., byte[] x = { 1,2,y,4 } => x[int 0] = 0x01020004, x[2]=y.) -+ for (int j = 0; j < num_tiles; j++) { -+ jlong con = tiles[j]; -+ jlong init = inits[j]; -+ if (con == 0) continue; -+ jint con0, con1; // split the constant, address-wise -+ jint init0, init1; // split the init map, address-wise -+ { union { jlong con; jint intcon[2]; } u; -+ u.con = con; -+ con0 = u.intcon[0]; -+ con1 = u.intcon[1]; -+ u.con = init; -+ init0 = u.intcon[0]; -+ init1 = u.intcon[1]; -+ } -+ -+ Node* old = nodes[j]; -+ assert(old != NULL, "need the prior store"); -+ intptr_t offset = (j * BytesPerLong); -+ -+ bool split = !Matcher::isSimpleConstant64(con); -+ -+ if (offset < header_size) { -+ assert(offset + BytesPerInt >= header_size, "second int counts"); -+ assert(*(jint*)&tiles[j] == 0, "junk in header"); -+ split = true; // only the second word counts -+ // Example: int a[] = { 42 ... } -+ } else if (con0 == 0 && init0 == -1) { -+ split = true; // first word is covered by full inits -+ // Example: int a[] = { ... foo(), 42 ... } -+ } else if (con1 == 0 && init1 == -1) { -+ split = true; // second word is covered by full inits -+ // Example: int a[] = { ... 42, foo() ... } -+ } -+ -+ // Here's a case where init0 is neither 0 nor -1: -+ // byte a[] = { ... 0,0,foo(),0, 0,0,0,42 ... } -+ // Assuming big-endian memory, init0, init1 are 0x0000FF00, 0x000000FF. -+ // In this case the tile is not split; it is (jlong)42. -+ // The big tile is stored down, and then the foo() value is inserted. -+ // (If there were foo(),foo() instead of foo(),0, init0 would be -1.) -+ -+ Node* ctl = old->in(MemNode::Control); -+ Node* adr = make_raw_address(offset, phase); -+ const TypePtr* atp = TypeRawPtr::BOTTOM; -+ -+ // One or two coalesced stores to plop down. -+ Node* st[2]; -+ intptr_t off[2]; -+ int nst = 0; -+ if (!split) { -+ ++new_long; -+ off[nst] = offset; -+ st[nst++] = StoreNode::make(C, ctl, zmem, adr, atp, -+ phase->longcon(con), T_LONG); -+ } else { -+ // Omit either if it is a zero. -+ if (con0 != 0) { -+ ++new_int; -+ off[nst] = offset; -+ st[nst++] = StoreNode::make(C, ctl, zmem, adr, atp, -+ phase->intcon(con0), T_INT); -+ } -+ if (con1 != 0) { -+ ++new_int; -+ offset += BytesPerInt; -+ adr = make_raw_address(offset, phase); -+ off[nst] = offset; -+ st[nst++] = StoreNode::make(C, ctl, zmem, adr, atp, -+ phase->intcon(con1), T_INT); -+ } -+ } -+ -+ // Insert second store first, then the first before the second. -+ // Insert each one just before any overlapping non-constant stores. -+ while (nst > 0) { -+ Node* st1 = st[--nst]; -+ C->copy_node_notes_to(st1, old); -+ st1 = phase->transform(st1); -+ offset = off[nst]; -+ assert(offset >= header_size, "do not smash header"); -+ int ins_idx = captured_store_insertion_point(offset, /*size:*/0, phase); -+ guarantee(ins_idx != 0, "must re-insert constant store"); -+ if (ins_idx < 0) ins_idx = -ins_idx; // never overlap -+ if (ins_idx > InitializeNode::RawStores && in(ins_idx-1) == zmem) -+ set_req(--ins_idx, st1); -+ else -+ ins_req(ins_idx, st1); -+ } -+ } -+ -+ if (PrintCompilation && WizardMode) -+ tty->print_cr("Changed %d/%d subword/long constants into %d/%d int/long", -+ old_subword, old_long, new_int, new_long); -+ if (C->log() != NULL) -+ C->log()->elem("comment that='%d/%d subword/long to %d/%d int/long'", -+ old_subword, old_long, new_int, new_long); -+ -+ // Clean up any remaining occurrences of zmem: -+ remove_extra_zeroes(); -+} -+ -+// Explore forward from in(start) to find the first fully initialized -+// word, and return its offset. Skip groups of subword stores which -+// together initialize full words. If in(start) is itself part of a -+// fully initialized word, return the offset of in(start). If there -+// are no following full-word stores, or if something is fishy, return -+// a negative value. -+intptr_t InitializeNode::find_next_fullword_store(uint start, PhaseGVN* phase) { -+ int int_map = 0; -+ intptr_t int_map_off = 0; -+ const int FULL_MAP = right_n_bits(BytesPerInt); // the int_map we hope for -+ -+ for (uint i = start, limit = req(); i < limit; i++) { -+ Node* st = in(i); -+ -+ intptr_t st_off = get_store_offset(st, phase); -+ if (st_off < 0) break; // return conservative answer -+ -+ int st_size = st->as_Store()->memory_size(); -+ if (st_size >= BytesPerInt && (st_off % BytesPerInt) == 0) { -+ return st_off; // we found a complete word init -+ } -+ -+ // update the map: -+ -+ intptr_t this_int_off = align_size_down(st_off, BytesPerInt); -+ if (this_int_off != int_map_off) { -+ // reset the map: -+ int_map = 0; -+ int_map_off = this_int_off; -+ } -+ -+ int subword_off = st_off - this_int_off; -+ int_map |= right_n_bits(st_size) << subword_off; -+ if ((int_map & FULL_MAP) == FULL_MAP) { -+ return this_int_off; // we found a complete word init -+ } -+ -+ // Did this store hit or cross the word boundary? -+ intptr_t next_int_off = align_size_down(st_off + st_size, BytesPerInt); -+ if (next_int_off == this_int_off + BytesPerInt) { -+ // We passed the current int, without fully initializing it. -+ int_map_off = next_int_off; -+ int_map >>= BytesPerInt; -+ } else if (next_int_off > this_int_off + BytesPerInt) { -+ // We passed the current and next int. -+ return this_int_off + BytesPerInt; -+ } -+ } -+ -+ return -1; -+} -+ -+ -+// Called when the associated AllocateNode is expanded into CFG. -+// At this point, we may perform additional optimizations. -+// Linearize the stores by ascending offset, to make memory -+// activity as coherent as possible. -+Node* InitializeNode::complete_stores(Node* rawctl, Node* rawmem, Node* rawptr, -+ intptr_t header_size, -+ Node* size_in_bytes, -+ PhaseGVN* phase) { -+ assert(!is_complete(), "not already complete"); -+ assert(stores_are_sane(phase), ""); -+ assert(allocation() != NULL, "must be present"); -+ -+ remove_extra_zeroes(); -+ -+ if (ReduceFieldZeroing || ReduceBulkZeroing) -+ // reduce instruction count for common initialization patterns -+ coalesce_subword_stores(header_size, size_in_bytes, phase); -+ -+ Node* zmem = zero_memory(); // initially zero memory state -+ Node* inits = zmem; // accumulating a linearized chain of inits -+ #ifdef ASSERT -+ intptr_t last_init_off = sizeof(oopDesc); // previous init offset -+ intptr_t last_init_end = sizeof(oopDesc); // previous init offset+size -+ intptr_t last_tile_end = sizeof(oopDesc); // previous tile offset+size -+ #endif -+ intptr_t zeroes_done = header_size; -+ -+ bool do_zeroing = true; // we might give up if inits are very sparse -+ int big_init_gaps = 0; // how many large gaps have we seen? -+ -+ if (ZeroTLAB) do_zeroing = false; -+ if (!ReduceFieldZeroing && !ReduceBulkZeroing) do_zeroing = false; -+ -+ for (uint i = InitializeNode::RawStores, limit = req(); i < limit; i++) { -+ Node* st = in(i); -+ intptr_t st_off = get_store_offset(st, phase); -+ if (st_off < 0) -+ break; // unknown junk in the inits -+ if (st->in(MemNode::Memory) != zmem) -+ break; // complicated store chains somehow in list -+ -+ int st_size = st->as_Store()->memory_size(); -+ intptr_t next_init_off = st_off + st_size; -+ -+ if (do_zeroing && zeroes_done < next_init_off) { -+ // See if this store needs a zero before it or under it. -+ intptr_t zeroes_needed = st_off; -+ -+ if (st_size < BytesPerInt) { -+ // Look for subword stores which only partially initialize words. -+ // If we find some, we must lay down some word-level zeroes first, -+ // underneath the subword stores. -+ // -+ // Examples: -+ // byte[] a = { p,q,r,s } => a[0]=p,a[1]=q,a[2]=r,a[3]=s -+ // byte[] a = { x,y,0,0 } => a[0..3] = 0, a[0]=x,a[1]=y -+ // byte[] a = { 0,0,z,0 } => a[0..3] = 0, a[2]=z -+ // -+ // Note: coalesce_subword_stores may have already done this, -+ // if it was prompted by constant non-zero subword initializers. -+ // But this case can still arise with non-constant stores. -+ -+ intptr_t next_full_store = find_next_fullword_store(i, phase); -+ -+ // In the examples above: -+ // in(i) p q r s x y z -+ // st_off 12 13 14 15 12 13 14 -+ // st_size 1 1 1 1 1 1 1 -+ // next_full_s. 12 16 16 16 16 16 16 -+ // z's_done 12 16 16 16 12 16 12 -+ // z's_needed 12 16 16 16 16 16 16 -+ // zsize 0 0 0 0 4 0 4 -+ if (next_full_store < 0) { -+ // Conservative tack: Zero to end of current word. -+ zeroes_needed = align_size_up(zeroes_needed, BytesPerInt); -+ } else { -+ // Zero to beginning of next fully initialized word. -+ // Or, don't zero at all, if we are already in that word. -+ assert(next_full_store >= zeroes_needed, "must go forward"); -+ assert((next_full_store & (BytesPerInt-1)) == 0, "even boundary"); -+ zeroes_needed = next_full_store; -+ } -+ } -+ -+ if (zeroes_needed > zeroes_done) { -+ intptr_t zsize = zeroes_needed - zeroes_done; -+ // Do some incremental zeroing on rawmem, in parallel with inits. -+ zeroes_done = align_size_down(zeroes_done, BytesPerInt); -+ rawmem = ClearArrayNode::clear_memory(rawctl, rawmem, rawptr, -+ zeroes_done, zeroes_needed, -+ phase); -+ zeroes_done = zeroes_needed; -+ if (zsize > Matcher::init_array_short_size && ++big_init_gaps > 2) -+ do_zeroing = false; // leave the hole, next time -+ } -+ } -+ -+ // Collect the store and move on: -+ st->set_req(MemNode::Memory, inits); -+ inits = st; // put it on the linearized chain -+ set_req(i, zmem); // unhook from previous position -+ -+ if (zeroes_done == st_off) -+ zeroes_done = next_init_off; -+ -+ assert(!do_zeroing || zeroes_done >= next_init_off, "don't miss any"); -+ -+ #ifdef ASSERT -+ // Various order invariants. Weaker than stores_are_sane because -+ // a large constant tile can be filled in by smaller non-constant stores. -+ assert(st_off >= last_init_off, "inits do not reverse"); -+ last_init_off = st_off; -+ const Type* val = NULL; -+ if (st_size >= BytesPerInt && -+ (val = phase->type(st->in(MemNode::ValueIn)))->singleton() && -+ (int)val->basic_type() < (int)T_OBJECT) { -+ assert(st_off >= last_tile_end, "tiles do not overlap"); -+ assert(st_off >= last_init_end, "tiles do not overwrite inits"); -+ last_tile_end = MAX2(last_tile_end, next_init_off); -+ } else { -+ intptr_t st_tile_end = align_size_up(next_init_off, BytesPerLong); -+ assert(st_tile_end >= last_tile_end, "inits stay with tiles"); -+ assert(st_off >= last_init_end, "inits do not overlap"); -+ last_init_end = next_init_off; // it's a non-tile -+ } -+ #endif //ASSERT -+ } -+ -+ remove_extra_zeroes(); // clear out all the zmems left over -+ add_req(inits); -+ -+ if (!ZeroTLAB) { -+ // If anything remains to be zeroed, zero it all now. -+ zeroes_done = align_size_down(zeroes_done, BytesPerInt); -+ // if it is the last unused 4 bytes of an instance, forget about it -+ intptr_t size_limit = phase->find_intptr_t_con(size_in_bytes, max_jint); -+ if (zeroes_done + BytesPerLong >= size_limit) { -+ assert(allocation() != NULL, ""); -+ Node* klass_node = allocation()->in(AllocateNode::KlassNode); -+ ciKlass* k = phase->type(klass_node)->is_klassptr()->klass(); -+ if (zeroes_done == k->layout_helper()) -+ zeroes_done = size_limit; -+ } -+ if (zeroes_done < size_limit) { -+ rawmem = ClearArrayNode::clear_memory(rawctl, rawmem, rawptr, -+ zeroes_done, size_in_bytes, phase); -+ } -+ } -+ -+ set_complete(phase); -+ return rawmem; -+} -+ -+ -+#ifdef ASSERT -+bool InitializeNode::stores_are_sane(PhaseTransform* phase) { -+ if (is_complete()) -+ return true; // stores could be anything at this point -+ intptr_t last_off = sizeof(oopDesc); -+ for (uint i = InitializeNode::RawStores; i < req(); i++) { -+ Node* st = in(i); -+ intptr_t st_off = get_store_offset(st, phase); -+ if (st_off < 0) continue; // ignore dead garbage -+ if (last_off > st_off) { -+ tty->print_cr("*** bad store offset at %d: %d > %d", i, last_off, st_off); -+ this->dump(2); -+ assert(false, "ascending store offsets"); -+ return false; -+ } -+ last_off = st_off + st->as_Store()->memory_size(); -+ } -+ return true; -+} -+#endif //ASSERT -+ -+ -+ -+ -+//============================MergeMemNode===================================== - // - // SEMANTICS OF MEMORY MERGES: A MergeMem is a memory state assembled from several - // contributing store or call operations. Each contributor provides the memory -@@ -1880,16 +3043,16 @@ - - //------------------------------dump_spec-------------------------------------- - #ifndef PRODUCT --void MergeMemNode::dump_spec() const { -- tty->print(" {"); -+void MergeMemNode::dump_spec(outputStream *st) const { -+ st->print(" {"); - Node* base_mem = base_memory(); - for( uint i = Compile::AliasIdxRaw; i < req(); i++ ) { - Node* mem = memory_at(i); -- if (mem == base_mem) { tty->print(" -"); continue; } -- tty->print( " N%d:", mem->_idx ); -- Compile::current()->get_adr_type(i)->dump(); -+ if (mem == base_mem) { st->print(" -"); continue; } -+ st->print( " N%d:", mem->_idx ); -+ Compile::current()->get_adr_type(i)->dump_on(st); - } -- tty->print(" }"); -+ st->print(" }"); - } - #endif // !PRODUCT - -diff -ruNb openjdk6/hotspot/src/share/vm/opto/memnode.hpp openjdk/hotspot/src/share/vm/opto/memnode.hpp ---- openjdk6/hotspot/src/share/vm/opto/memnode.hpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/memnode.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)memnode.hpp 1.118 07/05/05 17:06:18 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -63,9 +60,16 @@ - debug_only(_adr_type=at; adr_type();) - } - -+ // Helpers for the optimizer. Documented in memnode.cpp. -+ static bool detect_ptr_independence(Node* p1, AllocateNode* a1, -+ Node* p2, AllocateNode* a2, -+ PhaseTransform* phase); - static bool adr_phi_is_loop_invariant(Node* adr_phi, Node* cast); - - public: -+ // This one should probably be a phase-specific function: -+ static bool detect_dominating_control(Node* dom, Node* sub); -+ - // Is this Node a MemNode or some descendent? Default is YES. - virtual Node *Ideal_DU_postCCP( PhaseCCP *ccp ); - -@@ -105,8 +109,8 @@ - Node* can_see_stored_value(Node* st, PhaseTransform* phase) const; - - #ifndef PRODUCT -- static void dump_adr_type(const Node* mem, const TypePtr* adr_type); -- virtual void dump_spec() const; -+ static void dump_adr_type(const Node* mem, const TypePtr* adr_type, outputStream *st); -+ virtual void dump_spec(outputStream *st) const; - #endif - }; - -@@ -160,7 +164,7 @@ - virtual int store_Opcode() const = 0; - - #ifndef PRODUCT -- virtual void dump_spec() const; -+ virtual void dump_spec(outputStream *st) const; - #endif - protected: - const Type* load_array_final_field(const TypeKlassPtr *tkls, -@@ -241,9 +245,9 @@ - bool require_atomic_access() { return _require_atomic_access; } - static LoadLNode* make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, const Type* rt); - #ifndef PRODUCT -- virtual void dump_spec() const { -- LoadNode::dump_spec(); -- if (_require_atomic_access) tty->print(" Atomic!"); -+ virtual void dump_spec(outputStream *st) const { -+ LoadNode::dump_spec(st); -+ if (_require_atomic_access) st->print(" Atomic!"); - } - #endif - }; -@@ -436,9 +440,9 @@ - bool require_atomic_access() { return _require_atomic_access; } - static StoreLNode* make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val); - #ifndef PRODUCT -- virtual void dump_spec() const { -- StoreNode::dump_spec(); -- if (_require_atomic_access) tty->print(" Atomic!"); -+ virtual void dump_spec(outputStream *st) const { -+ StoreNode::dump_spec(st); -+ if (_require_atomic_access) st->print(" Atomic!"); - } - #endif - }; -@@ -521,7 +525,7 @@ - virtual uint ideal_reg() const { return 0;} // memory projections don't have a register - virtual const Type *Value( PhaseTransform *phase ) const; - #ifndef PRODUCT -- virtual void dump_spec() const {}; -+ virtual void dump_spec(outputStream *st) const {}; - #endif - }; - -@@ -596,11 +600,19 @@ - virtual uint match_edge(uint idx) const; - - // Clear the given area of an object or array. -- // Assume that the end_offset is aligned mod BytesPerLong. -- // The start_offset (e.g., 8 or 12) must be aligned at least mod BytesPerInt. -+ // The start offset must always be aligned mod BytesPerInt. -+ // The end offset must always be aligned mod BytesPerLong. - // Return the new memory. - static Node* clear_memory(Node* control, Node* mem, Node* dest, - intptr_t start_offset, -+ intptr_t end_offset, -+ PhaseGVN* phase); -+ static Node* clear_memory(Node* control, Node* mem, Node* dest, -+ intptr_t start_offset, -+ Node* end_offset, -+ PhaseGVN* phase); -+ static Node* clear_memory(Node* control, Node* mem, Node* dest, -+ Node* start_offset, - Node* end_offset, - PhaseGVN* phase); - }; -@@ -705,6 +717,92 @@ - virtual uint ideal_reg() const { return 0; } // not matched in the AD file - }; - -+// Isolation of object setup after an AllocateNode and before next safepoint. -+// (See comment in memnode.cpp near InitializeNode::InitializeNode for semantics.) -+class InitializeNode: public MemBarNode { -+ friend class AllocateNode; -+ -+ bool _is_complete; -+ -+public: -+ enum { -+ Control = TypeFunc::Control, -+ Memory = TypeFunc::Memory, // MergeMem for states affected by this op -+ RawAddress = TypeFunc::Parms+0, // the newly-allocated raw address -+ RawStores = TypeFunc::Parms+1 // zero or more stores (or TOP) -+ }; -+ -+ InitializeNode(Compile* C, int adr_type, Node* rawoop); -+ virtual int Opcode() const; -+ virtual uint size_of() const { return sizeof(*this); } -+ virtual uint ideal_reg() const { return 0; } // not matched in the AD file -+ virtual const RegMask &in_RegMask(uint) const; // mask for RawAddress -+ -+ // Manage incoming memory edges via a MergeMem on in(Memory): -+ Node* memory(uint alias_idx); -+ -+ // The raw memory edge coming directly from the Allocation. -+ // The contents of this memory are *always* all-zero-bits. -+ Node* zero_memory() { return memory(Compile::AliasIdxRaw); } -+ -+ // Return the corresponding allocation for this initialization (or null if none). -+ // (Note: Both InitializeNode::allocation and AllocateNode::initialization -+ // are defined in graphKit.cpp, which sets up the bidirectional relation.) -+ AllocateNode* allocation(); -+ -+ // Anything other than zeroing in this init? -+ bool is_non_zero(); -+ -+ // An InitializeNode must completed before macro expansion is done. -+ // Completion requires that the AllocateNode must be followed by -+ // initialization of the new memory to zero, then to any initializers. -+ bool is_complete() { return _is_complete; } -+ -+ // Mark complete. (Must not yet be complete.) -+ void set_complete(PhaseGVN* phase); -+ -+#ifdef ASSERT -+ // ensure all non-degenerate stores are ordered and non-overlapping -+ bool stores_are_sane(PhaseTransform* phase); -+#endif //ASSERT -+ -+ // See if this store can be captured; return offset where it initializes. -+ // Return 0 if the store cannot be moved (any sort of problem). -+ intptr_t can_capture_store(StoreNode* st, PhaseTransform* phase); -+ -+ // Capture another store; reformat it to write my internal raw memory. -+ // Return the captured copy, else NULL if there is some sort of problem. -+ Node* capture_store(StoreNode* st, intptr_t start, PhaseTransform* phase); -+ -+ // Find captured store which corresponds to the range [start..start+size). -+ // Return my own memory projection (meaning the initial zero bits) -+ // if there is no such store. Return NULL if there is a problem. -+ Node* find_captured_store(intptr_t start, int size_in_bytes, PhaseTransform* phase); -+ -+ // Called when the associated AllocateNode is expanded into CFG. -+ Node* complete_stores(Node* rawctl, Node* rawmem, Node* rawptr, -+ intptr_t header_size, Node* size_in_bytes, -+ PhaseGVN* phase); -+ -+ private: -+ void remove_extra_zeroes(); -+ -+ // Find out where a captured store should be placed (or already is placed). -+ int captured_store_insertion_point(intptr_t start, int size_in_bytes, -+ PhaseTransform* phase); -+ -+ static intptr_t get_store_offset(Node* st, PhaseTransform* phase); -+ -+ Node* make_raw_address(intptr_t offset, PhaseTransform* phase); -+ -+ bool detect_init_independence(Node* n, bool st_is_pinned, int& count); -+ -+ void coalesce_subword_stores(intptr_t header_size, Node* size_in_bytes, -+ PhaseGVN* phase); -+ -+ intptr_t find_next_fullword_store(uint i, PhaseGVN* phase); -+}; -+ - //------------------------------MergeMem--------------------------------------- - // (See comment in memnode.cpp near MergeMemNode::MergeMemNode for semantics.) - class MergeMemNode: public Node { -@@ -747,7 +845,7 @@ - void grow_to_match(const MergeMemNode* other); - bool verify_sparse() const PRODUCT_RETURN0; - #ifndef PRODUCT -- virtual void dump_spec() const; -+ virtual void dump_spec(outputStream *st) const; - #endif - }; - -@@ -962,4 +1060,3 @@ - virtual uint match_edge(uint idx) const { return idx==2; } - virtual const Type *bottom_type() const { return Type::ABIO; } - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/mulnode.cpp openjdk/hotspot/src/share/vm/opto/mulnode.cpp ---- openjdk6/hotspot/src/share/vm/opto/mulnode.cpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/mulnode.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)mulnode.cpp 1.133 07/05/05 17:06:16 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -410,6 +407,13 @@ - const TypeInt *t2 = phase->type( in(2) )->isa_int(); - if( t2 && t2->is_con() ) { - int con = t2->get_con(); -+ // Masking off high bits which are always zero is useless. -+ const TypeInt* t1 = phase->type( in(1) )->isa_int(); -+ if (t1 != NULL && t1->_lo >= 0) { -+ jint t1_support = ((jint)1 << (1 + log2_intptr(t1->_hi))) - 1; -+ if ((t1_support & con) == t1_support) -+ return load; -+ } - uint lop = load->Opcode(); - if( lop == Op_LoadC && - con == 0x0000FFFF ) // Already zero-extended -@@ -536,6 +540,13 @@ - const TypeLong *t2 = phase->type( in(2) )->isa_long(); - if( t2 && t2->is_con() ) { - jlong con = t2->get_con(); -+ // Masking off high bits which are always zero is useless. -+ const TypeLong* t1 = phase->type( in(1) )->isa_long(); -+ if (t1 != NULL && t1->_lo >= 0) { -+ jlong t1_support = ((jlong)1 << (1 + log2_long(t1->_hi))) - 1; -+ if ((t1_support & con) == t1_support) -+ return usr; -+ } - uint lop = usr->Opcode(); - // Masking off the high bits of a unsigned-shift-right is not - // needed either. -@@ -669,11 +680,27 @@ - const TypeInt *r1 = t1->is_int(); // Handy access - const TypeInt *r2 = t2->is_int(); // Handy access - -- if( !r1->is_con() || !r2->is_con() ) -+ if (!r2->is_con()) - return TypeInt::INT; - - uint shift = r2->get_con(); - shift &= BitsPerJavaInteger-1; // semantics of Java shifts -+ // Shift by a multiple of 32 does nothing: -+ if (shift == 0) return t1; -+ -+ // If the shift is a constant, shift the bounds of the type, -+ // unless this could lead to an overflow. -+ if (!r1->is_con()) { -+ jint lo = r1->_lo, hi = r1->_hi; -+ if (((lo << shift) >> shift) == lo && -+ ((hi << shift) >> shift) == hi) { -+ // No overflow. The range shifts up cleanly. -+ return TypeInt::make((jint)lo << (jint)shift, -+ (jint)hi << (jint)shift, -+ MAX2(r1->_widen,r2->_widen)); -+ } -+ return TypeInt::INT; -+ } - - return TypeInt::make( (jint)r1->get_con() << (jint)shift ); - } -@@ -762,11 +789,27 @@ - const TypeLong *r1 = t1->is_long(); // Handy access - const TypeInt *r2 = t2->is_int(); // Handy access - -- if( !r1->is_con() || !r2->is_con() ) -+ if (!r2->is_con()) - return TypeLong::LONG; - - uint shift = r2->get_con(); - shift &= (BitsPerJavaInteger*2)-1; // semantics of Java shifts -+ // Shift by a multiple of 64 does nothing: -+ if (shift == 0) return t1; -+ -+ // If the shift is a constant, shift the bounds of the type, -+ // unless this could lead to an overflow. -+ if (!r1->is_con()) { -+ jlong lo = r1->_lo, hi = r1->_hi; -+ if (((lo << shift) >> shift) == lo && -+ ((hi << shift) >> shift) == hi) { -+ // No overflow. The range shifts up cleanly. -+ return TypeLong::make((jlong)lo << (jint)shift, -+ (jlong)hi << (jint)shift, -+ MAX2(r1->_widen,r2->_widen)); -+ } -+ return TypeLong::LONG; -+ } - - return TypeLong::make( (jlong)r1->get_con() << (jint)shift ); - } -@@ -1056,9 +1099,14 @@ - if( in1_op == Op_AndI ) { - const TypeInt *t3 = phase->type( andi->in(2) )->isa_int(); - if( t3 && t3->is_con() ) { // Right input is a constant -- const jint mask2 = t3->get_con(); -+ jint mask2 = t3->get_con(); -+ mask2 >>= con; // *signed* shift downward (high-order zeroes do not help) - Node *newshr = phase->transform( new (phase->C, 3) URShiftINode(andi->in(1), in(2)) ); -- return new (phase->C, 3) AndINode(newshr, phase->intcon( (mask2 >> con) & mask )); -+ return new (phase->C, 3) AndINode(newshr, phase->intcon(mask2)); -+ // The negative values are easier to materialize than positive ones. -+ // A typical case from address arithmetic is ((x & ~15) >> 4). -+ // It's better to change that to ((x >> 4) & ~0) versus -+ // ((x >> 4) & 0x0FFFFFFF). The difference is greatest in LP64. - } - } - -@@ -1184,9 +1232,10 @@ - if( andi->Opcode() == Op_AndL ) { - const TypeLong *t3 = phase->type( andi->in(2) )->isa_long(); - if( t3 && t3->is_con() ) { // Right input is a constant -- const jlong mask2 = t3->get_con(); -+ jlong mask2 = t3->get_con(); -+ mask2 >>= con; // *signed* shift downward (high-order zeroes do not help) - Node *newshr = phase->transform( new (phase->C, 3) URShiftLNode(andi->in(1), in(2)) ); -- return new (phase->C, 3) AndLNode(newshr, phase->longcon((mask2 >> con) & mask)); -+ return new (phase->C, 3) AndLNode(newshr, phase->longcon(mask2)); - } - } - -diff -ruNb openjdk6/hotspot/src/share/vm/opto/mulnode.hpp openjdk/hotspot/src/share/vm/opto/mulnode.hpp ---- openjdk6/hotspot/src/share/vm/opto/mulnode.hpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/mulnode.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)mulnode.hpp 1.53 07/05/05 17:06:18 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -248,4 +245,3 @@ - const Type *bottom_type() const { return TypeLong::LONG; } - virtual uint ideal_reg() const { return Op_RegL; } - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/multnode.cpp openjdk/hotspot/src/share/vm/opto/multnode.cpp ---- openjdk6/hotspot/src/share/vm/opto/multnode.cpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/multnode.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)multnode.cpp 1.60 07/05/05 17:06:23 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -96,7 +93,7 @@ - - bool ProjNode::pinned() const { return in(0)->pinned(); } - #ifndef PRODUCT --void ProjNode::dump_spec() const { tty->print("#%d",_con); if(_is_io_use) tty->print(" (i_o_use)");} -+void ProjNode::dump_spec(outputStream *st) const { st->print("#%d",_con); if(_is_io_use) st->print(" (i_o_use)");} - #endif - - //----------------------------check_con---------------------------------------- -@@ -130,5 +127,3 @@ - uint ProjNode::ideal_reg() const { - return Matcher::base2reg[bottom_type()->base()]; - } -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/multnode.hpp openjdk/hotspot/src/share/vm/opto/multnode.hpp ---- openjdk6/hotspot/src/share/vm/opto/multnode.hpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/multnode.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)multnode.hpp 1.46 07/05/05 17:06:24 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -79,7 +76,6 @@ - virtual uint ideal_reg() const; - virtual const RegMask &out_RegMask() const; - #ifndef PRODUCT -- virtual void dump_spec() const; -+ virtual void dump_spec(outputStream *st) const; - #endif - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/node.cpp openjdk/hotspot/src/share/vm/opto/node.cpp ---- openjdk6/hotspot/src/share/vm/opto/node.cpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/node.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)node.cpp 1.227 07/05/21 15:45:56 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -898,7 +895,7 @@ - - //------------------------------format----------------------------------------- - // Print as assembly --void Node::format( PhaseRegAlloc * ) const {} -+void Node::format( PhaseRegAlloc *, outputStream *st ) const {} - //------------------------------emit------------------------------------------- - // Emit bytes starting at parameter 'ptr'. - void Node::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {} -@@ -1369,7 +1366,7 @@ - } - - // Dump node-specific info -- dump_spec(); -+ dump_spec(tty); - #ifdef ASSERT - // Dump the non-reset _debug_idx - if( Verbose && WizardMode ) { -@@ -1393,7 +1390,7 @@ - t->dump(); - } else if( t == Type::MEMORY ) { - tty->print(" Memory:"); -- MemNode::dump_adr_type(this, adr_type()); -+ MemNode::dump_adr_type(this, adr_type(), tty); - } else if( Verbose || WizardMode ) { - tty->print(" Type:"); - if( t ) { -@@ -1408,7 +1405,7 @@ - if (nn != NULL && !nn->is_clear()) { - if (nn->jvms() != NULL) { - tty->print(" !jvms:"); -- nn->jvms()->dump_spec(); -+ nn->jvms()->dump_spec(tty); - } - } - } -@@ -1901,10 +1898,10 @@ - //============================================================================= - uint TypeNode::size_of() const { return sizeof(*this); } - #ifndef PRODUCT --void TypeNode::dump_spec() const { -+void TypeNode::dump_spec(outputStream *st) const { - if( !Verbose && !WizardMode ) { - // standard dump does this in Verbose and WizardMode -- tty->print(" #"); _type->dump(); -+ st->print(" #"); _type->dump_on(st); - } - } - #endif -@@ -1920,5 +1917,3 @@ - uint TypeNode::ideal_reg() const { - return Matcher::base2reg[_type->base()]; - } -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/node.hpp openjdk/hotspot/src/share/vm/opto/node.hpp ---- openjdk6/hotspot/src/share/vm/opto/node.hpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/node.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)node.hpp 1.221 07/05/17 17:44:27 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -59,6 +56,7 @@ - class FastLockNode; - class FastUnlockNode; - class IfNode; -+class InitializeNode; - class JVMState; - class JumpNode; - class JumpProjNode; -@@ -538,6 +536,7 @@ - DEFINE_CLASS_ID(NeverBranch, MultiBranch, 2) - DEFINE_CLASS_ID(Start, Multi, 2) - DEFINE_CLASS_ID(MemBar, Multi, 3) -+ DEFINE_CLASS_ID(Initialize, MemBar, 0) - - DEFINE_CLASS_ID(Mach, Node, 1) - DEFINE_CLASS_ID(MachReturn, Mach, 0) -@@ -687,6 +686,7 @@ - DEFINE_CLASS_QUERY(If) - DEFINE_CLASS_QUERY(IfFalse) - DEFINE_CLASS_QUERY(IfTrue) -+ DEFINE_CLASS_QUERY(Initialize) - DEFINE_CLASS_QUERY(Jump) - DEFINE_CLASS_QUERY(JumpProj) - DEFINE_CLASS_QUERY(Load) -@@ -840,6 +840,10 @@ - // value, if it appears (by local graph inspection) to be computed by a simple conditional. - bool is_iteratively_computed(); - -+ // Determine if a node is Counted loop induction variable. -+ // The method is defined in loopnode.cpp. -+ const Node* is_loop_iv() const; -+ - // Return a node with opcode "opc" and same inputs as "this" if one can - // be found; Otherwise return NULL; - Node* find_similar(int opc); -@@ -870,7 +874,7 @@ - virtual JVMState* jvms() const; - - // Print as assembly -- virtual void format( PhaseRegAlloc * ) const; -+ virtual void format( PhaseRegAlloc *, outputStream* st = tty ) const; - // Emit bytes starting at parameter 'ptr' - // Bump 'ptr' by the number of output bytes - virtual void emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const; -@@ -945,7 +949,7 @@ - virtual void dump_req() const; // Print required-edge info - virtual void dump_prec() const; // Print precedence-edge info - virtual void dump_out() const; // Print the output edge info -- virtual void dump_spec() const {}; // Print per-node info -+ virtual void dump_spec(outputStream *st) const {}; // Print per-node info - void verify_edges(Unique_Node_List &visited); // Verify bi-directional edges - void verify() const; // Check Def-Use info for my subgraph - static void verify_recur(const Node *n, int verify_depth, VectorSet &old_space, VectorSet &new_space); -@@ -1483,7 +1487,6 @@ - virtual const Type *bottom_type() const; - virtual uint ideal_reg() const; - #ifndef PRODUCT -- virtual void dump_spec() const; -+ virtual void dump_spec(outputStream *st) const; - #endif - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/opcodes.cpp openjdk/hotspot/src/share/vm/opto/opcodes.cpp ---- openjdk6/hotspot/src/share/vm/opto/opcodes.cpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/opcodes.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)opcodes.cpp 1.15 07/05/05 17:06:24 JVM" --#endif - /* - * Copyright 1998-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -43,4 +40,3 @@ - "_last_class_name", - }; - #undef macro -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/opcodes.hpp openjdk/hotspot/src/share/vm/opto/opcodes.hpp ---- openjdk6/hotspot/src/share/vm/opto/opcodes.hpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/opcodes.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)opcodes.hpp 1.31 07/05/05 17:06:24 JVM" --#endif - /* - * Copyright 1997-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/opto/optoreg.hpp openjdk/hotspot/src/share/vm/opto/optoreg.hpp ---- openjdk6/hotspot/src/share/vm/opto/optoreg.hpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/optoreg.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)optoreg.hpp 1.6 07/05/05 17:06:18 JVM" --#endif - /* - * Copyright 2006-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/opto/output.cpp openjdk/hotspot/src/share/vm/opto/output.cpp ---- openjdk6/hotspot/src/share/vm/opto/output.cpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/output.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)output.cpp 1.289 07/05/17 15:59:26 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -216,7 +213,6 @@ - MachCallNode* call = n->as_MachCall(); - if (call->entry_point() == OptoRuntime::new_instance_Java() || - call->entry_point() == OptoRuntime::new_array_Java() || -- call->entry_point() == OptoRuntime::multianewarray1_Java() || - call->entry_point() == OptoRuntime::multianewarray2_Java() || - call->entry_point() == OptoRuntime::multianewarray3_Java() || - call->entry_point() == OptoRuntime::multianewarray4_Java() || -diff -ruNb openjdk6/hotspot/src/share/vm/opto/output.hpp openjdk/hotspot/src/share/vm/opto/output.hpp ---- openjdk6/hotspot/src/share/vm/opto/output.hpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/output.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)output.hpp 1.28 07/05/05 17:06:24 JVM" --#endif - /* - * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -216,4 +213,3 @@ - #endif - - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/parse.hpp openjdk/hotspot/src/share/vm/opto/parse.hpp ---- openjdk6/hotspot/src/share/vm/opto/parse.hpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/parse.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)parse.hpp 1.269 07/05/05 17:06:25 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -107,6 +104,7 @@ - // Debug information collected during parse - uint count_inlines() const { return _count_inlines; }; - #endif -+ GrowableArray subtrees() { return _subtrees; } - }; - - -@@ -132,6 +130,7 @@ - Block** _successors; - - // Use init_node/init_graph to initialize Blocks. -+ // Block() : _live_locals((uintptr_t*)NULL,0) { ShouldNotReachHere(); } - Block() : _live_locals(NULL,0) { ShouldNotReachHere(); } - - public: -@@ -431,7 +430,7 @@ - - // Helper function to identify inlining potential at call-site - ciMethod* optimize_inlining(ciMethod* caller, int bci, ciInstanceKlass* klass, -- ciMethod *dest_method, const TypeInstPtr* receiver_type); -+ ciMethod *dest_method, const TypeOopPtr* receiver_type); - - // Helper function to setup for type-profile based inlining - bool prepare_type_profile_inline(ciInstanceKlass* prof_klass, ciMethod* prof_method); -@@ -470,6 +469,7 @@ - void do_newarray(BasicType elemtype); - void do_anewarray(); - void do_multianewarray(); -+ Node* expand_multianewarray(ciArrayKlass* array_klass, Node* *lengths, int ndimensions); - - // implementation of jsr/ret - void do_jsr(); -@@ -505,8 +505,8 @@ - void set_md_flag_at(ciMethodData* md, ciProfileData* data, int flag_constant); - - void profile_method_entry(); -- void profile_taken_branch(int target_bci); -- void profile_not_taken_branch(); -+ void profile_taken_branch(int target_bci, bool force_update = false); -+ void profile_not_taken_branch(bool force_update = false); - void profile_call(Node* receiver); - void profile_generic_call(); - void profile_receiver_type(Node* receiver); -@@ -553,4 +553,3 @@ - void dump_bci(int bci); - #endif - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/parse1.cpp openjdk/hotspot/src/share/vm/opto/parse1.cpp ---- openjdk6/hotspot/src/share/vm/opto/parse1.cpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/parse1.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)parse1.cpp 1.493 07/05/17 15:59:31 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/opto/parse2.cpp openjdk/hotspot/src/share/vm/opto/parse2.cpp ---- openjdk6/hotspot/src/share/vm/opto/parse2.cpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/parse2.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)parse2.cpp 1.359 07/05/05 17:06:23 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -897,6 +894,11 @@ - tty->print_cr("Never-taken backedge stops compilation at bci %d",bci()); - #endif - repush_if_args(); // to gather stats on loop -+ // We need to mark this branch as taken so that if we recompile we will -+ // see that it is possible. In the tiered system the interpreter doesn't -+ // do profiling and by the time we get to the lower tier from the interpreter -+ // the path may be cold again. Make sure it doesn't look untaken -+ profile_taken_branch(target_bci, !ProfileInterpreter); - uncommon_trap(Deoptimization::Reason_unreached, - Deoptimization::Action_reinterpret, - NULL, "cold"); -@@ -970,6 +972,11 @@ - tty->print_cr("Never-taken backedge stops compilation at bci %d",bci()); - #endif - repush_if_args(); // to gather stats on loop -+ // We need to mark this branch as taken so that if we recompile we will -+ // see that it is possible. In the tiered system the interpreter doesn't -+ // do profiling and by the time we get to the lower tier from the interpreter -+ // the path may be cold again. Make sure it doesn't look untaken -+ profile_taken_branch(target_bci, !ProfileInterpreter); - uncommon_trap(Deoptimization::Reason_unreached, - Deoptimization::Action_reinterpret, - NULL, "cold"); -@@ -1067,6 +1074,15 @@ - // We do not simply inspect for a null constant, since a node may - // optimize to 'null' later on. - repush_if_args(); -+ // We need to mark this branch as taken so that if we recompile we will -+ // see that it is possible. In the tiered system the interpreter doesn't -+ // do profiling and by the time we get to the lower tier from the interpreter -+ // the path may be cold again. Make sure it doesn't look untaken -+ if (is_fallthrough) { -+ profile_not_taken_branch(!ProfileInterpreter); -+ } else { -+ profile_taken_branch(iter().get_dest(), !ProfileInterpreter); -+ } - uncommon_trap(Deoptimization::Reason_unreached, - Deoptimization::Action_reinterpret, - NULL, -@@ -1498,9 +1514,9 @@ - c = pop(); // Oop to store - b = pop(); // index (already used) - a = pop(); // the array itself -+ const Type* elemtype = _gvn.type(a)->is_aryptr()->elem(); - const TypeAryPtr* adr_type = TypeAryPtr::OOPS; -- Node* store = store_to_memory(control(), d, c, T_OBJECT, adr_type); -- store_barrier(store, T_ARRAY, a, d, c); -+ Node* store = store_oop_to_array(control(), a, d, adr_type, c, elemtype, T_OBJECT); - break; - } - case Bytecodes::_lastore: { -@@ -2140,4 +2156,16 @@ - tty->print("\nUnhandled bytecode %s\n", Bytecodes::name(bc()) ); - ShouldNotReachHere(); - } -+ -+#ifndef PRODUCT -+ IdealGraphPrinter *printer = IdealGraphPrinter::printer(); -+ if(printer) { -+ char buffer[256]; -+ sprintf(buffer, "Bytecode %d: %s", bci(), Bytecodes::name(bc())); -+ bool old = printer->traverse_outs(); -+ printer->set_traverse_outs(true); -+ printer->print_method(C, buffer, 3); -+ printer->set_traverse_outs(old); -+ } -+#endif - } -diff -ruNb openjdk6/hotspot/src/share/vm/opto/parse3.cpp openjdk/hotspot/src/share/vm/opto/parse3.cpp ---- openjdk6/hotspot/src/share/vm/opto/parse3.cpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/parse3.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)parse3.cpp 1.268 08/04/22 01:46:50 JVM" --#endif - /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -223,10 +220,18 @@ - if (bt == T_DOUBLE) val = dstore_rounding(val); - - // Store the value. -- Node* store = store_to_memory( control(), adr, val, bt, adr_type, is_vol ); -- -- // Object-writes need a store-barrier -- if (bt == T_OBJECT) store_barrier(store, T_OBJECT, obj, adr, val); -+ Node* store; -+ if (bt == T_OBJECT) { -+ const TypePtr* field_type; -+ if (!field->type()->is_loaded()) { -+ field_type = TypeInstPtr::BOTTOM; -+ } else { -+ field_type = TypeOopPtr::make_from_klass(field->type()->as_klass()); -+ } -+ store = store_oop_to_object( control(), obj, adr, adr_type, val, field_type, bt); -+ } else { -+ store = store_to_memory( control(), adr, val, bt, adr_type, is_vol ); -+ } - - // If reference is volatile, prevent following volatiles ops from - // floating up before the volatile write. -@@ -345,6 +350,28 @@ - push(obj); - } - -+// Expand simple expressions like new int[3][5] and new Object[2][nonConLen]. -+// Also handle the degenerate 1-dimensional case of anewarray. -+Node* Parse::expand_multianewarray(ciArrayKlass* array_klass, Node* *lengths, int ndimensions) { -+ Node* length = lengths[0]; -+ assert(length != NULL, ""); -+ Node* array = new_array(makecon(TypeKlassPtr::make(array_klass)), length); -+ if (ndimensions > 1) { -+ jint length_con = find_int_con(length, -1); -+ guarantee(length_con >= 0, "non-constant multianewarray"); -+ ciArrayKlass* array_klass_1 = array_klass->as_obj_array_klass()->element_klass()->as_array_klass(); -+ const TypePtr* adr_type = TypeAryPtr::OOPS; -+ const Type* elemtype = _gvn.type(array)->is_aryptr()->elem(); -+ const intptr_t header = arrayOopDesc::base_offset_in_bytes(T_OBJECT); -+ for (jint i = 0; i < length_con; i++) { -+ Node* elem = expand_multianewarray(array_klass_1, &lengths[1], ndimensions-1); -+ intptr_t offset = header + ((intptr_t)i << LogBytesPerWord); -+ Node* eaddr = basic_plus_adr(array, offset); -+ store_oop_to_array(control(), array, eaddr, adr_type, elem, elemtype, T_OBJECT); -+ } -+ } -+ return array; -+} - - void Parse::do_multianewarray() { - int ndimensions = iter().get_dimensions(); -@@ -356,7 +383,8 @@ - - // Note: Array classes are always initialized; no is_initialized check. - -- if (ndimensions > 5) { -+ enum { MAX_DIMENSION = 5 }; -+ if (ndimensions > MAX_DIMENSION || ndimensions <= 0) { - uncommon_trap(Deoptimization::Reason_unhandled, - Deoptimization::Action_none); - return; -@@ -364,75 +392,41 @@ - - kill_dead_locals(); - -- // Can use _multianewarray instead of _anewarray or _newarray -- // if only one dimension -- if( ndimensions == 1 && array_klass->is_type_array_klass() ) { -- // If this is for a basic type, call code for do_newarray instead -- BasicType element_type = array_klass->as_type_array_klass()->element_type(); -- do_newarray(element_type); -- return; -- } -- -- ciObjArrayKlass* obj_array_klass = array_klass->as_obj_array_klass(); -- -- // find the element type (etype) -- ciKlass* element_klass = obj_array_klass->base_element_klass(); -- // Base_element is either an instance-klass or a type-array but NOT -- // a basic type. We really wanted the klass of a basic type; since that's -- // not available we have to test for type-array here. -- const Type* element_type = element_klass->is_type_array_klass() -- ? Type::get_const_basic_type(element_klass->as_type_array_klass()->element_type()) -- : TypeInstPtr::make(TypePtr::BotPTR, element_klass->as_instance_klass()); -- -- int mdimensions = obj_array_klass->dimension(); -- - // get the lengths from the stack (first dimension is on top) -- Node** length = NEW_RESOURCE_ARRAY(Node*, ndimensions + 1); -+ Node* length[MAX_DIMENSION+1]; - length[ndimensions] = NULL; // terminating null for make_runtime_call -- for (int j = ndimensions-1; j >= 0 ; j--) length[j] = pop(); -+ int j; -+ for (j = ndimensions-1; j >= 0 ; j--) length[j] = pop(); - -- // construct the array type -- const Type* prev_type = element_type; -- ciKlass* prev_array = element_klass->is_type_array_klass() ? element_klass : NULL; -- -- // fill the lowest dimensions with unknown sizes -- for (int index = 0; index < mdimensions - ndimensions; index++) { -- const TypeAry* arr0 = TypeAry::make(prev_type, TypeInt::POS); -- prev_type = TypeAryPtr::make(TypePtr::BotPTR, arr0, prev_array, false, 0); -- prev_array = NULL; // array klasses can be lazy, except the first -- } -- -- // Fill in the dimensions with known sizes (passed in the JVM stack) -- for (int i = 0; i < ndimensions; i++) { -- const Type* count_type = TypeInt::POS; -- TypePtr::PTR ptr = TypePtr::BotPTR; -- bool is_exact = false; -- // For the outermost dimension, try to get a better type than POS for the -- // size. We don't do this for inner dimmensions because we lack the -- // support to invalidate the refined type when the base array is modified -- // by an aastore, or when it aliased via certain uses of an aaload. -- if (i == ndimensions - 1) { -- const Type* count_range_type = length[0]->bottom_type()->join(count_type); -- // Only improve the type if the array length is non-negative. -- if (!count_range_type->empty()) { -- count_type = count_range_type; -- ptr = TypePtr::NotNull; -- } -- // Only the outermost type is exact (4957832, 6587132), -- // since rows of the array can be either nulled out or replaced -- // by subarrays of sharper types. -- is_exact = true; -- } -- assert(count_type->is_int(), "must be integer"); -- const TypeAry* arr0 = TypeAry::make(prev_type, (TypeInt*)count_type); -- prev_type = TypeAryPtr::make(ptr, arr0, prev_array, is_exact, 0); -- prev_array = NULL; // array klasses can be lazy, except the first -+ // The original expression was of this form: new T[length0][length1]... -+ // It is often the case that the lengths are small (except the last). -+ // If that happens, use the fast 1-d creator a constant number of times. -+ const jint expand_limit = MIN2((juint)MultiArrayExpandLimit, (juint)100); -+ jint expand_count = 1; // count of allocations in the expansion -+ jint expand_fanout = 1; // running total fanout -+ for (j = 0; j < ndimensions-1; j++) { -+ jint dim_con = find_int_con(length[j], -1); -+ expand_fanout *= dim_con; -+ expand_count += expand_fanout; // count the level-J sub-arrays -+ if (dim_con < 0 -+ || dim_con > expand_limit -+ || expand_count > expand_limit) { -+ expand_count = 0; -+ break; -+ } -+ } -+ -+ // Can use multianewarray instead of [a]newarray if only one dimension, -+ // or if all non-final dimensions are small constants. -+ if (expand_count == 1 || (1 <= expand_count && expand_count <= expand_limit)) { -+ Node* obj = expand_multianewarray(array_klass, &length[0], ndimensions); -+ push(obj); -+ return; - } -- const TypeAryPtr* arr = (const TypeAryPtr*)prev_type; - - address fun = NULL; - switch (ndimensions) { -- case 1: fun = OptoRuntime::multianewarray1_Java(); break; -+ //case 1: Actually, there is no case 1. It's handled by new_array. - case 2: fun = OptoRuntime::multianewarray2_Java(); break; - case 3: fun = OptoRuntime::multianewarray3_Java(); break; - case 4: fun = OptoRuntime::multianewarray4_Java(); break; -@@ -447,6 +441,23 @@ - length[0], length[1], length[2], - length[3], length[4]); - Node* res = _gvn.transform(new (C, 1) ProjNode(c, TypeFunc::Parms)); -- Node *cast = _gvn.transform( new (C, 2) CheckCastPPNode(control(), res, arr) ); -- push( cast ); -+ -+ const Type* type = TypeOopPtr::make_from_klass_raw(array_klass); -+ -+ // Improve the type: We know it's not null, exact, and of a given length. -+ type = type->is_ptr()->cast_to_ptr_type(TypePtr::NotNull); -+ type = type->is_aryptr()->cast_to_exactness(true); -+ -+ const TypeInt* ltype = _gvn.find_int_type(length[0]); -+ if (ltype != NULL) -+ type = type->is_aryptr()->cast_to_size(ltype); -+ -+ // We cannot sharpen the nested sub-arrays, since the top level is mutable. -+ -+ Node* cast = _gvn.transform( new (C, 2) CheckCastPPNode(control(), res, type) ); -+ push(cast); -+ -+ // Possible improvements: -+ // - Make a fast path for small multi-arrays. (W/ implicit init. loops.) -+ // - Issue CastII against length[*] values, to TypeInt::POS. - } -diff -ruNb openjdk6/hotspot/src/share/vm/opto/parseHelper.cpp openjdk/hotspot/src/share/vm/opto/parseHelper.cpp ---- openjdk6/hotspot/src/share/vm/opto/parseHelper.cpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/parseHelper.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)parseHelper.cpp 1.196 07/05/23 17:37:28 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -347,7 +344,7 @@ - } - - //----------------------------profile_taken_branch----------------------------- --void Parse::profile_taken_branch(int target_bci) { -+void Parse::profile_taken_branch(int target_bci, bool force_update) { - // This is a potential osr_site if we have a backedge. - int cur_bci = bci(); - bool osr_site = -@@ -359,14 +356,21 @@ - // To do: factor out the the limit calculations below. These duplicate - // the similar limit calculations in the interpreter. - -- if (method_data_update()) { -+ if (method_data_update() || force_update) { - ciMethodData* md = method()->method_data(); - assert(md != NULL, "expected valid ciMethodData"); - ciProfileData* data = md->bci_to_data(cur_bci); - assert(data->is_JumpData(), "need JumpData for taken branch"); - increment_md_counter_at(md, data, JumpData::taken_offset()); -+ } - -+ // In the new tiered system this is all we need to do. In the old -+ // (c2 based) tiered sytem we must do the code below. -+#ifndef TIERED -+ if (method_data_update()) { -+ ciMethodData* md = method()->method_data(); - if (osr_site) { -+ ciProfileData* data = md->bci_to_data(cur_bci); - int limit = (CompileThreshold - * (OnStackReplacePercentage - InterpreterProfilePercentage)) / 100; - test_for_osr_md_counter_at(md, data, JumpData::taken_offset(), limit); -@@ -379,20 +383,23 @@ - increment_and_test_invocation_counter(limit); - } - } -+#endif // TIERED - - // Restore the original bytecode. - set_bci(cur_bci); - } - - //--------------------------profile_not_taken_branch--------------------------- --void Parse::profile_not_taken_branch() { -- if (!method_data_update()) return; -+void Parse::profile_not_taken_branch(bool force_update) { - -+ if (method_data_update() || force_update) { - ciMethodData* md = method()->method_data(); - assert(md != NULL, "expected valid ciMethodData"); - ciProfileData* data = md->bci_to_data(bci()); - assert(data->is_BranchData(), "need BranchData for not taken branch"); - increment_md_counter_at(md, data, BranchData::not_taken_offset()); -+ } -+ - } - - //---------------------------------profile_call-------------------------------- -@@ -511,5 +518,3 @@ - increment_md_counter_at(md, data, MultiBranchData::default_count_offset()); - } - } -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/phase.cpp openjdk/hotspot/src/share/vm/opto/phase.cpp ---- openjdk6/hotspot/src/share/vm/opto/phase.cpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/phase.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)phase.cpp 1.59 07/05/17 16:00:26 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/opto/phase.hpp openjdk/hotspot/src/share/vm/opto/phase.hpp ---- openjdk6/hotspot/src/share/vm/opto/phase.hpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/phase.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)phase.hpp 1.53 07/05/17 16:00:29 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -114,4 +111,3 @@ - static void print_timers(); - #endif - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/phaseX.cpp openjdk/hotspot/src/share/vm/opto/phaseX.cpp ---- openjdk6/hotspot/src/share/vm/opto/phaseX.cpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/phaseX.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)phaseX.cpp 1.261 07/05/05 17:06:24 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -1335,6 +1332,18 @@ - _worklist.push(u); - } - } -+ // If changed initialization activity, check dependent Stores -+ if (use_op == Op_Allocate || use_op == Op_AllocateArray) { -+ InitializeNode* init = use->as_Allocate()->initialization(); -+ if (init != NULL) { -+ Node* imem = init->proj_out(TypeFunc::Memory); -+ if (imem != NULL) add_users_to_worklist0(imem); -+ } -+ } -+ if (use_op == Op_Initialize) { -+ Node* imem = use->as_Initialize()->proj_out(TypeFunc::Memory); -+ if (imem != NULL) add_users_to_worklist0(imem); -+ } - } - } - -diff -ruNb openjdk6/hotspot/src/share/vm/opto/phaseX.hpp openjdk/hotspot/src/share/vm/opto/phaseX.hpp ---- openjdk6/hotspot/src/share/vm/opto/phaseX.hpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/phaseX.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)phaseX.hpp 1.119 07/05/05 17:06:26 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -517,4 +514,3 @@ - static void print_statistics(); - #endif - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/postaloc.cpp openjdk/hotspot/src/share/vm/opto/postaloc.cpp ---- openjdk6/hotspot/src/share/vm/opto/postaloc.cpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/postaloc.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)postaloc.cpp 1.83 07/05/05 17:06:28 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -585,5 +582,3 @@ - - } // End for all blocks - } -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/reg_split.cpp openjdk/hotspot/src/share/vm/opto/reg_split.cpp ---- openjdk6/hotspot/src/share/vm/opto/reg_split.cpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/reg_split.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)reg_split.cpp 1.81 07/05/05 17:06:27 JVM" --#endif - /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/opto/regalloc.cpp openjdk/hotspot/src/share/vm/opto/regalloc.cpp ---- openjdk6/hotspot/src/share/vm/opto/regalloc.cpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/regalloc.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)regalloc.cpp 1.28 07/05/05 17:06:27 JVM" --#endif - /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -128,4 +125,3 @@ - } - } - #endif -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/regalloc.hpp openjdk/hotspot/src/share/vm/opto/regalloc.hpp ---- openjdk6/hotspot/src/share/vm/opto/regalloc.hpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/regalloc.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)regalloc.hpp 1.23 07/05/05 17:06:28 JVM" --#endif - /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/opto/regmask.cpp openjdk/hotspot/src/share/vm/opto/regmask.cpp ---- openjdk6/hotspot/src/share/vm/opto/regmask.cpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/regmask.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)regmask.cpp 1.62 07/05/05 17:06:25 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -289,5 +286,3 @@ - tty->print("]"); - } - #endif -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/regmask.hpp openjdk/hotspot/src/share/vm/opto/regmask.hpp ---- openjdk6/hotspot/src/share/vm/opto/regmask.hpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/regmask.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)regmask.hpp 1.65 07/05/05 17:06:26 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/opto/rootnode.cpp openjdk/hotspot/src/share/vm/opto/rootnode.cpp ---- openjdk6/hotspot/src/share/vm/opto/rootnode.cpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/rootnode.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)rootnode.cpp 1.77 07/05/05 17:06:28 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -82,5 +79,3 @@ - const RegMask &HaltNode::out_RegMask() const { - return RegMask::Empty; - } -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/rootnode.hpp openjdk/hotspot/src/share/vm/opto/rootnode.hpp ---- openjdk6/hotspot/src/share/vm/opto/rootnode.hpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/rootnode.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)rootnode.hpp 1.48 07/05/05 17:06:28 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -63,4 +60,3 @@ - virtual uint ideal_reg() const { return NotAMachineReg; } - virtual uint match_edge(uint idx) const { return 0; } - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/runtime.cpp openjdk/hotspot/src/share/vm/opto/runtime.cpp ---- openjdk6/hotspot/src/share/vm/opto/runtime.cpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/runtime.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)runtime.cpp 1.458 07/05/17 16:00:35 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -43,7 +40,6 @@ - // Compiled code entry points - address OptoRuntime::_new_instance_Java = NULL; - address OptoRuntime::_new_array_Java = NULL; --address OptoRuntime::_multianewarray1_Java = NULL; - address OptoRuntime::_multianewarray2_Java = NULL; - address OptoRuntime::_multianewarray3_Java = NULL; - address OptoRuntime::_multianewarray4_Java = NULL; -@@ -89,7 +85,6 @@ - // ------------------------------------------------------------------------------------------------------------------------------- - gen(env, _new_instance_Java , new_instance_Type , new_instance_C , 0 , true , false, false); - gen(env, _new_array_Java , new_array_Type , new_array_C , 0 , true , false, false); -- gen(env, _multianewarray1_Java , multianewarray1_Type , multianewarray1_C , 0 , true , false, false); - gen(env, _multianewarray2_Java , multianewarray2_Type , multianewarray2_C , 0 , true , false, false); - gen(env, _multianewarray3_Java , multianewarray3_Type , multianewarray3_C , 0 , true , false, false); - gen(env, _multianewarray4_Java , multianewarray4_Type , multianewarray4_C , 0 , true , false, false); -@@ -144,6 +139,21 @@ - // We failed the fast-path allocation. Now we need to do a scavenge or GC - // and try allocation again. - -+void OptoRuntime::do_eager_card_mark(JavaThread* thread) { -+ // After any safepoint, just before going back to compiled code, -+ // we perform a card mark. This lets the compiled code omit -+ // card marks for initialization of new objects. -+ // Keep this code consistent with GraphKit::store_barrier. -+ -+ oop new_obj = thread->vm_result(); -+ if (new_obj == NULL) return; -+ -+ assert(Universe::heap()->can_elide_tlab_store_barriers(), -+ "compiler must check this first"); -+ new_obj = Universe::heap()->new_store_barrier(new_obj); -+ thread->set_vm_result(new_obj); -+} -+ - // object allocation - JRT_BLOCK_ENTRY(void, OptoRuntime::new_instance_C(klassOopDesc* klass, JavaThread* thread)) - JRT_BLOCK; -@@ -182,6 +192,10 @@ - deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION); - JRT_BLOCK_END; - -+ if (GraphKit::use_ReduceInitialCardMarks()) { -+ // do them now so we don't have to do them on the fast path -+ do_eager_card_mark(thread); -+ } - JRT_END - - -@@ -217,21 +231,13 @@ - thread->set_vm_result(result); - JRT_BLOCK_END; - -+ if (GraphKit::use_ReduceInitialCardMarks()) { -+ // do them now so we don't have to do them on the fast path -+ do_eager_card_mark(thread); -+ } - JRT_END - --// multianewarray for one dimension --JRT_ENTRY(void, OptoRuntime::multianewarray1_C(klassOopDesc* elem_type, int len1, JavaThread *thread)) --#ifndef PRODUCT -- SharedRuntime::_multi1_ctr++; // multianewarray for 1 dimension --#endif -- assert(check_compiled_frame(thread), "incorrect caller"); -- assert(oop(elem_type)->is_klass(), "not a class"); -- jint dims[1]; -- dims[0] = len1; -- oop obj = arrayKlass::cast(elem_type)->multi_allocate(1, dims, THREAD); -- deoptimize_caller_frame(thread, HAS_PENDING_EXCEPTION); -- thread->set_vm_result(obj); --JRT_END -+// Note: multianewarray for one dimension is handled inline by GraphKit::new_array. - - // multianewarray for 2 dimensions - JRT_ENTRY(void, OptoRuntime::multianewarray2_C(klassOopDesc* elem_type, int len1, int len2, JavaThread *thread)) -@@ -363,10 +369,6 @@ - return TypeFunc::make(domain, range); - } - --const TypeFunc *OptoRuntime::multianewarray1_Type() { -- return multianewarray_Type(1); --} -- - const TypeFunc *OptoRuntime::multianewarray2_Type() { - return multianewarray_Type(2); - } -diff -ruNb openjdk6/hotspot/src/share/vm/opto/runtime.hpp openjdk/hotspot/src/share/vm/opto/runtime.hpp ---- openjdk6/hotspot/src/share/vm/opto/runtime.hpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/runtime.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)runtime.hpp 1.199 07/05/17 16:01:38 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -107,7 +104,6 @@ - // References to generated stubs - static address _new_instance_Java; - static address _new_array_Java; -- static address _multianewarray1_Java; - static address _multianewarray2_Java; - static address _multianewarray3_Java; - static address _multianewarray4_Java; -@@ -135,9 +131,11 @@ - // Allocate storage for a objArray or typeArray - static void new_array_C(klassOopDesc* array_klass, int len, JavaThread *thread); - -+ // Post-allocation step for implementing ReduceInitialCardMarks: -+ static void do_eager_card_mark(JavaThread* thread); -+ - // Allocate storage for a multi-dimensional arrays - // Note: needs to be fixed for arbitrary number of dimensions -- static void multianewarray1_C(klassOopDesc* klass, int len1, JavaThread *thread); - static void multianewarray2_C(klassOopDesc* klass, int len1, int len2, JavaThread *thread); - static void multianewarray3_C(klassOopDesc* klass, int len1, int len2, int len3, JavaThread *thread); - static void multianewarray4_C(klassOopDesc* klass, int len1, int len2, int len3, int len4, JavaThread *thread); -@@ -193,7 +191,6 @@ - // access to runtime stubs entry points for java code - static address new_instance_Java() { return _new_instance_Java; } - static address new_array_Java() { return _new_array_Java; } -- static address multianewarray1_Java() { return _multianewarray1_Java; } - static address multianewarray2_Java() { return _multianewarray2_Java; } - static address multianewarray3_Java() { return _multianewarray3_Java; } - static address multianewarray4_Java() { return _multianewarray4_Java; } -@@ -231,7 +228,6 @@ - static const TypeFunc* new_instance_Type(); // object allocation (slow case) - static const TypeFunc* new_array_Type (); // [a]newarray (slow case) - static const TypeFunc* multianewarray_Type(int ndim); // multianewarray -- static const TypeFunc* multianewarray1_Type(); // multianewarray - static const TypeFunc* multianewarray2_Type(); // multianewarray - static const TypeFunc* multianewarray3_Type(); // multianewarray - static const TypeFunc* multianewarray4_Type(); // multianewarray -diff -ruNb openjdk6/hotspot/src/share/vm/opto/split_if.cpp openjdk/hotspot/src/share/vm/opto/split_if.cpp ---- openjdk6/hotspot/src/share/vm/opto/split_if.cpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/split_if.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)split_if.cpp 1.68 07/05/05 17:06:29 JVM" --#endif - /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -537,4 +534,3 @@ - if( VerifyLoopOptimizations ) verify(); - #endif - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/subnode.cpp openjdk/hotspot/src/share/vm/opto/subnode.cpp ---- openjdk6/hotspot/src/share/vm/opto/subnode.cpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/subnode.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)subnode.cpp 1.159 07/05/05 17:06:27 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -78,7 +75,7 @@ - - // Not correct for SubFnode and AddFNode (must check for infinity) - // Equal? Subtract is zero -- if( phase->eqv(in1, in2) ) return add_id(); -+ if (phase->eqv_uncast(in1, in2)) return add_id(); - - // Either input is BOTTOM ==> the result is the local BOTTOM - if( t1 == Type::BOTTOM || t2 == Type::BOTTOM ) -@@ -89,6 +86,31 @@ - } - - //============================================================================= -+ -+//------------------------------Helper function-------------------------------- -+static bool ok_to_convert(Node* inc, Node* iv) { -+ // Do not collapse (x+c0)-y if "+" is a loop increment, because the -+ // "-" is loop invariant and collapsing extends the live-range of "x" -+ // to overlap with the "+", forcing another register to be used in -+ // the loop. -+ // This test will be clearer with '&&' (apply DeMorgan's rule) -+ // but I like the early cutouts that happen here. -+ const PhiNode *phi; -+ if( ( !inc->in(1)->is_Phi() || -+ !(phi=inc->in(1)->as_Phi()) || -+ phi->is_copy() || -+ !phi->region()->is_CountedLoop() || -+ inc != phi->region()->as_CountedLoop()->incr() ) -+ && -+ // Do not collapse (x+c0)-iv if "iv" is a loop induction variable, -+ // because "x" maybe invariant. -+ ( !iv->is_loop_iv() ) -+ ) { -+ return true; -+ } else { -+ return false; -+ } -+} - //------------------------------Ideal------------------------------------------ - Node *SubINode::Ideal(PhaseGVN *phase, bool can_reshape){ - Node *in1 = in(1); -@@ -115,34 +137,28 @@ - } - - // Convert "(x+c0) - y" into (x-y) + c0" -- if( op1 == Op_AddI ) { -- // Do not collapse (x+y)-y if "+" is a loop increment, because the -- // "-" is loop invariant and collapsing extends the live-range of "x" -- // to overlap with the "+", forcing another register to be used in -- // the loop. -- const PhiNode *phi; -- // This test will be clearer with '&&' (apply DeMorgan's rule) -- // but I like the early cutouts that happen here. -- if( ( !in1->in(1)->is_Phi() || -- !(phi=in1->in(1)->as_Phi()) || -- phi->is_copy() || -- !phi->region()->is_CountedLoop() || -- in1 != phi->region()->as_CountedLoop()->incr() ) -- && -- // Do not collapse (x+c0)-iv if "iv" is a loop induction variable, -- // because "x" maybe invariant. -- ( !in2->is_Phi() || -- !(phi=in2->as_Phi()) || -- phi->is_copy() || -- !phi->region()->is_CountedLoop() || -- (Node*)phi != phi->region()->as_CountedLoop()->phi() ) -- ) { -+ // Do not collapse (x+c0)-y if "+" is a loop increment or -+ // if "y" is a loop induction variable. -+ if( op1 == Op_AddI && ok_to_convert(in1, in2) ) { - const Type *tadd = phase->type( in1->in(2) ); - if( tadd->singleton() && tadd != Type::TOP ) { - Node *sub2 = phase->transform( new (phase->C, 3) SubINode( in1->in(1), in2 )); - return new (phase->C, 3) AddINode( sub2, in1->in(2) ); - } - } -+ -+ -+ // Convert "x - (y+c0)" into "(x-y) - c0" -+ // Need the same check as in above optimization but reversed. -+ if (op2 == Op_AddI && ok_to_convert(in2, in1)) { -+ Node* in21 = in2->in(1); -+ Node* in22 = in2->in(2); -+ const TypeInt* tcon = phase->type(in22)->isa_int(); -+ if (tcon != NULL && tcon->is_con()) { -+ Node* sub2 = phase->transform( new (phase->C, 3) SubINode(in1, in21) ); -+ Node* neg_c0 = phase->intcon(- tcon->get_con()); -+ return new (phase->C, 3) AddINode(sub2, neg_c0); -+ } - } - - const Type *t1 = phase->type( in1 ); -@@ -241,23 +257,28 @@ - return new (phase->C, 3) AddLNode(in1, phase->longcon(-i->get_con())); - - // Convert "(x+c0) - y" into (x-y) + c0" -- if( op1 == Op_AddL ) { -- // Do not collapse (x+y)-y if "+" is a loop increment, because the -- // "-" is loop invariant and collapsing extends the live-range of "x" -- // to overlap with the "+", forcing another register to be used in -- // the loop. -+ // Do not collapse (x+c0)-y if "+" is a loop increment or -+ // if "y" is a loop induction variable. -+ if( op1 == Op_AddL && ok_to_convert(in1, in2) ) { - Node *in11 = in1->in(1); -- const PhiNode *phi = in11->is_Phi() ? in11->as_Phi() : NULL; -- if( phi == NULL || -- phi->is_copy() || -- !phi->region()->is_CountedLoop() || -- in1 != phi->region()->as_CountedLoop()->incr() ) { - const Type *tadd = phase->type( in1->in(2) ); - if( tadd->singleton() && tadd != Type::TOP ) { - Node *sub2 = phase->transform( new (phase->C, 3) SubLNode( in11, in2 )); - return new (phase->C, 3) AddLNode( sub2, in1->in(2) ); - } - } -+ -+ // Convert "x - (y+c0)" into "(x-y) - c0" -+ // Need the same check as in above optimization but reversed. -+ if (op2 == Op_AddL && ok_to_convert(in2, in1)) { -+ Node* in21 = in2->in(1); -+ Node* in22 = in2->in(2); -+ const TypeLong* tcon = phase->type(in22)->isa_long(); -+ if (tcon != NULL && tcon->is_con()) { -+ Node* sub2 = phase->transform( new (phase->C, 3) SubLNode(in1, in21) ); -+ Node* neg_c0 = phase->longcon(- tcon->get_con()); -+ return new (phase->C, 3) AddLNode(sub2, neg_c0); -+ } - } - - const Type *t1 = phase->type( in1 ); -@@ -837,9 +858,9 @@ - //------------------------------dump_spec------------------------------------- - // Print special per-node info - #ifndef PRODUCT --void BoolTest::dump() const { -+void BoolTest::dump_on(outputStream *st) const { - const char *msg[] = {"eq","gt","??","lt","ne","le","??","ge"}; -- tty->print(msg[_test]); -+ st->print(msg[_test]); - } - #endif - -@@ -1048,10 +1069,10 @@ - //------------------------------dump_spec-------------------------------------- - // Dump special per-node info - #ifndef PRODUCT --void BoolNode::dump_spec() const { -- tty->print("["); -- _test.dump(); -- tty->print("]"); -+void BoolNode::dump_spec(outputStream *st) const { -+ st->print("["); -+ _test.dump_on(st); -+ st->print("]"); - } - #endif - -@@ -1183,4 +1204,3 @@ - if( d2 < 0.0 ) return Type::DOUBLE; - return TypeD::make( SharedRuntime::dpow( d1, d2 ) ); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/subnode.hpp openjdk/hotspot/src/share/vm/opto/subnode.hpp ---- openjdk6/hotspot/src/share/vm/opto/subnode.hpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/subnode.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)subnode.hpp 1.85 07/05/05 17:06:29 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -259,7 +256,7 @@ - mask negate( ) const { return mask(_test^4); } - bool is_canonical( ) const { return (_test == BoolTest::ne || _test == BoolTest::lt || _test == BoolTest::le); } - #ifndef PRODUCT -- void dump() const; -+ void dump_on(outputStream *st) const; - #endif - }; - -@@ -289,7 +286,7 @@ - - bool is_counted_loop_exit_test(); - #ifndef PRODUCT -- virtual void dump_spec() const; -+ virtual void dump_spec(outputStream *st) const; - #endif - }; - -diff -ruNb openjdk6/hotspot/src/share/vm/opto/superword.cpp openjdk/hotspot/src/share/vm/opto/superword.cpp ---- openjdk6/hotspot/src/share/vm/opto/superword.cpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/superword.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)superword.cpp 1.6 07/09/25 22:02:47 JVM" --#endif - /* - * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -1734,6 +1731,12 @@ - assert(valid(), "Usable"); - } - -+// Following is used to create a temporary object during -+// the pattern match of an address expression. -+SWPointer::SWPointer(SWPointer* p) : -+ _mem(p->_mem), _slp(p->_slp), _base(NULL), _adr(NULL), -+ _scale(0), _offset(0), _invar(NULL), _negate_invar(false) {} -+ - //------------------------scaled_iv_plus_offset-------------------- - // Match: k*iv + offset - // where: k is a constant that maybe zero, and -@@ -1789,6 +1792,25 @@ - _scale = 1 << n->in(2)->get_int(); - return true; - } -+ } else if (opc == Op_ConvI2L) { -+ if (scaled_iv_plus_offset(n->in(1))) { -+ return true; -+ } -+ } else if (opc == Op_LShiftL) { -+ if (!has_iv() && _invar == NULL) { -+ // Need to preserve the current _offset value, so -+ // create a temporary object for this expression subtree. -+ // Hacky, so should re-engineer the address pattern match. -+ SWPointer tmp(this); -+ if (tmp.scaled_iv_plus_offset(n->in(1))) { -+ if (tmp._invar == NULL) { -+ int mult = 1 << n->in(2)->get_int(); -+ _scale = tmp._scale * mult; -+ _offset += tmp._offset * mult; -+ return true; -+ } -+ } -+ } - } - return false; - } -@@ -1801,6 +1823,16 @@ - if (opc == Op_ConI) { - _offset += negate ? -(n->get_int()) : n->get_int(); - return true; -+ } else if (opc == Op_ConL) { -+ // Okay if value fits into an int -+ const TypeLong* t = n->find_long_type(); -+ if (t->higher_equal(TypeLong::INT)) { -+ jlong loff = n->get_long(); -+ jint off = (jint)loff; -+ _offset += negate ? -off : loff; -+ return true; -+ } -+ return false; - } - if (_invar != NULL) return false; // already have an invariant - if (opc == Op_AddI) { -diff -ruNb openjdk6/hotspot/src/share/vm/opto/superword.hpp openjdk/hotspot/src/share/vm/opto/superword.hpp ---- openjdk6/hotspot/src/share/vm/opto/superword.hpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/superword.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)superword.hpp 1.6 07/05/17 16:01:57 JVM" --#endif - /* - * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -443,6 +440,9 @@ - }; - - SWPointer(MemNode* mem, SuperWord* slp); -+ // Following is used to create a temporary object during -+ // the pattern match of an address expression. -+ SWPointer(SWPointer* p); - - bool valid() { return _adr != NULL; } - bool has_iv() { return _scale != 0; } -diff -ruNb openjdk6/hotspot/src/share/vm/opto/type.cpp openjdk/hotspot/src/share/vm/opto/type.cpp ---- openjdk6/hotspot/src/share/vm/opto/type.cpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/type.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)type.cpp 1.253 07/05/17 16:02:23 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -662,15 +659,15 @@ - - #ifndef PRODUCT - //------------------------------dump2------------------------------------------ --void Type::dump2( Dict &d, uint depth ) const { -- tty->print(msg[_base]); -+void Type::dump2( Dict &d, uint depth, outputStream *st ) const { -+ st->print(msg[_base]); - } - - //------------------------------dump------------------------------------------- --void Type::dump() const { -+void Type::dump_on(outputStream *st) const { - ResourceMark rm; - Dict d(cmpkey,hashkey); // Stop recursive type dumping -- dump2(d,1); -+ dump2(d,1, st); - } - - //------------------------------data------------------------------------------- -@@ -859,9 +856,9 @@ - //------------------------------dump2------------------------------------------ - // Dump float constant Type - #ifndef PRODUCT --void TypeF::dump2( Dict &d, uint depth ) const { -- Type::dump2(d,depth); -- tty->print("%f", _f); -+void TypeF::dump2( Dict &d, uint depth, outputStream *st ) const { -+ Type::dump2(d,depth, st); -+ st->print("%f", _f); - } - #endif - -@@ -971,9 +968,9 @@ - //------------------------------dump2------------------------------------------ - // Dump double constant Type - #ifndef PRODUCT --void TypeD::dump2( Dict &d, uint depth ) const { -- Type::dump2(d,depth); -- tty->print("%f", _d); -+void TypeD::dump2( Dict &d, uint depth, outputStream *st ) const { -+ Type::dump2(d,depth,st); -+ st->print("%f", _d); - } - #endif - -@@ -1205,29 +1202,29 @@ - return buf; - } - --void TypeInt::dump2( Dict &d, uint depth ) const { -+void TypeInt::dump2( Dict &d, uint depth, outputStream *st ) const { - char buf[40], buf2[40]; - if (_lo == min_jint && _hi == max_jint) -- tty->print("int"); -+ st->print("int"); - else if (is_con()) -- tty->print("int:%s", intname(buf, get_con())); -+ st->print("int:%s", intname(buf, get_con())); - else if (_lo == BOOL->_lo && _hi == BOOL->_hi) -- tty->print("bool"); -+ st->print("bool"); - else if (_lo == BYTE->_lo && _hi == BYTE->_hi) -- tty->print("byte"); -+ st->print("byte"); - else if (_lo == CHAR->_lo && _hi == CHAR->_hi) -- tty->print("char"); -+ st->print("char"); - else if (_lo == SHORT->_lo && _hi == SHORT->_hi) -- tty->print("short"); -+ st->print("short"); - else if (_hi == max_jint) -- tty->print("int:>=%s", intname(buf, _lo)); -+ st->print("int:>=%s", intname(buf, _lo)); - else if (_lo == min_jint) -- tty->print("int:<=%s", intname(buf, _hi)); -+ st->print("int:<=%s", intname(buf, _hi)); - else -- tty->print("int:%s..%s", intname(buf, _lo), intname(buf2, _hi)); -+ st->print("int:%s..%s", intname(buf, _lo), intname(buf2, _hi)); - - if (_widen != 0 && this != TypeInt::INT) -- tty->print(":%.*s", _widen, "wwww"); -+ st->print(":%.*s", _widen, "wwww"); - } - #endif - -@@ -1469,21 +1466,21 @@ - return buf; - } - --void TypeLong::dump2( Dict &d, uint depth ) const { -+void TypeLong::dump2( Dict &d, uint depth, outputStream *st ) const { - char buf[80], buf2[80]; - if (_lo == min_jlong && _hi == max_jlong) -- tty->print("long"); -+ st->print("long"); - else if (is_con()) -- tty->print("long:%s", longname(buf, get_con())); -+ st->print("long:%s", longname(buf, get_con())); - else if (_hi == max_jlong) -- tty->print("long:>=%s", longname(buf, _lo)); -+ st->print("long:>=%s", longname(buf, _lo)); - else if (_lo == min_jlong) -- tty->print("long:<=%s", longname(buf, _hi)); -+ st->print("long:<=%s", longname(buf, _hi)); - else -- tty->print("long:%s..%s", longname(buf, _lo), longname(buf2, _hi)); -+ st->print("long:%s..%s", longname(buf, _lo), longname(buf2, _hi)); - - if (_widen != 0 && this != TypeLong::LONG) -- tty->print(":%.*s", _widen, "wwww"); -+ st->print(":%.*s", _widen, "wwww"); - } - #endif - -@@ -1669,24 +1666,24 @@ - //------------------------------dump2------------------------------------------ - // Dump signature Type - #ifndef PRODUCT --void TypeTuple::dump2( Dict &d, uint depth ) const { -- tty->print("{"); -+void TypeTuple::dump2( Dict &d, uint depth, outputStream *st ) const { -+ st->print("{"); - if( !depth || d[this] ) { // Check for recursive print -- tty->print("...}"); -+ st->print("...}"); - return; - } - d.Insert((void*)this, (void*)this); // Stop recursion - if( _cnt ) { - uint i; - for( i=0; i<_cnt-1; i++ ) { -- tty->print("%d:", i); -- _fields[i]->dump2(d, depth-1); -- tty->print(", "); -+ st->print("%d:", i); -+ _fields[i]->dump2(d, depth-1, st); -+ st->print(", "); - } -- tty->print("%d:", i); -- _fields[i]->dump2(d, depth-1); -+ st->print("%d:", i); -+ _fields[i]->dump2(d, depth-1, st); - } -- tty->print("}"); -+ st->print("}"); - } - #endif - -@@ -1708,8 +1705,20 @@ - //============================================================================= - // Convenience common pre-built types. - -+inline const TypeInt* normalize_array_size(const TypeInt* size) { -+ // Certain normalizations keep us sane when comparing types. -+ // We do not want arrayOop variables to differ only by the wideness -+ // of their index types. Pick minimum wideness, since that is the -+ // forced wideness of small ranges anyway. -+ if (size->_widen != Type::WidenMin) -+ return TypeInt::make(size->_lo, size->_hi, Type::WidenMin); -+ else -+ return size; -+} -+ - //------------------------------make------------------------------------------- - const TypeAry *TypeAry::make( const Type *elem, const TypeInt *size) { -+ size = normalize_array_size(size); - return (TypeAry*)(new TypeAry(elem,size))->hashcons(); - } - -@@ -1742,7 +1751,9 @@ - //------------------------------xdual------------------------------------------ - // Dual: compute field-by-field dual - const Type *TypeAry::xdual() const { -- return new TypeAry( _elem->dual(), _size->dual()->is_int() ); -+ const TypeInt* size_dual = _size->dual()->is_int(); -+ size_dual = normalize_array_size(size_dual); -+ return new TypeAry( _elem->dual(), size_dual); - } - - //------------------------------eq--------------------------------------------- -@@ -1761,11 +1772,11 @@ - - //------------------------------dump2------------------------------------------ - #ifndef PRODUCT --void TypeAry::dump2( Dict &d, uint depth ) const { -- _elem->dump2(d, depth); -- tty->print("["); -- _size->dump2(d, depth); -- tty->print("]"); -+void TypeAry::dump2( Dict &d, uint depth, outputStream *st ) const { -+ _elem->dump2(d, depth, st); -+ st->print("["); -+ _size->dump2(d, depth, st); -+ st->print("]"); - } - #endif - -@@ -1930,12 +1941,12 @@ - }; - - #ifndef PRODUCT --void TypePtr::dump2( Dict &d, uint depth ) const { -- if( _ptr == Null ) tty->print("NULL"); -- else tty->print("%s *", ptr_msg[_ptr]); -- if( _offset == OffsetTop ) tty->print("+top"); -- else if( _offset == OffsetBot ) tty->print("+bot"); -- else if( _offset ) tty->print("+%d", _offset); -+void TypePtr::dump2( Dict &d, uint depth, outputStream *st ) const { -+ if( _ptr == Null ) st->print("NULL"); -+ else st->print("%s *", ptr_msg[_ptr]); -+ if( _offset == OffsetTop ) st->print("+top"); -+ else if( _offset == OffsetBot ) st->print("+bot"); -+ else if( _offset ) st->print("+%d", _offset); - } - #endif - -@@ -2073,11 +2084,11 @@ - - //------------------------------dump2------------------------------------------ - #ifndef PRODUCT --void TypeRawPtr::dump2( Dict &d, uint depth ) const { -+void TypeRawPtr::dump2( Dict &d, uint depth, outputStream *st ) const { - if( _ptr == Constant ) -- tty->print(INTPTR_FORMAT, _bits); -+ st->print(INTPTR_FORMAT, _bits); - else -- tty->print("rawptr:%s", ptr_msg[_ptr]); -+ st->print("rawptr:%s", ptr_msg[_ptr]); - } - #endif - -@@ -2402,18 +2413,18 @@ - - //------------------------------dump2------------------------------------------ - #ifndef PRODUCT --void TypeOopPtr::dump2( Dict &d, uint depth ) const { -- tty->print("oopptr:%s", ptr_msg[_ptr]); -- if( _klass_is_exact ) tty->print(":exact"); -- if( const_oop() ) tty->print(INTPTR_FORMAT, const_oop()); -+void TypeOopPtr::dump2( Dict &d, uint depth, outputStream *st ) const { -+ st->print("oopptr:%s", ptr_msg[_ptr]); -+ if( _klass_is_exact ) st->print(":exact"); -+ if( const_oop() ) st->print(INTPTR_FORMAT, const_oop()); - switch( _offset ) { -- case OffsetTop: tty->print("+top"); break; -- case OffsetBot: tty->print("+any"); break; -+ case OffsetTop: st->print("+top"); break; -+ case OffsetBot: st->print("+any"); break; - case 0: break; -- default: tty->print("+%d",_offset); break; -+ default: st->print("+%d",_offset); break; - } - if (_instance_id != UNKNOWN_INSTANCE) -- tty->print(",iid=%d",_instance_id); -+ st->print(",iid=%d",_instance_id); - } - #endif - -@@ -2904,38 +2915,38 @@ - //------------------------------dump2------------------------------------------ - // Dump oop Type - #ifndef PRODUCT --void TypeInstPtr::dump2( Dict &d, uint depth ) const { -+void TypeInstPtr::dump2( Dict &d, uint depth, outputStream *st ) const { - // Print the name of the klass. -- klass()->print_name(); -+ klass()->print_name_on(st); - - switch( _ptr ) { - case Constant: - // TO DO: Make CI print the hex address of the underlying oop. - if (WizardMode || Verbose) { -- const_oop()->print_oop(); -+ const_oop()->print_oop(st); - } - case BotPTR: - if (!WizardMode && !Verbose) { -- if( _klass_is_exact ) tty->print(":exact"); -+ if( _klass_is_exact ) st->print(":exact"); - break; - } - case TopPTR: - case AnyNull: - case NotNull: -- tty->print(":%s", ptr_msg[_ptr]); -- if( _klass_is_exact ) tty->print(":exact"); -+ st->print(":%s", ptr_msg[_ptr]); -+ if( _klass_is_exact ) st->print(":exact"); - break; - } - - if( _offset ) { // Dump offset, if any -- if( _offset == OffsetBot ) tty->print("+any"); -- else if( _offset == OffsetTop ) tty->print("+unknown"); -- else tty->print("+%d", _offset); -+ if( _offset == OffsetBot ) st->print("+any"); -+ else if( _offset == OffsetTop ) st->print("+unknown"); -+ else st->print("+%d", _offset); - } - -- tty->print(" *"); -+ st->print(" *"); - if (_instance_id != UNKNOWN_INSTANCE) -- tty->print(",iid=%d",_instance_id); -+ st->print(",iid=%d",_instance_id); - } - #endif - -@@ -3001,15 +3012,50 @@ - return make(ptr(), const_oop(), _ary, klass(), exact, _offset, instance_id); - } - -+//-----------------------------narrow_size_type------------------------------- -+// Local cache for arrayOopDesc::max_array_length(etype), -+// which is kind of slow (and cached elsewhere by other users). -+static jint max_array_length_cache[T_CONFLICT+1]; -+static jint max_array_length(BasicType etype) { -+ jint& cache = max_array_length_cache[etype]; -+ jint res = cache; -+ if (res == 0) { -+ switch (etype) { -+ case T_CONFLICT: -+ case T_ILLEGAL: -+ case T_VOID: -+ etype = T_BYTE; // will produce conservatively high value -+ } -+ cache = res = arrayOopDesc::max_array_length(etype); -+ } -+ return res; -+} -+ -+// Narrow the given size type to the index range for the given array base type. -+// Return NULL if the resulting int type becomes empty. -+const TypeInt* TypeAryPtr::narrow_size_type(const TypeInt* size, BasicType elem) { -+ jint hi = size->_hi; -+ jint lo = size->_lo; -+ jint min_lo = 0; -+ jint max_hi = max_array_length(elem); -+ //if (index_not_size) --max_hi; // type of a valid array index, FTR -+ bool chg = false; -+ if (lo < min_lo) { lo = min_lo; chg = true; } -+ if (hi > max_hi) { hi = max_hi; chg = true; } -+ if (lo > hi) -+ return NULL; -+ if (!chg) -+ return size; -+ return TypeInt::make(lo, hi, Type::WidenMin); -+} -+ - //-------------------------------cast_to_size---------------------------------- - const TypeAryPtr* TypeAryPtr::cast_to_size(const TypeInt* new_size) const { -- if (new_size == size() || new_size == NULL) return this; -- if (new_size->_lo < 0) { -- new_size = new_size->join(TypeInt::POS)->is_int(); -- if (new_size == size()) return this; -- } -- if (new_size->empty()) // Negative length arrays will produce weird -+ assert(new_size != NULL, ""); -+ new_size = narrow_size_type(new_size, elem()->basic_type()); -+ if (new_size == NULL) // Negative length arrays will produce weird - new_size = TypeInt::ZERO; // intermediate dead fast-path goo -+ if (new_size == size()) return this; - const TypeAry* new_ary = TypeAry::make(elem(), new_size); - return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset); - } -@@ -3198,33 +3244,33 @@ - - //------------------------------dump2------------------------------------------ - #ifndef PRODUCT --void TypeAryPtr::dump2( Dict &d, uint depth ) const { -- _ary->dump2(d,depth); -+void TypeAryPtr::dump2( Dict &d, uint depth, outputStream *st ) const { -+ _ary->dump2(d,depth,st); - switch( _ptr ) { - case Constant: -- const_oop()->print(); -+ const_oop()->print(st); - break; - case BotPTR: - if (!WizardMode && !Verbose) { -- if( _klass_is_exact ) tty->print(":exact"); -+ if( _klass_is_exact ) st->print(":exact"); - break; - } - case TopPTR: - case AnyNull: - case NotNull: -- tty->print(":%s", ptr_msg[_ptr]); -- if( _klass_is_exact ) tty->print(":exact"); -+ st->print(":%s", ptr_msg[_ptr]); -+ if( _klass_is_exact ) st->print(":exact"); - break; - } - -- tty->print("*"); -+ st->print("*"); - if (_instance_id != UNKNOWN_INSTANCE) -- tty->print(",iid=%d",_instance_id); -+ st->print(",iid=%d",_instance_id); - if( !_offset ) return; -- if( _offset == OffsetTop ) tty->print("+undefined"); -- else if( _offset == OffsetBot ) tty->print("+any"); -- else if( _offset < 12 ) tty->print("+%d",_offset); -- else tty->print("[%d]", (_offset-12)/4 ); -+ if( _offset == OffsetTop ) st->print("+undefined"); -+ else if( _offset == OffsetBot ) st->print("+any"); -+ else if( _offset < 12 ) st->print("+%d",_offset); -+ else st->print("[%d]", (_offset-12)/4 ); - } - #endif - -@@ -3524,15 +3570,15 @@ - //------------------------------dump2------------------------------------------ - // Dump Klass Type - #ifndef PRODUCT --void TypeKlassPtr::dump2( Dict & d, uint depth ) const { -+void TypeKlassPtr::dump2( Dict & d, uint depth, outputStream *st ) const { - switch( _ptr ) { - case Constant: -- tty->print("precise "); -+ st->print("precise "); - case NotNull: - { - const char *name = klass()->name()->as_utf8(); - if( name ) { -- tty->print("klass %s: " INTPTR_FORMAT, name, klass()); -+ st->print("klass %s: " INTPTR_FORMAT, name, klass()); - } else { - ShouldNotReachHere(); - } -@@ -3541,18 +3587,18 @@ - if( !WizardMode && !Verbose && !_klass_is_exact ) break; - case TopPTR: - case AnyNull: -- tty->print(":%s", ptr_msg[_ptr]); -- if( _klass_is_exact ) tty->print(":exact"); -+ st->print(":%s", ptr_msg[_ptr]); -+ if( _klass_is_exact ) st->print(":exact"); - break; - } - - if( _offset ) { // Dump offset, if any -- if( _offset == OffsetBot ) { tty->print("+any"); } -- else if( _offset == OffsetTop ) { tty->print("+unknown"); } -- else { tty->print("+%d", _offset); } -+ if( _offset == OffsetBot ) { st->print("+any"); } -+ else if( _offset == OffsetTop ) { st->print("+unknown"); } -+ else { st->print("+%d", _offset); } - } - -- tty->print(" *"); -+ st->print(" *"); - } - #endif - -@@ -3627,31 +3673,31 @@ - //------------------------------dump2------------------------------------------ - // Dump Function Type - #ifndef PRODUCT --void TypeFunc::dump2( Dict &d, uint depth ) const { -+void TypeFunc::dump2( Dict &d, uint depth, outputStream *st ) const { - if( _range->_cnt <= Parms ) -- tty->print("void"); -+ st->print("void"); - else { - uint i; - for (i = Parms; i < _range->_cnt-1; i++) { -- _range->field_at(i)->dump2(d,depth); -- tty->print("/"); -+ _range->field_at(i)->dump2(d,depth,st); -+ st->print("/"); - } -- _range->field_at(i)->dump2(d,depth); -+ _range->field_at(i)->dump2(d,depth,st); - } -- tty->print(" "); -- tty->print("( "); -+ st->print(" "); -+ st->print("( "); - if( !depth || d[this] ) { // Check for recursive dump -- tty->print("...)"); -+ st->print("...)"); - return; - } - d.Insert((void*)this,(void*)this); // Stop recursion - if (Parms < _domain->_cnt) -- _domain->field_at(Parms)->dump2(d,depth-1); -+ _domain->field_at(Parms)->dump2(d,depth-1,st); - for (uint i = Parms+1; i < _domain->_cnt; i++) { -- tty->print(", "); -- _domain->field_at(i)->dump2(d,depth-1); -+ st->print(", "); -+ _domain->field_at(i)->dump2(d,depth-1,st); - } -- tty->print(" )"); -+ st->print(" )"); - } - - //------------------------------print_flattened-------------------------------- -@@ -3703,4 +3749,3 @@ - } - return range()->field_at(TypeFunc::Parms)->basic_type(); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/type.hpp openjdk/hotspot/src/share/vm/opto/type.hpp ---- openjdk6/hotspot/src/share/vm/opto/type.hpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/type.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)type.hpp 1.156 07/05/17 16:02:31 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -244,8 +241,11 @@ - // Printing, statistics - static const char * const msg[lastype]; // Printable strings - #ifndef PRODUCT -- void dump() const; -- virtual void dump2( Dict &d, uint depth ) const; -+ void dump_on(outputStream *st) const; -+ void dump() const { -+ dump_on(tty); -+ } -+ virtual void dump2( Dict &d, uint depth, outputStream *st ) const; - static void dump_stats(); - static void verify_lastype(); // Check that arrays match type enum - #endif -@@ -326,7 +326,7 @@ - static const TypeF *ZERO; // positive zero only - static const TypeF *ONE; - #ifndef PRODUCT -- virtual void dump2(Dict &d, uint depth) const; -+ virtual void dump2( Dict &d, uint depth, outputStream *st ) const; - #endif - }; - -@@ -353,7 +353,7 @@ - static const TypeD *ZERO; // positive zero only - static const TypeD *ONE; - #ifndef PRODUCT -- virtual void dump2(Dict &d, uint depth) const; -+ virtual void dump2( Dict &d, uint depth, outputStream *st ) const; - #endif - }; - -@@ -407,7 +407,7 @@ - static const TypeInt *INT; - static const TypeInt *SYMINT; // symmetric range [-max_jint..max_jint] - #ifndef PRODUCT -- virtual void dump2(Dict &d, uint depth) const; -+ virtual void dump2( Dict &d, uint depth, outputStream *st ) const; - #endif - }; - -@@ -451,7 +451,7 @@ - static const TypeLong *INT; // 32-bit subrange [min_jint..max_jint] - static const TypeLong *UINT; // 32-bit unsigned [0..max_juint] - #ifndef PRODUCT -- virtual void dump2( Dict &d, uint ) const;// Specialized per-Type dumping -+ virtual void dump2( Dict &d, uint, outputStream *st ) const;// Specialized per-Type dumping - #endif - }; - -@@ -503,7 +503,7 @@ - static const TypeTuple *INT_PAIR; - static const TypeTuple *LONG_PAIR; - #ifndef PRODUCT -- virtual void dump2( Dict &d, uint ) const; // Specialized per-Type dumping -+ virtual void dump2( Dict &d, uint, outputStream *st ) const; // Specialized per-Type dumping - #endif - }; - -@@ -530,7 +530,7 @@ - virtual const Type *xdual() const; // Compute dual right now. - bool ary_must_be_exact() const; // true if arrays of such are never generic - #ifndef PRODUCT -- virtual void dump2( Dict &d, uint ) const; // Specialized per-Type dumping -+ virtual void dump2( Dict &d, uint, outputStream *st ) const; // Specialized per-Type dumping - #endif - }; - -@@ -591,7 +591,7 @@ - static const TypePtr *NOTNULL; - static const TypePtr *BOTTOM; - #ifndef PRODUCT -- virtual void dump2( Dict &d, uint depth ) const; -+ virtual void dump2( Dict &d, uint depth, outputStream *st ) const; - #endif - }; - -@@ -623,7 +623,7 @@ - static const TypeRawPtr *BOTTOM; - static const TypeRawPtr *NOTNULL; - #ifndef PRODUCT -- virtual void dump2( Dict &d, uint depth ) const; -+ virtual void dump2( Dict &d, uint depth, outputStream *st ) const; - #endif - }; - -@@ -709,7 +709,7 @@ - // Convenience common pre-built type. - static const TypeOopPtr *BOTTOM; - #ifndef PRODUCT -- virtual void dump2( Dict &d, uint depth ) const; -+ virtual void dump2( Dict &d, uint depth, outputStream *st ) const; - #endif - }; - -@@ -780,7 +780,7 @@ - static const TypeInstPtr *MARK; - static const TypeInstPtr *KLASS; - #ifndef PRODUCT -- virtual void dump2( Dict &d, uint ) const; // Specialized per-Type dumping -+ virtual void dump2( Dict &d, uint depth, outputStream *st ) const; // Specialized per-Type dumping - #endif - }; - -@@ -837,8 +837,10 @@ - return _array_body_type[elem]; - } - static const TypeAryPtr *_array_body_type[T_CONFLICT+1]; -+ // sharpen the type of an int which is used as an array size -+ static const TypeInt* narrow_size_type(const TypeInt* size, BasicType elem); - #ifndef PRODUCT -- virtual void dump2( Dict &d, uint ) const; // Specialized per-Type dumping -+ virtual void dump2( Dict &d, uint depth, outputStream *st ) const; // Specialized per-Type dumping - #endif - }; - -@@ -875,7 +877,7 @@ - static const TypeKlassPtr* OBJECT; // Not-null object klass or below - static const TypeKlassPtr* OBJECT_OR_NULL; // Maybe-null version of same - #ifndef PRODUCT -- virtual void dump2( Dict &d, uint ) const; // Specialized per-Type dumping -+ virtual void dump2( Dict &d, uint depth, outputStream *st ) const; // Specialized per-Type dumping - #endif - }; - -@@ -914,7 +916,7 @@ - BasicType return_type() const; - - #ifndef PRODUCT -- virtual void dump2( Dict &d, uint ) const; // Specialized per-Type dumping -+ virtual void dump2( Dict &d, uint depth, outputStream *st ) const; // Specialized per-Type dumping - void print_flattened() const; // Print a 'flattened' signature - #endif - // Convenience common pre-built types. -@@ -1120,4 +1122,3 @@ - #define ConvX2L(x) ConvI2L(x) - - #endif -- -diff -ruNb openjdk6/hotspot/src/share/vm/opto/vectornode.cpp openjdk/hotspot/src/share/vm/opto/vectornode.cpp ---- openjdk6/hotspot/src/share/vm/opto/vectornode.cpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/vectornode.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)vectornode.cpp 1.5 07/05/17 16:02:33 JVM" --#endif - /* - * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/opto/vectornode.hpp openjdk/hotspot/src/share/vm/opto/vectornode.hpp ---- openjdk6/hotspot/src/share/vm/opto/vectornode.hpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/opto/vectornode.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)vectornode.hpp 1.6 07/05/17 16:02:36 JVM" --#endif - /* - * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/prims/evmCompat.cpp openjdk/hotspot/src/share/vm/prims/evmCompat.cpp ---- openjdk6/hotspot/src/share/vm/prims/evmCompat.cpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/evmCompat.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)evmCompat.cpp 1.12 07/05/05 17:06:31 JVM" --#endif - /* - * Copyright 1999-2002 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/prims/forte.cpp openjdk/hotspot/src/share/vm/prims/forte.cpp ---- openjdk6/hotspot/src/share/vm/prims/forte.cpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/forte.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)forte.cpp 1.69 07/05/17 16:02:39 JVM" --#endif - /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -403,40 +400,6 @@ - } while (!fill_from_frame()); - } - -- --// is_valid_method() exists in fprofiler.cpp and now here. --// We need one central version of this routine. -- --bool forte_is_valid_method(methodOop method) { -- -- if (method == NULL || -- // The methodOop is extracted via an offset from the current -- // interpreter frame. With AsyncGetCallTrace() the interpreter -- // frame may still be under construction so we need to make -- // sure that we got an aligned oop before we try to use it. -- !Space::is_aligned(method) || -- !Universe::heap()->is_in((void*)method) || -- // See if GC became active after we entered AsyncGetCallTrace() -- // and before we try to use the methodOop. This routine is -- // used in validation of the top_frame so we don't have any -- // other data to flush if we bail due to GC here. -- // Yes, there is still a window after this check and before -- // we use methodOop below, but we can't lock out GC so that -- // has to be an acceptable risk. -- Universe::heap()->is_gc_active() || -- // -- // is_perm_and_alloced() needs to be checked before klass() because you can -- // get a method pointing into the unmapped part of the heap's -- // reserved area (e.g., a very high address just within bounds), -- // and the instruction which loads the class will SIGSEGV. -- !method->is_perm_and_alloced() || -- method->klass() != Universe::methodKlassObj()) { -- return false; // doesn't look good -- } -- return true; // hopefully this is a method indeed --} -- -- - // Determine if 'fr' is a walkable, compiled frame. - // *is_compiled_p is set to true if the frame is compiled and if it - // is, then *is_walkable_p is set to true if it is also walkable. -@@ -505,7 +468,7 @@ - // access address in order not to trigger asserts that - // are built in interpreter_frame_method function - methodOop method = *fr->interpreter_frame_method_addr(); -- if (forte_is_valid_method(method)) { -+ if (Universe::heap()->is_valid_method(method)) { - intptr_t bcx = fr->interpreter_frame_bcx(); - int bci = method->validate_bci_from_bcx(bcx); - // note: bci is set to -1 if not a valid bci -@@ -680,6 +643,8 @@ - return; - } - -+ CollectedHeap* ch = Universe::heap(); -+ - if (method != NULL) { - // The method is not stored GC safe so see if GC became active - // after we entered AsyncGetCallTrace() and before we try to -@@ -687,7 +652,7 @@ - // Yes, there is still a window after this check and before - // we use methodOop below, but we can't lock out GC so that - // has to be an acceptable risk. -- if (!forte_is_valid_method(method)) { -+ if (!ch->is_valid_method(method)) { - trace->num_frames = -2; - return; - } -@@ -725,7 +690,7 @@ - // Yes, there is still a window after this check and before - // we use methodOop below, but we can't lock out GC so that - // has to be an acceptable risk. -- if (!forte_is_valid_method(method)) { -+ if (!ch->is_valid_method(method)) { - // we throw away everything we've gathered in this sample since - // none of it is safe - trace->num_frames = -2; -diff -ruNb openjdk6/hotspot/src/share/vm/prims/forte.hpp openjdk/hotspot/src/share/vm/prims/forte.hpp ---- openjdk6/hotspot/src/share/vm/prims/forte.hpp 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/forte.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)forte.hpp 1.7 07/05/05 17:06:31 JVM" --#endif - /* - * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -29,6 +26,7 @@ - - class Forte : AllStatic { - public: -- static void register_stub(const char* name, address start, address end); -+ static void register_stub(const char* name, address start, address end) -+ KERNEL_RETURN; - // register internal VM stub - }; -diff -ruNb openjdk6/hotspot/src/share/vm/prims/hpi_imported.h openjdk/hotspot/src/share/vm/prims/hpi_imported.h ---- openjdk6/hotspot/src/share/vm/prims/hpi_imported.h 2008-07-10 22:04:34.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/hpi_imported.h 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)hpi_imported.h 1.17 07/05/05 17:06:31 JVM" --#endif - /* - * Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -318,4 +315,3 @@ - #endif - - #endif /* !_JAVASOFT_HPI_H_ */ -- -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jni.cpp openjdk/hotspot/src/share/vm/prims/jni.cpp ---- openjdk6/hotspot/src/share/vm/prims/jni.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jni.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)jni.cpp 1.435 07/06/28 16:50:01 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -1854,7 +1851,9 @@ - JNI_ENTRY(jobject, jni_GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID)) - JNIWrapper("GetStaticObjectField"); - DTRACE_PROBE3(hotspot_jni, GetStaticObjectField__entry, env, clazz, fieldID); -+#ifndef JNICHECK_KERNEL - DEBUG_ONLY(klassOop param_k = jniCheck::validate_class(thread, clazz);) -+#endif // JNICHECK_KERNEL - JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); - assert(id->is_static_field_id(), "invalid static field id"); - // Keep JVMTI addition small and only check enabled flag here. -@@ -3145,7 +3144,11 @@ - - // Returns the function structure - struct JNINativeInterface_* jni_functions() { -+#ifndef JNICHECK_KERNEL - if (CheckJNICalls) return jni_functions_check(); -+#else // JNICHECK_KERNEL -+ if (CheckJNICalls) warning("-Xcheck:jni is not supported in kernel vm."); -+#endif // JNICHECK_KERNEL - return &jni_NativeInterface; - } - -@@ -3577,4 +3580,3 @@ - jni_GetEnv, - jni_AttachCurrentThreadAsDaemon - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jni.h openjdk/hotspot/src/share/vm/prims/jni.h ---- openjdk6/hotspot/src/share/vm/prims/jni.h 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jni.h 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)jni.h 1.45 07/05/05 17:06:31 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -1960,6 +1957,3 @@ - #endif /* __cplusplus */ - - #endif /* !_JAVASOFT_JNI_H_ */ -- -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jniCheck.cpp openjdk/hotspot/src/share/vm/prims/jniCheck.cpp ---- openjdk6/hotspot/src/share/vm/prims/jniCheck.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jniCheck.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)jniCheck.cpp 1.49 07/05/05 17:06:30 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -237,6 +234,10 @@ - } - klassOop k_oop = oopObj->klass(); - -+ if (!jfieldIDWorkaround::is_valid_jfieldID(k_oop, fid)) { -+ ReportJNIFatalError(thr, fatal_wrong_field); -+ } -+ - /* make sure the field exists */ - int offset = jfieldIDWorkaround::from_instance_jfieldID(k_oop, fid); - if (!instanceKlass::cast(k_oop)->contains_field_offset(offset)) -@@ -2046,5 +2047,3 @@ - - return &checked_jni_NativeInterface; - } -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jniCheck.hpp openjdk/hotspot/src/share/vm/prims/jniCheck.hpp ---- openjdk6/hotspot/src/share/vm/prims/jniCheck.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jniCheck.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)jniCheck.hpp 1.11 07/05/05 17:06:32 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jniFastGetField.cpp openjdk/hotspot/src/share/vm/prims/jniFastGetField.cpp ---- openjdk6/hotspot/src/share/vm/prims/jniFastGetField.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jniFastGetField.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)jniFastGetField.cpp 1.8 07/05/05 17:06:32 JVM" --#endif - /* - * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -40,4 +37,3 @@ - } - return (address)-1; - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jniFastGetField.hpp openjdk/hotspot/src/share/vm/prims/jniFastGetField.hpp ---- openjdk6/hotspot/src/share/vm/prims/jniFastGetField.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jniFastGetField.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)jniFastGetField.hpp 1.8 07/05/05 17:06:32 JVM" --#endif - /* - * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jni_md.h openjdk/hotspot/src/share/vm/prims/jni_md.h ---- openjdk6/hotspot/src/share/vm/prims/jni_md.h 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jni_md.h 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)jni_md.h 1.25 07/05/05 17:06:34 JVM" --#endif - /* - * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvm.cpp openjdk/hotspot/src/share/vm/prims/jvm.cpp ---- openjdk6/hotspot/src/share/vm/prims/jvm.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvm.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)jvm.cpp 1.567 07/08/20 16:28:14 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -612,7 +609,7 @@ - oop mirror = NULL; - BasicType t = name2type(utf); - if (t != T_ILLEGAL && t != T_OBJECT && t != T_ARRAY) { -- mirror = SystemDictionary::java_mirror(t); -+ mirror = Universe::java_mirror(t); - } - if (mirror == NULL) { - THROW_MSG_0(vmSymbols::java_lang_ClassNotFoundException(), (char*) utf); -@@ -3980,14 +3977,14 @@ - // Do class based checks - if (java_lang_Class::is_primitive(mirror())) { - const char* msg = ""; -- if (mirror == SystemDictionary::bool_mirror()) msg = "java/lang/Boolean"; -- else if (mirror == SystemDictionary::char_mirror()) msg = "java/lang/Character"; -- else if (mirror == SystemDictionary::float_mirror()) msg = "java/lang/Float"; -- else if (mirror == SystemDictionary::double_mirror()) msg = "java/lang/Double"; -- else if (mirror == SystemDictionary::byte_mirror()) msg = "java/lang/Byte"; -- else if (mirror == SystemDictionary::short_mirror()) msg = "java/lang/Short"; -- else if (mirror == SystemDictionary::int_mirror()) msg = "java/lang/Integer"; -- else if (mirror == SystemDictionary::long_mirror()) msg = "java/lang/Long"; -+ if (mirror == Universe::bool_mirror()) msg = "java/lang/Boolean"; -+ else if (mirror == Universe::char_mirror()) msg = "java/lang/Character"; -+ else if (mirror == Universe::float_mirror()) msg = "java/lang/Float"; -+ else if (mirror == Universe::double_mirror()) msg = "java/lang/Double"; -+ else if (mirror == Universe::byte_mirror()) msg = "java/lang/Byte"; -+ else if (mirror == Universe::short_mirror()) msg = "java/lang/Short"; -+ else if (mirror == Universe::int_mirror()) msg = "java/lang/Integer"; -+ else if (mirror == Universe::long_mirror()) msg = "java/lang/Long"; - THROW_MSG_0(vmSymbols::java_lang_NullPointerException(), msg); - } - -@@ -4492,6 +4489,10 @@ - // consider to expose this new capability in the sun.rt.jvmCapabilities jvmstat - // counter defined in runtimeService.cpp. - info->is_attachable = AttachListener::is_attach_supported(); -+#ifdef KERNEL -+ info->is_kernel_jvm = 1; // true; -+#else // KERNEL -+ info->is_kernel_jvm = 0; // false; -+#endif // KERNEL - } - JVM_END -- -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvm.h openjdk/hotspot/src/share/vm/prims/jvm.h ---- openjdk6/hotspot/src/share/vm/prims/jvm.h 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvm.h 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)jvm.h 1.87 07/08/20 16:26:30 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -1499,7 +1496,8 @@ - * the new bit is also added in the main/baseline. - */ - unsigned int is_attachable : 1; -- unsigned int : 31; -+ unsigned int is_kernel_jvm : 1; -+ unsigned int : 30; - unsigned int : 32; - unsigned int : 32; - } jvm_version_info; -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvm_misc.hpp openjdk/hotspot/src/share/vm/prims/jvm_misc.hpp ---- openjdk6/hotspot/src/share/vm/prims/jvm_misc.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvm_misc.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)jvm_misc.hpp 1.24 07/05/05 17:06:34 JVM" --#endif - /* - * Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmti.xml openjdk/hotspot/src/share/vm/prims/jvmti.xml ---- openjdk6/hotspot/src/share/vm/prims/jvmti.xml 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmti.xml 2007-12-14 08:57:03.000000000 +0100 -@@ -56,6 +56,7 @@ - callbacksafe (safe|unsafe) #IMPLIED - impl CDATA #IMPLIED - hide CDATA #IMPLIED -+ jkernel (yes|no) #IMPLIED - since CDATA "1.0"> - - -+ microversion="109"> - - <tm>JVM</tm> Tool Interface - -@@ -969,7 +970,7 @@ - allocation libraries and mechanisms. - - -- -+ - Allocate - - Allocate an area of memory through the allocator. -@@ -1007,7 +1008,7 @@ - - - -- -+ - Deallocate - - Deallocate mem using the allocator. -@@ -2074,7 +2075,7 @@ - - - -- -+ - Set Thread Local Storage - - The VM stores a pointer value associated with each environment-thread -@@ -2114,7 +2115,7 @@ - - - -- -+ - Get Thread Local Storage - - Called by the agent to get the value of the thread-local -@@ -6360,7 +6361,7 @@ - - - -- -+ - Get Loaded Classes - - Return an array of all classes loaded in the virtual machine. -@@ -6394,7 +6395,7 @@ - - - -- -+ - Get Classloader Classes - - Returns an array of those classes for which this class loader has -@@ -6935,7 +6936,7 @@ - - - -- -+ - Is Modifiable Class - - Determines whether a class is modifiable. -@@ -7060,7 +7061,7 @@ - - - -- -+ - Retransform Classes - - This function facilitates the -@@ -7228,7 +7229,7 @@ - - - -- -+ - Redefine Classes - - -@@ -7385,7 +7386,7 @@ - - - -- -+ - Get Object Size - - For the object indicated by object, -@@ -8310,7 +8311,7 @@ - - - -- -+ - Set Native Method Prefix - - This function modifies the failure handling of -@@ -8433,7 +8434,7 @@ - - - -- -+ - Set Native Method Prefixes - - For a normal agent, -@@ -8868,7 +8869,7 @@ - - - -- -+ - Set Event Callbacks - - Set the functions to be called for each event. -@@ -8911,7 +8912,7 @@ - - - -- -+ - Set Event Notification Mode - - Control the generation of events. -@@ -9857,7 +9858,7 @@ - - - -- -+ - Get Potential Capabilities - - Returns via the -@@ -9972,7 +9973,7 @@ - - - -- -+ - Add Capabilities - - Set new capabilities by adding the capabilities -@@ -10049,7 +10050,7 @@ - - - -- -+ - Get Capabilities - - Returns via the optional -@@ -10416,7 +10417,7 @@ - This is useful for installing instrumentation under the correct class loader. - - -- -+ - Add To Bootstrap Class Loader Search - - This function can be used to cause instrumentation classes to be defined by the -@@ -10468,7 +10469,7 @@ - - - -- -+ - Add To System Class Loader Search - - This function can be used to cause instrumentation classes to be -@@ -10685,7 +10686,7 @@ - - - -- -+ - Get Phase - - Return the current phase of VM execution. -@@ -10747,7 +10748,7 @@ - - - -- -+ - Dispose Environment - - Shutdown a connection created with JNI GetEnv -@@ -10793,7 +10794,7 @@ - - - -- -+ - Set Environment Local Storage - - The VM stores a pointer value associated with each environment. -@@ -10827,7 +10828,7 @@ - - - -- -+ - Get Environment Local Storage - - Called by the agent to get the value of the environment-local -@@ -10852,7 +10853,7 @@ - - - -- -+ - Get Version Number - - Return the version via version_ptr. -@@ -13382,7 +13383,7 @@ - - - -- -+ - - The specification is an evolving document with major, minor, - and micro version numbers. -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiAgentThread.hpp openjdk/hotspot/src/share/vm/prims/jvmtiAgentThread.hpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiAgentThread.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiAgentThread.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)jvmtiAgentThread.hpp 1.13 07/05/05 17:06:36 JVM" --#endif - /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp openjdk/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)jvmtiClassFileReconstituter.cpp 1.21 07/05/05 17:06:36 JVM" --#endif - /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.hpp openjdk/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.hpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)jvmtiClassFileReconstituter.hpp 1.15 07/05/05 17:06:36 JVM" --#endif - /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiCodeBlobEvents.cpp openjdk/hotspot/src/share/vm/prims/jvmtiCodeBlobEvents.cpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiCodeBlobEvents.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiCodeBlobEvents.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)jvmtiCodeBlobEvents.cpp 1.20 07/05/05 17:06:36 JVM" --#endif - /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiCodeBlobEvents.hpp openjdk/hotspot/src/share/vm/prims/jvmtiCodeBlobEvents.hpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiCodeBlobEvents.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiCodeBlobEvents.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)jvmtiCodeBlobEvents.hpp 1.11 07/05/05 17:06:35 JVM" --#endif - /* - * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiEnter.hpp openjdk/hotspot/src/share/vm/prims/jvmtiEnter.hpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiEnter.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiEnter.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)jvmtiEnter.hpp 1.8 07/05/05 17:06:35 JVM" --#endif - /* - * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiEnter.xsl openjdk/hotspot/src/share/vm/prims/jvmtiEnter.xsl ---- openjdk6/hotspot/src/share/vm/prims/jvmtiEnter.xsl 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiEnter.xsl 2007-12-14 08:57:03.000000000 +0100 -@@ -465,6 +465,13 @@ - - ) { - -+ -+ -+ #ifdef JVMTI_KERNEL -+ return JVMTI_ERROR_NOT_AVAILABLE; -+ #else -+ -+ - - - -@@ -584,9 +591,13 @@ - - - return err; --} -- - -+ -+ -+ #endif // JVMTI_KERNEL -+ -+ -+ } - - - -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiEnv.cpp openjdk/hotspot/src/share/vm/prims/jvmtiEnv.cpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiEnv.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiEnv.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)jvmtiEnv.cpp 1.162 07/05/23 10:53:40 JVM" --#endif - /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -35,12 +32,10 @@ - // FIXLATER: hook into JvmtiTrace - #define TraceJVMTICalls false - --JvmtiEnv::JvmtiEnv() : JvmtiEnvBase() --{ -+JvmtiEnv::JvmtiEnv() : JvmtiEnvBase() { - } - --JvmtiEnv::~JvmtiEnv() --{ -+JvmtiEnv::~JvmtiEnv() { - } - - JvmtiEnv* -@@ -91,6 +86,517 @@ - return deallocate(mem); - } /* end Deallocate */ - -+// Threads_lock NOT held, java_thread not protected by lock -+// java_thread - pre-checked -+// data - NULL is a valid value, must be checked -+jvmtiError -+JvmtiEnv::SetThreadLocalStorage(JavaThread* java_thread, const void* data) { -+ JvmtiThreadState* state = java_thread->jvmti_thread_state(); -+ if (state == NULL) { -+ if (data == NULL) { -+ // leaving state unset same as data set to NULL -+ return JVMTI_ERROR_NONE; -+ } -+ // otherwise, create the state -+ state = JvmtiThreadState::state_for(java_thread); -+ } -+ state->env_thread_state(this)->set_agent_thread_local_storage_data((void*)data); -+ return JVMTI_ERROR_NONE; -+} /* end SetThreadLocalStorage */ -+ -+ -+// Threads_lock NOT held -+// thread - NOT pre-checked -+// data_ptr - pre-checked for NULL -+jvmtiError -+JvmtiEnv::GetThreadLocalStorage(jthread thread, void** data_ptr) { -+ JavaThread* current_thread = JavaThread::current(); -+ if (thread == NULL) { -+ JvmtiThreadState* state = current_thread->jvmti_thread_state(); -+ *data_ptr = (state == NULL) ? NULL : -+ state->env_thread_state(this)->get_agent_thread_local_storage_data(); -+ } else { -+ -+ // jvmti_GetThreadLocalStorage is "in native" and doesn't transition -+ // the thread to _thread_in_vm. However, when the TLS for a thread -+ // other than the current thread is required we need to transition -+ // from native so as to resolve the jthread. -+ -+ ThreadInVMfromNative __tiv(current_thread); -+ __ENTRY(jvmtiError, JvmtiEnv::GetThreadLocalStorage , current_thread) -+ debug_only(VMNativeEntryWrapper __vew;) -+ -+ oop thread_oop = JNIHandles::resolve_external_guard(thread); -+ if (thread_oop == NULL) { -+ return JVMTI_ERROR_INVALID_THREAD; -+ } -+ if (!thread_oop->is_a(SystemDictionary::thread_klass())) { -+ return JVMTI_ERROR_INVALID_THREAD; -+ } -+ JavaThread* java_thread = java_lang_Thread::thread(thread_oop); -+ if (java_thread == NULL) { -+ return JVMTI_ERROR_THREAD_NOT_ALIVE; -+ } -+ JvmtiThreadState* state = java_thread->jvmti_thread_state(); -+ *data_ptr = (state == NULL) ? NULL : -+ state->env_thread_state(this)->get_agent_thread_local_storage_data(); -+ } -+ return JVMTI_ERROR_NONE; -+} /* end GetThreadLocalStorage */ -+ -+ // -+ // Class functions -+ // -+ -+// class_count_ptr - pre-checked for NULL -+// classes_ptr - pre-checked for NULL -+jvmtiError -+JvmtiEnv::GetLoadedClasses(jint* class_count_ptr, jclass** classes_ptr) { -+ return JvmtiGetLoadedClasses::getLoadedClasses(this, class_count_ptr, classes_ptr); -+} /* end GetLoadedClasses */ -+ -+ -+// initiating_loader - NULL is a valid value, must be checked -+// class_count_ptr - pre-checked for NULL -+// classes_ptr - pre-checked for NULL -+jvmtiError -+JvmtiEnv::GetClassLoaderClasses(jobject initiating_loader, jint* class_count_ptr, jclass** classes_ptr) { -+ return JvmtiGetLoadedClasses::getClassLoaderClasses(this, initiating_loader, -+ class_count_ptr, classes_ptr); -+} /* end GetClassLoaderClasses */ -+ -+// k_mirror - may be primitive, this must be checked -+// is_modifiable_class_ptr - pre-checked for NULL -+jvmtiError -+JvmtiEnv::IsModifiableClass(oop k_mirror, jboolean* is_modifiable_class_ptr) { -+ *is_modifiable_class_ptr = VM_RedefineClasses::is_modifiable_class(k_mirror)? -+ JNI_TRUE : JNI_FALSE; -+ return JVMTI_ERROR_NONE; -+} /* end IsModifiableClass */ -+ -+// class_count - pre-checked to be greater than or equal to 0 -+// classes - pre-checked for NULL -+jvmtiError -+JvmtiEnv::RetransformClasses(jint class_count, const jclass* classes) { -+//TODO: add locking -+ -+ int index; -+ JavaThread* current_thread = JavaThread::current(); -+ ResourceMark rm(current_thread); -+ -+ jvmtiClassDefinition* class_definitions = -+ NEW_RESOURCE_ARRAY(jvmtiClassDefinition, class_count); -+ NULL_CHECK(class_definitions, JVMTI_ERROR_OUT_OF_MEMORY); -+ -+ for (index = 0; index < class_count; index++) { -+ HandleMark hm(current_thread); -+ -+ jclass jcls = classes[index]; -+ oop k_mirror = JNIHandles::resolve_external_guard(jcls); -+ if (k_mirror == NULL) { -+ return JVMTI_ERROR_INVALID_CLASS; -+ } -+ if (!k_mirror->is_a(SystemDictionary::class_klass())) { -+ return JVMTI_ERROR_INVALID_CLASS; -+ } -+ -+ if (java_lang_Class::is_primitive(k_mirror)) { -+ return JVMTI_ERROR_UNMODIFIABLE_CLASS; -+ } -+ -+ klassOop k_oop = java_lang_Class::as_klassOop(k_mirror); -+ KlassHandle klass(current_thread, k_oop); -+ -+ jint status = klass->jvmti_class_status(); -+ if (status & (JVMTI_CLASS_STATUS_ERROR)) { -+ return JVMTI_ERROR_INVALID_CLASS; -+ } -+ if (status & (JVMTI_CLASS_STATUS_ARRAY)) { -+ return JVMTI_ERROR_UNMODIFIABLE_CLASS; -+ } -+ -+ instanceKlassHandle ikh(current_thread, k_oop); -+ if (ikh->get_cached_class_file_bytes() == NULL) { -+ // not cached, we need to reconstitute the class file from VM representation -+ constantPoolHandle constants(current_thread, ikh->constants()); -+ ObjectLocker ol(constants, current_thread); // lock constant pool while we query it -+ -+ JvmtiClassFileReconstituter reconstituter(ikh); -+ if (reconstituter.get_error() != JVMTI_ERROR_NONE) { -+ return reconstituter.get_error(); -+ } -+ -+ class_definitions[index].class_byte_count = (jint)reconstituter.class_file_size(); -+ class_definitions[index].class_bytes = (unsigned char*) -+ reconstituter.class_file_bytes(); -+ } else { -+ // it is cached, get it from the cache -+ class_definitions[index].class_byte_count = ikh->get_cached_class_file_len(); -+ class_definitions[index].class_bytes = ikh->get_cached_class_file_bytes(); -+ } -+ class_definitions[index].klass = jcls; -+ } -+ VM_RedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_retransform); -+ VMThread::execute(&op); -+ return (op.check_error()); -+} /* end RetransformClasses */ -+ -+ -+// class_count - pre-checked to be greater than or equal to 0 -+// class_definitions - pre-checked for NULL -+jvmtiError -+JvmtiEnv::RedefineClasses(jint class_count, const jvmtiClassDefinition* class_definitions) { -+//TODO: add locking -+ VM_RedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_redefine); -+ VMThread::execute(&op); -+ return (op.check_error()); -+} /* end RedefineClasses */ -+ -+ -+ // -+ // Object functions -+ // -+ -+// size_ptr - pre-checked for NULL -+jvmtiError -+JvmtiEnv::GetObjectSize(jobject object, jlong* size_ptr) { -+ oop mirror = JNIHandles::resolve_external_guard(object); -+ NULL_CHECK(mirror, JVMTI_ERROR_INVALID_OBJECT); -+ -+ if (mirror->klass() == SystemDictionary::class_klass()) { -+ if (!java_lang_Class::is_primitive(mirror)) { -+ mirror = java_lang_Class::as_klassOop(mirror); -+ assert(mirror != NULL, "class for non-primitive mirror must exist"); -+ } -+ } -+ -+ *size_ptr = mirror->size() * wordSize; -+ return JVMTI_ERROR_NONE; -+} /* end GetObjectSize */ -+ -+ // -+ // Method functions -+ // -+ -+// prefix - NULL is a valid value, must be checked -+jvmtiError -+JvmtiEnv::SetNativeMethodPrefix(const char* prefix) { -+ return prefix == NULL? -+ SetNativeMethodPrefixes(0, NULL) : -+ SetNativeMethodPrefixes(1, (char**)&prefix); -+} /* end SetNativeMethodPrefix */ -+ -+ -+// prefix_count - pre-checked to be greater than or equal to 0 -+// prefixes - pre-checked for NULL -+jvmtiError -+JvmtiEnv::SetNativeMethodPrefixes(jint prefix_count, char** prefixes) { -+ // Have to grab JVMTI thread state lock to be sure that some thread -+ // isn't accessing the prefixes at the same time we are setting them. -+ // No locks during VM bring-up. -+ if (Threads::number_of_threads() == 0) { -+ return set_native_method_prefixes(prefix_count, prefixes); -+ } else { -+ MutexLocker mu(JvmtiThreadState_lock); -+ return set_native_method_prefixes(prefix_count, prefixes); -+ } -+} /* end SetNativeMethodPrefixes */ -+ -+ // -+ // Event Management functions -+ // -+ -+// callbacks - NULL is a valid value, must be checked -+// size_of_callbacks - pre-checked to be greater than or equal to 0 -+jvmtiError -+JvmtiEnv::SetEventCallbacks(const jvmtiEventCallbacks* callbacks, jint size_of_callbacks) { -+ JvmtiEventController::set_event_callbacks(this, callbacks, size_of_callbacks); -+ return JVMTI_ERROR_NONE; -+} /* end SetEventCallbacks */ -+ -+ -+// event_thread - NULL is a valid value, must be checked -+jvmtiError -+JvmtiEnv::SetEventNotificationMode(jvmtiEventMode mode, jvmtiEvent event_type, jthread event_thread, ...) { -+ JavaThread* java_thread = NULL; -+ if (event_thread != NULL) { -+ oop thread_oop = JNIHandles::resolve_external_guard(event_thread); -+ if (thread_oop == NULL) { -+ return JVMTI_ERROR_INVALID_THREAD; -+ } -+ if (!thread_oop->is_a(SystemDictionary::thread_klass())) { -+ return JVMTI_ERROR_INVALID_THREAD; -+ } -+ java_thread = java_lang_Thread::thread(thread_oop); -+ if (java_thread == NULL) { -+ return JVMTI_ERROR_THREAD_NOT_ALIVE; -+ } -+ } -+ -+ // event_type must be valid -+ if (!JvmtiEventController::is_valid_event_type(event_type)) { -+ return JVMTI_ERROR_INVALID_EVENT_TYPE; -+ } -+ -+ // global events cannot be controlled at thread level. -+ if (java_thread != NULL && JvmtiEventController::is_global_event(event_type)) { -+ return JVMTI_ERROR_ILLEGAL_ARGUMENT; -+ } -+ -+ bool enabled = (mode == JVMTI_ENABLE); -+ -+ // assure that needed capabilities are present -+ if (enabled && !JvmtiUtil::has_event_capability(event_type, get_capabilities())) { -+ return JVMTI_ERROR_MUST_POSSESS_CAPABILITY; -+ } -+ -+ if (event_type == JVMTI_EVENT_CLASS_FILE_LOAD_HOOK && enabled) { -+ record_class_file_load_hook_enabled(); -+ } -+ JvmtiEventController::set_user_enabled(this, java_thread, event_type, enabled); -+ -+ return JVMTI_ERROR_NONE; -+} /* end SetEventNotificationMode */ -+ -+ // -+ // Capability functions -+ // -+ -+// capabilities_ptr - pre-checked for NULL -+jvmtiError -+JvmtiEnv::GetPotentialCapabilities(jvmtiCapabilities* capabilities_ptr) { -+ JvmtiManageCapabilities::get_potential_capabilities(get_capabilities(), -+ get_prohibited_capabilities(), -+ capabilities_ptr); -+ return JVMTI_ERROR_NONE; -+} /* end GetPotentialCapabilities */ -+ -+ -+// capabilities_ptr - pre-checked for NULL -+jvmtiError -+JvmtiEnv::AddCapabilities(const jvmtiCapabilities* capabilities_ptr) { -+ return JvmtiManageCapabilities::add_capabilities(get_capabilities(), -+ get_prohibited_capabilities(), -+ capabilities_ptr, -+ get_capabilities()); -+} /* end AddCapabilities */ -+ -+ -+// capabilities_ptr - pre-checked for NULL -+jvmtiError -+JvmtiEnv::RelinquishCapabilities(const jvmtiCapabilities* capabilities_ptr) { -+ JvmtiManageCapabilities::relinquish_capabilities(get_capabilities(), capabilities_ptr, get_capabilities()); -+ return JVMTI_ERROR_NONE; -+} /* end RelinquishCapabilities */ -+ -+ -+// capabilities_ptr - pre-checked for NULL -+jvmtiError -+JvmtiEnv::GetCapabilities(jvmtiCapabilities* capabilities_ptr) { -+ JvmtiManageCapabilities::copy_capabilities(get_capabilities(), capabilities_ptr); -+ return JVMTI_ERROR_NONE; -+} /* end GetCapabilities */ -+ -+ // -+ // Class Loader Search functions -+ // -+ -+// segment - pre-checked for NULL -+jvmtiError -+JvmtiEnv::AddToBootstrapClassLoaderSearch(const char* segment) { -+ jvmtiPhase phase = get_phase(); -+ if (phase == JVMTI_PHASE_ONLOAD) { -+ Arguments::append_sysclasspath(segment); -+ return JVMTI_ERROR_NONE; -+ } else { -+ assert(phase == JVMTI_PHASE_LIVE, "sanity check"); -+ -+ // create the zip entry -+ ClassPathZipEntry* zip_entry = ClassLoader::create_class_path_zip_entry(segment); -+ if (zip_entry == NULL) { -+ return JVMTI_ERROR_ILLEGAL_ARGUMENT; -+ } -+ -+ // lock the loader -+ Thread* thread = Thread::current(); -+ HandleMark hm; -+ Handle loader_lock = Handle(thread, SystemDictionary::system_loader_lock()); -+ -+ ObjectLocker ol(loader_lock, thread); -+ -+ // add the jar file to the bootclasspath -+ if (TraceClassLoading) { -+ tty->print_cr("[Opened %s]", zip_entry->name()); -+ } -+ ClassLoader::add_to_list(zip_entry); -+ return JVMTI_ERROR_NONE; -+ } -+ -+} /* end AddToBootstrapClassLoaderSearch */ -+ -+ -+// segment - pre-checked for NULL -+jvmtiError -+JvmtiEnv::AddToSystemClassLoaderSearch(const char* segment) { -+ jvmtiPhase phase = get_phase(); -+ -+ if (phase == JVMTI_PHASE_ONLOAD) { -+ for (SystemProperty* p = Arguments::system_properties(); p != NULL; p = p->next()) { -+ if (strcmp("java.class.path", p->key()) == 0) { -+ p->append_value(segment); -+ break; -+ } -+ } -+ return JVMTI_ERROR_NONE; -+ } else { -+ HandleMark hm; -+ -+ assert(phase == JVMTI_PHASE_LIVE, "sanity check"); -+ -+ // create the zip entry (which will open the zip file and hence -+ // check that the segment is indeed a zip file). -+ ClassPathZipEntry* zip_entry = ClassLoader::create_class_path_zip_entry(segment); -+ if (zip_entry == NULL) { -+ return JVMTI_ERROR_ILLEGAL_ARGUMENT; -+ } -+ delete zip_entry; // no longer needed -+ -+ // lock the loader -+ Thread* THREAD = Thread::current(); -+ Handle loader = Handle(THREAD, SystemDictionary::java_system_loader()); -+ -+ ObjectLocker ol(loader, THREAD); -+ -+ // need the path as java.lang.String -+ Handle path = java_lang_String::create_from_str(segment, THREAD); -+ if (HAS_PENDING_EXCEPTION) { -+ CLEAR_PENDING_EXCEPTION; -+ return JVMTI_ERROR_INTERNAL; -+ } -+ -+ instanceKlassHandle loader_ik(THREAD, loader->klass()); -+ -+ // Invoke the appendToClassPathForInstrumentation method - if the method -+ // is not found it means the loader doesn't support adding to the class path -+ // in the live phase. -+ { -+ JavaValue res(T_VOID); -+ JavaCalls::call_special(&res, -+ loader, -+ loader_ik, -+ vmSymbolHandles::appendToClassPathForInstrumentation_name(), -+ vmSymbolHandles::appendToClassPathForInstrumentation_signature(), -+ path, -+ THREAD); -+ if (HAS_PENDING_EXCEPTION) { -+ symbolOop ex_name = PENDING_EXCEPTION->klass()->klass_part()->name(); -+ CLEAR_PENDING_EXCEPTION; -+ -+ if (ex_name == vmSymbols::java_lang_NoSuchMethodError()) { -+ return JVMTI_ERROR_CLASS_LOADER_UNSUPPORTED; -+ } else { -+ return JVMTI_ERROR_INTERNAL; -+ } -+ } -+ } -+ -+ return JVMTI_ERROR_NONE; -+ } -+} /* end AddToSystemClassLoaderSearch */ -+ -+ // -+ // General functions -+ // -+ -+// phase_ptr - pre-checked for NULL -+jvmtiError -+JvmtiEnv::GetPhase(jvmtiPhase* phase_ptr) { -+ *phase_ptr = get_phase(); -+ return JVMTI_ERROR_NONE; -+} /* end GetPhase */ -+ -+ -+jvmtiError -+JvmtiEnv::DisposeEnvironment() { -+ dispose(); -+ return JVMTI_ERROR_NONE; -+} /* end DisposeEnvironment */ -+ -+ -+// data - NULL is a valid value, must be checked -+jvmtiError -+JvmtiEnv::SetEnvironmentLocalStorage(const void* data) { -+ set_env_local_storage(data); -+ return JVMTI_ERROR_NONE; -+} /* end SetEnvironmentLocalStorage */ -+ -+ -+// data_ptr - pre-checked for NULL -+jvmtiError -+JvmtiEnv::GetEnvironmentLocalStorage(void** data_ptr) { -+ *data_ptr = (void*)get_env_local_storage(); -+ return JVMTI_ERROR_NONE; -+} /* end GetEnvironmentLocalStorage */ -+ -+// version_ptr - pre-checked for NULL -+jvmtiError -+JvmtiEnv::GetVersionNumber(jint* version_ptr) { -+ *version_ptr = JVMTI_VERSION; -+ return JVMTI_ERROR_NONE; -+} /* end GetVersionNumber */ -+ -+ -+// name_ptr - pre-checked for NULL -+jvmtiError -+JvmtiEnv::GetErrorName(jvmtiError error, char** name_ptr) { -+ if (error < JVMTI_ERROR_NONE || error > JVMTI_ERROR_MAX) { -+ return JVMTI_ERROR_ILLEGAL_ARGUMENT; -+ } -+ const char *name = JvmtiUtil::error_name(error); -+ if (name == NULL) { -+ return JVMTI_ERROR_ILLEGAL_ARGUMENT; -+ } -+ size_t len = strlen(name) + 1; -+ jvmtiError err = allocate(len, (unsigned char**)name_ptr); -+ if (err == JVMTI_ERROR_NONE) { -+ memcpy(*name_ptr, name, len); -+ } -+ return err; -+} /* end GetErrorName */ -+ -+ -+jvmtiError -+JvmtiEnv::SetVerboseFlag(jvmtiVerboseFlag flag, jboolean value) { -+ switch (flag) { -+ case JVMTI_VERBOSE_OTHER: -+ // ignore -+ break; -+ case JVMTI_VERBOSE_CLASS: -+ TraceClassLoading = value != 0; -+ TraceClassUnloading = value != 0; -+ break; -+ case JVMTI_VERBOSE_GC: -+ PrintGC = value != 0; -+ TraceClassUnloading = value != 0; -+ break; -+ case JVMTI_VERBOSE_JNI: -+ PrintJNIResolving = value != 0; -+ break; -+ default: -+ return JVMTI_ERROR_ILLEGAL_ARGUMENT; -+ }; -+ return JVMTI_ERROR_NONE; -+} /* end SetVerboseFlag */ -+ -+ -+// format_ptr - pre-checked for NULL -+jvmtiError -+JvmtiEnv::GetJLocationFormat(jvmtiJlocationFormat* format_ptr) { -+ *format_ptr = JVMTI_JLOCATION_JVMBCI; -+ return JVMTI_ERROR_NONE; -+} /* end GetJLocationFormat */ -+ -+#ifndef JVMTI_KERNEL - - // - // Thread functions -@@ -550,102 +1056,42 @@ - // proc - pre-checked for NULL - // arg - NULL is a valid value, must be checked - jvmtiError --JvmtiEnv::RunAgentThread(jthread thread, jvmtiStartFunction proc, const void* arg, jint priority) { -- oop thread_oop = JNIHandles::resolve_external_guard(thread); -- if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::thread_klass())) { -- return JVMTI_ERROR_INVALID_THREAD; -- } -- if (priority < JVMTI_THREAD_MIN_PRIORITY || priority > JVMTI_THREAD_MAX_PRIORITY) { -- return JVMTI_ERROR_INVALID_PRIORITY; -- } -- -- //Thread-self -- JavaThread* current_thread = JavaThread::current(); -- -- Handle thread_hndl(current_thread, thread_oop); -- { -- MutexLocker mu(Threads_lock); // grab Threads_lock -- -- JvmtiAgentThread *new_thread = new JvmtiAgentThread(this, proc, arg); -- -- // At this point it may be possible that no osthread was created for the -- // JavaThread due to lack of memory. -- if (new_thread == NULL || new_thread->osthread() == NULL) { -- if (new_thread) delete new_thread; -- return JVMTI_ERROR_OUT_OF_MEMORY; -- } -- -- java_lang_Thread::set_thread(thread_hndl(), new_thread); -- java_lang_Thread::set_priority(thread_hndl(), (ThreadPriority)priority); -- java_lang_Thread::set_daemon(thread_hndl()); -- -- new_thread->set_threadObj(thread_hndl()); -- Threads::add(new_thread); -- Thread::start(new_thread); -- } // unlock Threads_lock -- -- return JVMTI_ERROR_NONE; --} /* end RunAgentThread */ -- -- --// Threads_lock NOT held, java_thread not protected by lock --// java_thread - pre-checked --// data - NULL is a valid value, must be checked --jvmtiError --JvmtiEnv::SetThreadLocalStorage(JavaThread* java_thread, const void* data) { -- JvmtiThreadState* state = java_thread->jvmti_thread_state(); -- if (state == NULL) { -- if (data == NULL) { -- // leaving state unset same as data set to NULL -- return JVMTI_ERROR_NONE; -- } -- // otherwise, create the state -- state = JvmtiThreadState::state_for(java_thread); -- } -- state->env_thread_state(this)->set_agent_thread_local_storage_data((void*)data); -- return JVMTI_ERROR_NONE; --} /* end SetThreadLocalStorage */ -- -- --// Threads_lock NOT held --// thread - NOT pre-checked --// data_ptr - pre-checked for NULL --jvmtiError --JvmtiEnv::GetThreadLocalStorage(jthread thread, void** data_ptr) { -- JavaThread* current_thread = JavaThread::current(); -- if (thread == NULL) { -- JvmtiThreadState* state = current_thread->jvmti_thread_state(); -- *data_ptr = (state == NULL) ? NULL : -- state->env_thread_state(this)->get_agent_thread_local_storage_data(); -- } else { -- -- // jvmti_GetThreadLocalStorage is "in native" and doesn't transition -- // the thread to _thread_in_vm. However, when the TLS for a thread -- // other than the current thread is required we need to transition -- // from native so as to resolve the jthread. -- -- ThreadInVMfromNative __tiv(current_thread); -- __ENTRY(jvmtiError, JvmtiEnv::GetThreadLocalStorage , current_thread) -- debug_only(VMNativeEntryWrapper __vew;) -- -- oop thread_oop = JNIHandles::resolve_external_guard(thread); -- if (thread_oop == NULL) { -- return JVMTI_ERROR_INVALID_THREAD; -- } -- if (!thread_oop->is_a(SystemDictionary::thread_klass())) { -+JvmtiEnv::RunAgentThread(jthread thread, jvmtiStartFunction proc, const void* arg, jint priority) { -+ oop thread_oop = JNIHandles::resolve_external_guard(thread); -+ if (thread_oop == NULL || !thread_oop->is_a(SystemDictionary::thread_klass())) { - return JVMTI_ERROR_INVALID_THREAD; - } -- JavaThread* java_thread = java_lang_Thread::thread(thread_oop); -- if (java_thread == NULL) { -- return JVMTI_ERROR_THREAD_NOT_ALIVE; -+ if (priority < JVMTI_THREAD_MIN_PRIORITY || priority > JVMTI_THREAD_MAX_PRIORITY) { -+ return JVMTI_ERROR_INVALID_PRIORITY; - } -- JvmtiThreadState* state = java_thread->jvmti_thread_state(); -- *data_ptr = (state == NULL) ? NULL : -- state->env_thread_state(this)->get_agent_thread_local_storage_data(); -+ -+ //Thread-self -+ JavaThread* current_thread = JavaThread::current(); -+ -+ Handle thread_hndl(current_thread, thread_oop); -+ { -+ MutexLocker mu(Threads_lock); // grab Threads_lock -+ -+ JvmtiAgentThread *new_thread = new JvmtiAgentThread(this, proc, arg); -+ -+ // At this point it may be possible that no osthread was created for the -+ // JavaThread due to lack of memory. -+ if (new_thread == NULL || new_thread->osthread() == NULL) { -+ if (new_thread) delete new_thread; -+ return JVMTI_ERROR_OUT_OF_MEMORY; - } -- return JVMTI_ERROR_NONE; --} /* end GetThreadLocalStorage */ - -+ java_lang_Thread::set_thread(thread_hndl(), new_thread); -+ java_lang_Thread::set_priority(thread_hndl(), (ThreadPriority)priority); -+ java_lang_Thread::set_daemon(thread_hndl()); -+ -+ new_thread->set_threadObj(thread_hndl()); -+ Threads::add(new_thread); -+ Thread::start(new_thread); -+ } // unlock Threads_lock -+ -+ return JVMTI_ERROR_NONE; -+} /* end RunAgentThread */ - - // - // Thread Group functions -@@ -1554,28 +2000,10 @@ - return JVMTI_ERROR_NONE; - } /* end ClearFieldModificationWatch */ - -- - // - // Class functions - // - --// class_count_ptr - pre-checked for NULL --// classes_ptr - pre-checked for NULL --jvmtiError --JvmtiEnv::GetLoadedClasses(jint* class_count_ptr, jclass** classes_ptr) { -- return JvmtiGetLoadedClasses::getLoadedClasses(this, class_count_ptr, classes_ptr); --} /* end GetLoadedClasses */ -- -- --// initiating_loader - NULL is a valid value, must be checked --// class_count_ptr - pre-checked for NULL --// classes_ptr - pre-checked for NULL --jvmtiError --JvmtiEnv::GetClassLoaderClasses(jobject initiating_loader, jint* class_count_ptr, jclass** classes_ptr) { -- return JvmtiGetLoadedClasses::getClassLoaderClasses(this, initiating_loader, -- class_count_ptr, classes_ptr); --} /* end GetClassLoaderClasses */ -- - - // k_mirror - may be primitive, this must be checked - // signature_ptr - NULL is a valid value, must be checked -@@ -1982,16 +2410,6 @@ - - - // k_mirror - may be primitive, this must be checked --// is_modifiable_class_ptr - pre-checked for NULL --jvmtiError --JvmtiEnv::IsModifiableClass(oop k_mirror, jboolean* is_modifiable_class_ptr) { -- *is_modifiable_class_ptr = VM_RedefineClasses::is_modifiable_class(k_mirror)? -- JNI_TRUE : JNI_FALSE; -- return JVMTI_ERROR_NONE; --} /* end IsModifiableClass */ -- -- --// k_mirror - may be primitive, this must be checked - // classloader_ptr - pre-checked for NULL - jvmtiError - JvmtiEnv::GetClassLoader(oop k_mirror, jobject* classloader_ptr) { -@@ -2046,108 +2464,10 @@ - return JVMTI_ERROR_NONE; - } /* end GetSourceDebugExtension */ - -- --// class_count - pre-checked to be greater than or equal to 0 --// classes - pre-checked for NULL --jvmtiError --JvmtiEnv::RetransformClasses(jint class_count, const jclass* classes) { --//TODO: add locking -- -- int index; -- JavaThread* current_thread = JavaThread::current(); -- ResourceMark rm(current_thread); -- -- jvmtiClassDefinition* class_definitions = -- NEW_RESOURCE_ARRAY(jvmtiClassDefinition, class_count); -- NULL_CHECK(class_definitions, JVMTI_ERROR_OUT_OF_MEMORY); -- -- for (index = 0; index < class_count; index++) { -- HandleMark hm(current_thread); -- -- jclass jcls = classes[index]; -- oop k_mirror = JNIHandles::resolve_external_guard(jcls); -- if (k_mirror == NULL) { -- return JVMTI_ERROR_INVALID_CLASS; -- } -- if (!k_mirror->is_a(SystemDictionary::class_klass())) { -- return JVMTI_ERROR_INVALID_CLASS; -- } -- -- if (java_lang_Class::is_primitive(k_mirror)) { -- return JVMTI_ERROR_UNMODIFIABLE_CLASS; -- } -- -- klassOop k_oop = java_lang_Class::as_klassOop(k_mirror); -- KlassHandle klass(current_thread, k_oop); -- -- jint status = klass->jvmti_class_status(); -- if (status & (JVMTI_CLASS_STATUS_ERROR)) { -- return JVMTI_ERROR_INVALID_CLASS; -- } -- if (status & (JVMTI_CLASS_STATUS_ARRAY)) { -- return JVMTI_ERROR_UNMODIFIABLE_CLASS; -- } -- -- instanceKlassHandle ikh(current_thread, k_oop); -- if (ikh->get_cached_class_file_bytes() == NULL) { -- // not cached, we need to reconstitute the class file from VM representation -- constantPoolHandle constants(current_thread, ikh->constants()); -- ObjectLocker ol(constants, current_thread); // lock constant pool while we query it -- -- JvmtiClassFileReconstituter reconstituter(ikh); -- if (reconstituter.get_error() != JVMTI_ERROR_NONE) { -- return reconstituter.get_error(); -- } -- -- class_definitions[index].class_byte_count = (jint)reconstituter.class_file_size(); -- class_definitions[index].class_bytes = (unsigned char*) -- reconstituter.class_file_bytes(); -- } else { -- // it is cached, get it from the cache -- class_definitions[index].class_byte_count = ikh->get_cached_class_file_len(); -- class_definitions[index].class_bytes = ikh->get_cached_class_file_bytes(); -- } -- class_definitions[index].klass = jcls; -- } -- VM_RedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_retransform); -- VMThread::execute(&op); -- return (op.check_error()); --} /* end RetransformClasses */ -- -- --// class_count - pre-checked to be greater than or equal to 0 --// class_definitions - pre-checked for NULL --jvmtiError --JvmtiEnv::RedefineClasses(jint class_count, const jvmtiClassDefinition* class_definitions) { --//TODO: add locking -- VM_RedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_redefine); -- VMThread::execute(&op); -- return (op.check_error()); --} /* end RedefineClasses */ -- -- - // - // Object functions - // - --// size_ptr - pre-checked for NULL --jvmtiError --JvmtiEnv::GetObjectSize(jobject object, jlong* size_ptr) { -- oop mirror = JNIHandles::resolve_external_guard(object); -- NULL_CHECK(mirror, JVMTI_ERROR_INVALID_OBJECT); -- -- if (mirror->klass() == SystemDictionary::class_klass()) { -- if (!java_lang_Class::is_primitive(mirror)) { -- mirror = java_lang_Class::as_klassOop(mirror); -- assert(mirror != NULL, "class for non-primitive mirror must exist"); -- } -- } -- -- *size_ptr = mirror->size() * wordSize; -- return JVMTI_ERROR_NONE; --} /* end GetObjectSize */ -- -- - // hash_code_ptr - pre-checked for NULL - jvmtiError - JvmtiEnv::GetObjectHashCode(jobject object, jint* hash_code_ptr) { -@@ -2538,32 +2858,6 @@ - return JVMTI_ERROR_NONE; - } /* end IsMethodObsolete */ - -- --// prefix - NULL is a valid value, must be checked --jvmtiError --JvmtiEnv::SetNativeMethodPrefix(const char* prefix) { -- return prefix == NULL? -- SetNativeMethodPrefixes(0, NULL) : -- SetNativeMethodPrefixes(1, (char**)&prefix); --} /* end SetNativeMethodPrefix */ -- -- --// prefix_count - pre-checked to be greater than or equal to 0 --// prefixes - pre-checked for NULL --jvmtiError --JvmtiEnv::SetNativeMethodPrefixes(jint prefix_count, char** prefixes) { -- // Have to grab JVMTI thread state lock to be sure that some thread -- // isn't accessing the prefixes at the same time we are setting them. -- // No locks during VM bring-up. -- if (Threads::number_of_threads() == 0) { -- return set_native_method_prefixes(prefix_count, prefixes); -- } else { -- MutexLocker mu(JvmtiThreadState_lock); -- return set_native_method_prefixes(prefix_count, prefixes); -- } --} /* end SetNativeMethodPrefixes */ -- -- - // - // Raw Monitor functions - // -@@ -2853,6 +3147,7 @@ - // JNI Function Interception functions - // - -+ - // function_table - pre-checked for NULL - jvmtiError - JvmtiEnv::SetJNIFunctionTable(const jniNativeInterface* function_table) { -@@ -2864,73 +3159,20 @@ - } /* end SetJNIFunctionTable */ - - --// function_table - pre-checked for NULL --jvmtiError --JvmtiEnv::GetJNIFunctionTable(jniNativeInterface** function_table) { -- *function_table=(jniNativeInterface*)jvmtiMalloc(sizeof(jniNativeInterface)); -- if (*function_table == NULL) -- return JVMTI_ERROR_OUT_OF_MEMORY; -- memcpy(*function_table,(JavaThread::current())->get_jni_functions(),sizeof(jniNativeInterface)); -- return JVMTI_ERROR_NONE; --} /* end GetJNIFunctionTable */ -- -- -- // -- // Event Management functions -- // -- --// callbacks - NULL is a valid value, must be checked --// size_of_callbacks - pre-checked to be greater than or equal to 0 --jvmtiError --JvmtiEnv::SetEventCallbacks(const jvmtiEventCallbacks* callbacks, jint size_of_callbacks) { -- JvmtiEventController::set_event_callbacks(this, callbacks, size_of_callbacks); -- return JVMTI_ERROR_NONE; --} /* end SetEventCallbacks */ -- -- --// event_thread - NULL is a valid value, must be checked --jvmtiError --JvmtiEnv::SetEventNotificationMode(jvmtiEventMode mode, jvmtiEvent event_type, jthread event_thread, ...) { -- JavaThread* java_thread = NULL; -- if (event_thread != NULL) { -- oop thread_oop = JNIHandles::resolve_external_guard(event_thread); -- if (thread_oop == NULL) { -- return JVMTI_ERROR_INVALID_THREAD; -- } -- if (!thread_oop->is_a(SystemDictionary::thread_klass())) { -- return JVMTI_ERROR_INVALID_THREAD; -- } -- java_thread = java_lang_Thread::thread(thread_oop); -- if (java_thread == NULL) { -- return JVMTI_ERROR_THREAD_NOT_ALIVE; -- } -- } -- -- // event_type must be valid -- if (!JvmtiEventController::is_valid_event_type(event_type)) { -- return JVMTI_ERROR_INVALID_EVENT_TYPE; -- } -- -- // global events cannot be controlled at thread level. -- if (java_thread != NULL && JvmtiEventController::is_global_event(event_type)) { -- return JVMTI_ERROR_ILLEGAL_ARGUMENT; -- } -- -- bool enabled = (mode == JVMTI_ENABLE); -- -- // assure that needed capabilities are present -- if (enabled && !JvmtiUtil::has_event_capability(event_type, get_capabilities())) { -- return JVMTI_ERROR_MUST_POSSESS_CAPABILITY; -- } -- -- if (event_type == JVMTI_EVENT_CLASS_FILE_LOAD_HOOK && enabled) { -- record_class_file_load_hook_enabled(); -- } -- JvmtiEventController::set_user_enabled(this, java_thread, event_type, enabled); -- -+// function_table - pre-checked for NULL -+jvmtiError -+JvmtiEnv::GetJNIFunctionTable(jniNativeInterface** function_table) { -+ *function_table=(jniNativeInterface*)jvmtiMalloc(sizeof(jniNativeInterface)); -+ if (*function_table == NULL) -+ return JVMTI_ERROR_OUT_OF_MEMORY; -+ memcpy(*function_table,(JavaThread::current())->get_jni_functions(),sizeof(jniNativeInterface)); - return JVMTI_ERROR_NONE; --} /* end SetEventNotificationMode */ -+} /* end GetJNIFunctionTable */ -+ - -+ // -+ // Event Management functions -+ // - - jvmtiError - JvmtiEnv::GenerateEvents(jvmtiEvent event_type) { -@@ -2980,47 +3222,6 @@ - return JvmtiExtensions::set_event_callback(this, extension_event_index, callback); - } /* end SetExtensionEventCallback */ - -- -- // -- // Capability functions -- // -- --// capabilities_ptr - pre-checked for NULL --jvmtiError --JvmtiEnv::GetPotentialCapabilities(jvmtiCapabilities* capabilities_ptr) { -- JvmtiManageCapabilities::get_potential_capabilities(get_capabilities(), -- get_prohibited_capabilities(), -- capabilities_ptr); -- return JVMTI_ERROR_NONE; --} /* end GetPotentialCapabilities */ -- -- --// capabilities_ptr - pre-checked for NULL --jvmtiError --JvmtiEnv::AddCapabilities(const jvmtiCapabilities* capabilities_ptr) { -- return JvmtiManageCapabilities::add_capabilities(get_capabilities(), -- get_prohibited_capabilities(), -- capabilities_ptr, -- get_capabilities()); --} /* end AddCapabilities */ -- -- --// capabilities_ptr - pre-checked for NULL --jvmtiError --JvmtiEnv::RelinquishCapabilities(const jvmtiCapabilities* capabilities_ptr) { -- JvmtiManageCapabilities::relinquish_capabilities(get_capabilities(), capabilities_ptr, get_capabilities()); -- return JVMTI_ERROR_NONE; --} /* end RelinquishCapabilities */ -- -- --// capabilities_ptr - pre-checked for NULL --jvmtiError --JvmtiEnv::GetCapabilities(jvmtiCapabilities* capabilities_ptr) { -- JvmtiManageCapabilities::copy_capabilities(get_capabilities(), capabilities_ptr); -- return JVMTI_ERROR_NONE; --} /* end GetCapabilities */ -- -- - // - // Timers functions - // -@@ -3082,115 +3283,6 @@ - return JVMTI_ERROR_NONE; - } /* end GetAvailableProcessors */ - -- -- // -- // Class Loader Search functions -- // -- --// segment - pre-checked for NULL --jvmtiError --JvmtiEnv::AddToBootstrapClassLoaderSearch(const char* segment) { -- jvmtiPhase phase = get_phase(); -- if (phase == JVMTI_PHASE_ONLOAD) { -- Arguments::append_sysclasspath(segment); -- return JVMTI_ERROR_NONE; -- } else { -- assert(phase == JVMTI_PHASE_LIVE, "sanity check"); -- -- // create the zip entry -- ClassPathZipEntry* zip_entry = ClassLoader::create_class_path_zip_entry(segment); -- if (zip_entry == NULL) { -- return JVMTI_ERROR_ILLEGAL_ARGUMENT; -- } -- -- // lock the loader -- Thread* thread = Thread::current(); -- HandleMark hm; -- Handle loader_lock = Handle(thread, SystemDictionary::system_loader_lock()); -- -- ObjectLocker ol(loader_lock, thread); -- -- // add the jar file to the bootclasspath -- if (TraceClassLoading) { -- tty->print_cr("[Opened %s]", zip_entry->name()); -- } -- ClassLoader::add_to_list(zip_entry); -- return JVMTI_ERROR_NONE; -- } -- --} /* end AddToBootstrapClassLoaderSearch */ -- -- --// segment - pre-checked for NULL --jvmtiError --JvmtiEnv::AddToSystemClassLoaderSearch(const char* segment) { -- jvmtiPhase phase = get_phase(); -- -- if (phase == JVMTI_PHASE_ONLOAD) { -- for (SystemProperty* p = Arguments::system_properties(); p != NULL; p = p->next()) { -- if (strcmp("java.class.path", p->key()) == 0) { -- p->append_value(segment); -- break; -- } -- } -- return JVMTI_ERROR_NONE; -- } else { -- HandleMark hm; -- -- assert(phase == JVMTI_PHASE_LIVE, "sanity check"); -- -- // create the zip entry (which will open the zip file and hence -- // check that the segment is indeed a zip file). -- ClassPathZipEntry* zip_entry = ClassLoader::create_class_path_zip_entry(segment); -- if (zip_entry == NULL) { -- return JVMTI_ERROR_ILLEGAL_ARGUMENT; -- } -- delete zip_entry; // no longer needed -- -- // lock the loader -- Thread* THREAD = Thread::current(); -- Handle loader = Handle(THREAD, SystemDictionary::java_system_loader()); -- -- ObjectLocker ol(loader, THREAD); -- -- // need the path as java.lang.String -- Handle path = java_lang_String::create_from_str(segment, THREAD); -- if (HAS_PENDING_EXCEPTION) { -- CLEAR_PENDING_EXCEPTION; -- return JVMTI_ERROR_INTERNAL; -- } -- -- instanceKlassHandle loader_ik(THREAD, loader->klass()); -- -- // Invoke the appendToClassPathForInstrumentation method - if the method -- // is not found it means the loader doesn't support adding to the class path -- // in the live phase. -- { -- JavaValue res(T_VOID); -- JavaCalls::call_special(&res, -- loader, -- loader_ik, -- vmSymbolHandles::appendToClassPathForInstrumentation_name(), -- vmSymbolHandles::appendToClassPathForInstrumentation_signature(), -- path, -- THREAD); -- if (HAS_PENDING_EXCEPTION) { -- symbolOop ex_name = PENDING_EXCEPTION->klass()->klass_part()->name(); -- CLEAR_PENDING_EXCEPTION; -- -- if (ex_name == vmSymbols::java_lang_NoSuchMethodError()) { -- return JVMTI_ERROR_CLASS_LOADER_UNSUPPORTED; -- } else { -- return JVMTI_ERROR_INTERNAL; -- } -- } -- } -- -- return JVMTI_ERROR_NONE; -- } --} /* end AddToSystemClassLoaderSearch */ -- -- - // - // System Properties functions - // -@@ -3263,96 +3355,4 @@ - return err; - } /* end SetSystemProperty */ - -- -- // -- // General functions -- // -- --// phase_ptr - pre-checked for NULL --jvmtiError --JvmtiEnv::GetPhase(jvmtiPhase* phase_ptr) { -- *phase_ptr = get_phase(); -- return JVMTI_ERROR_NONE; --} /* end GetPhase */ -- -- --jvmtiError --JvmtiEnv::DisposeEnvironment() { -- dispose(); -- return JVMTI_ERROR_NONE; --} /* end DisposeEnvironment */ -- -- --// data - NULL is a valid value, must be checked --jvmtiError --JvmtiEnv::SetEnvironmentLocalStorage(const void* data) { -- set_env_local_storage(data); -- return JVMTI_ERROR_NONE; --} /* end SetEnvironmentLocalStorage */ -- -- --// data_ptr - pre-checked for NULL --jvmtiError --JvmtiEnv::GetEnvironmentLocalStorage(void** data_ptr) { -- *data_ptr = (void*)get_env_local_storage(); -- return JVMTI_ERROR_NONE; --} /* end GetEnvironmentLocalStorage */ -- -- --// version_ptr - pre-checked for NULL --jvmtiError --JvmtiEnv::GetVersionNumber(jint* version_ptr) { -- *version_ptr = JVMTI_VERSION; -- return JVMTI_ERROR_NONE; --} /* end GetVersionNumber */ -- -- --// name_ptr - pre-checked for NULL --jvmtiError --JvmtiEnv::GetErrorName(jvmtiError error, char** name_ptr) { -- if (error < JVMTI_ERROR_NONE || error > JVMTI_ERROR_MAX) { -- return JVMTI_ERROR_ILLEGAL_ARGUMENT; -- } -- const char *name = JvmtiUtil::error_name(error); -- if (name == NULL) { -- return JVMTI_ERROR_ILLEGAL_ARGUMENT; -- } -- size_t len = strlen(name) + 1; -- jvmtiError err = allocate(len, (unsigned char**)name_ptr); -- if (err == JVMTI_ERROR_NONE) { -- memcpy(*name_ptr, name, len); -- } -- return err; --} /* end GetErrorName */ -- -- --jvmtiError --JvmtiEnv::SetVerboseFlag(jvmtiVerboseFlag flag, jboolean value) { -- switch (flag) { -- case JVMTI_VERBOSE_OTHER: -- // ignore -- break; -- case JVMTI_VERBOSE_CLASS: -- TraceClassLoading = value != 0; -- TraceClassUnloading = value != 0; -- break; -- case JVMTI_VERBOSE_GC: -- PrintGC = value != 0; -- TraceClassUnloading = value != 0; -- break; -- case JVMTI_VERBOSE_JNI: -- PrintJNIResolving = value != 0; -- break; -- default: -- return JVMTI_ERROR_ILLEGAL_ARGUMENT; -- }; -- return JVMTI_ERROR_NONE; --} /* end SetVerboseFlag */ -- -- --// format_ptr - pre-checked for NULL --jvmtiError --JvmtiEnv::GetJLocationFormat(jvmtiJlocationFormat* format_ptr) { -- *format_ptr = JVMTI_JLOCATION_JVMBCI; -- return JVMTI_ERROR_NONE; --} /* end GetJLocationFormat */ -+#endif // !JVMTI_KERNEL -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp openjdk/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)jvmtiEnvBase.cpp 1.89 07/05/17 16:04:59 JVM" --#endif - /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -56,8 +53,10 @@ - - JvmtiManageCapabilities::initialize(); - -+#ifndef JVMTI_KERNEL - // register extension functions and events - JvmtiExtensions::register_extensions(); -+#endif // !JVMTI_KERNEL - - #ifdef JVMTI_TRACE - JvmtiTrace::initialize(); -@@ -150,9 +149,6 @@ - // checking for a valid environment when setting callbacks (while - // holding the JvmtiThreadState_lock). - -- JvmtiTagMap* tag_map_to_deallocate = _tag_map; -- set_tag_map(NULL); -- - // Mark as invalid. - _magic = DISPOSED_MAGIC; - -@@ -163,10 +159,14 @@ - // Same situation as with events (see above) - set_native_method_prefixes(0, NULL); - -+#ifndef JVMTI_KERNEL -+ JvmtiTagMap* tag_map_to_deallocate = _tag_map; -+ set_tag_map(NULL); - // A tag map can be big, deallocate it now - if (tag_map_to_deallocate != NULL) { - delete tag_map_to_deallocate; - } -+#endif // !JVMTI_KERNEL - - _needs_clean_up = true; - } -@@ -178,11 +178,14 @@ - // There is a small window of time during which the tag map of a - // disposed environment could have been reallocated. - // Make sure it is gone. -+#ifndef JVMTI_KERNEL - JvmtiTagMap* tag_map_to_deallocate = _tag_map; - set_tag_map(NULL); -+ // A tag map can be big, deallocate it now - if (tag_map_to_deallocate != NULL) { - delete tag_map_to_deallocate; - } -+#endif // !JVMTI_KERNEL - - _magic = BAD_MAGIC; - } -@@ -399,7 +402,6 @@ - } - } - -- - // Called from JVMTI entry points which perform stack walking. If the - // associated JavaThread is the current thread, then wait_for_suspend - // is not used. Otherwise, it determines if we should wait for the -@@ -523,6 +525,8 @@ - return (jclass)jni_reference(Klass::cast(k)->java_mirror()); - } - -+#ifndef JVMTI_KERNEL -+ - // - // Field Information - // -@@ -1408,3 +1412,4 @@ - } - } - -+#endif // !JVMTI_KERNEL -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiEnvBase.hpp openjdk/hotspot/src/share/vm/prims/jvmtiEnvBase.hpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiEnvBase.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiEnvBase.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)jvmtiEnvBase.hpp 1.68 07/05/23 10:53:43 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -56,6 +53,11 @@ - - public: - -+ enum { -+ JDK15_JVMTI_VERSION = JVMTI_VERSION_1_0 + 33, /* version: 1.0.33 */ -+ JDK16_JVMTI_VERSION = JVMTI_VERSION_1_1 + 102 /* version: 1.1.102 */ -+ }; -+ - static jvmtiPhase get_phase() { return _phase; } - static void set_phase(jvmtiPhase phase) { _phase = phase; } - static bool is_vm_live() { return _phase == JVMTI_PHASE_LIVE; } -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiEnvFill.java openjdk/hotspot/src/share/vm/prims/jvmtiEnvFill.java ---- openjdk6/hotspot/src/share/vm/prims/jvmtiEnvFill.java 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiEnvFill.java 2007-12-14 08:57:03.000000000 +0100 -@@ -211,7 +211,7 @@ - top.add(line); - } else { - trimmed = line.trim(); -- if (!trimmed.equals("") && !trimmed.startsWith("//")) { -+ if (!trimmed.equals("") && !trimmed.startsWith("//") && !trimmed.startsWith("#")) { - error("only comments and blank lines allowed between functions"); - } - before.add(line); -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiEnvThreadState.cpp openjdk/hotspot/src/share/vm/prims/jvmtiEnvThreadState.cpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiEnvThreadState.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiEnvThreadState.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)jvmtiEnvThreadState.cpp 1.23 07/05/23 10:53:46 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -314,4 +311,3 @@ - clear_current_location(); - } - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiEnvThreadState.hpp openjdk/hotspot/src/share/vm/prims/jvmtiEnvThreadState.hpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiEnvThreadState.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiEnvThreadState.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)jvmtiEnvThreadState.hpp 1.17 07/05/05 17:06:37 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -176,4 +173,3 @@ - }; - - #endif /* _JAVA_JVMTIENVTHREADSTATE_H_ */ -- -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiEventController.cpp openjdk/hotspot/src/share/vm/prims/jvmtiEventController.cpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiEventController.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiEventController.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)jvmtiEventController.cpp 1.56 07/05/23 10:53:48 JVM" --#endif - /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -322,7 +319,7 @@ - void VM_ChangeSingleStep::doit() { - JvmtiEventControllerPrivate::set_should_post_single_step(_on); - if (_on) { -- AbstractInterpreter::notice_safepoints(); -+ Interpreter::notice_safepoints(); - } - } - -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiEventController.hpp openjdk/hotspot/src/share/vm/prims/jvmtiEventController.hpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiEventController.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiEventController.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)jvmtiEventController.hpp 1.22 07/05/05 17:06:37 JVM" --#endif - /* - * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiEventController.inline.hpp openjdk/hotspot/src/share/vm/prims/jvmtiEventController.inline.hpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiEventController.inline.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiEventController.inline.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)jvmtiEventController.inline.hpp 1.14 07/05/05 17:06:37 JVM" --#endif - /* - * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -102,4 +99,3 @@ - inline bool JvmtiEventController::is_enabled(jvmtiEvent event_type) { - return _universal_global_event_enabled.is_enabled(event_type); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiExport.cpp openjdk/hotspot/src/share/vm/prims/jvmtiExport.cpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiExport.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiExport.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)jvmtiExport.cpp 1.125 07/05/29 09:44:25 JVM" --#endif - /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -36,7 +33,6 @@ - #define EVT_TRACE(evt,out) - #endif - -- - /////////////////////////////////////////////////////////////// - // - // JvmtiEventTransition -@@ -268,225 +264,58 @@ - } - }; - --static inline klassOop oop_to_klassOop(oop obj) { -- klassOop k = obj->klass(); -- -- // if the object is a java.lang.Class then return the java mirror -- if (k == SystemDictionary::class_klass()) { -- if (!java_lang_Class::is_primitive(obj)) { -- k = java_lang_Class::as_klassOop(obj); -- assert(k != NULL, "class for non-primitive mirror must exist"); -- } -- } -- return k; --} -- --class JvmtiVMObjectAllocEventMark : public JvmtiClassEventMark { -- private: -- jobject _jobj; -- jlong _size; -- public: -- JvmtiVMObjectAllocEventMark(JavaThread *thread, oop obj) : JvmtiClassEventMark(thread, oop_to_klassOop(obj)) { -- _jobj = (jobject)to_jobject(obj); -- _size = obj->size() * wordSize; -- }; -- jobject jni_jobject() { return _jobj; } -- jlong size() { return _size; } --}; -- --class JvmtiCompiledMethodLoadEventMark : public JvmtiMethodEventMark { -- private: -- jint _code_size; -- const void *_code_data; -- jint _map_length; -- jvmtiAddrLocationMap *_map; -- const void *_compile_info; -- public: -- JvmtiCompiledMethodLoadEventMark(JavaThread *thread, nmethod *nm) -- : JvmtiMethodEventMark(thread,methodHandle(thread, nm->method())) { -- _code_data = nm->code_begin(); -- _code_size = nm->code_size(); -- _compile_info = NULL; /* no info for our VM. */ -- JvmtiCodeBlobEvents::build_jvmti_addr_location_map(nm, &_map, &_map_length); -- } -- ~JvmtiCompiledMethodLoadEventMark() { -- FREE_C_HEAP_ARRAY(jvmtiAddrLocationMap, _map); -- } -- -- jint code_size() { return _code_size; } -- const void *code_data() { return _code_data; } -- jint map_length() { return _map_length; } -- const jvmtiAddrLocationMap* map() { return _map; } -- const void *compile_info() { return _compile_info; } --}; -+////////////////////////////////////////////////////////////////////////////// - -+int JvmtiExport::_field_access_count = 0; -+int JvmtiExport::_field_modification_count = 0; - -+bool JvmtiExport::_can_access_local_variables = false; -+bool JvmtiExport::_can_examine_or_deopt_anywhere = false; -+bool JvmtiExport::_can_hotswap_or_post_breakpoint = false; -+bool JvmtiExport::_can_modify_any_class = false; -+bool JvmtiExport::_can_walk_any_space = false; - --class JvmtiMonitorEventMark : public JvmtiThreadEventMark { --private: -- jobject _jobj; --public: -- JvmtiMonitorEventMark(JavaThread *thread, oop object) -- : JvmtiThreadEventMark(thread){ -- _jobj = to_jobject(object); -- } -- jobject jni_object() { return _jobj; } --}; -+bool JvmtiExport::_has_redefined_a_class = false; -+bool JvmtiExport::_all_dependencies_are_recorded = false; - --/////////////////////////////////////////////////////////////// - // --// pending CompiledMethodUnload support -+// field access management - // - --bool JvmtiExport::_have_pending_compiled_method_unload_events; --GrowableArray* JvmtiExport::_pending_compiled_method_unload_method_ids; --GrowableArray* JvmtiExport::_pending_compiled_method_unload_code_begins; --JavaThread* JvmtiExport::_current_poster; -- --// post any pending CompiledMethodUnload events -- --void JvmtiExport::post_pending_compiled_method_unload_events() { -- JavaThread* self = JavaThread::current(); -- assert(!self->owns_locks(), "can't hold locks"); -- -- // Indicates if this is the first activiation of this function. -- // In theory the profiler's callback could call back into VM and provoke -- // another CompiledMethodLoad event to be posted from this thread. As the -- // stack rewinds we need to ensure that the original activation does the -- // completion and notifies any waiters. -- bool first_activation = false; -- -- // the jmethodID (may not be valid) to be used for a single event -- jmethodID method; -- const void *code_begin; -- -- // grab the monitor and check if another thread is already posting -- // events. If there is another thread posting events then we wait -- // until it completes. (In theory we could check the pending events to -- // see if any of the addresses overlap with the event that we want to -- // post but as it will happen so rarely we just block any thread waiting -- // to post a CompiledMethodLoad or DynamicCodeGenerated event until all -- // pending CompiledMethodUnload events have been posted). -- // -- // If another thread isn't posting we examine the list of pending jmethodIDs. -- // If the list is empty then we are done. If it's not empty then this thread -- // (self) becomes the pending event poster and we remove the top (last) -- // event from the list. Note that this means we remove the newest event first -- // but as they are all CompiledMethodUnload events the order doesn't matter. -- // Once we have removed a jmethodID then we exit the monitor. Any other thread -- // wanting to post a CompiledMethodLoad or DynamicCodeGenerated event will -- // be forced to wait on the monitor. -- { -- MutexLocker mu(JvmtiPendingEvent_lock); -- if (_current_poster != self) { -- while (_current_poster != NULL) { -- JvmtiPendingEvent_lock->wait(); -- } -- } -- if ((_pending_compiled_method_unload_method_ids == NULL) || -- (_pending_compiled_method_unload_method_ids->length() == 0)) { -- return; -- } -- if (_current_poster == NULL) { -- _current_poster = self; -- first_activation = true; -- } else { -- // re-entrant -- guarantee(_current_poster == self, "checking"); -- } -- method = _pending_compiled_method_unload_method_ids->pop(); -- code_begin = _pending_compiled_method_unload_code_begins->pop(); -- } -- -- // This thread is the pending event poster so it first posts the CompiledMethodUnload -- // event for the jmethodID that has been removed from the list. Once posted it -- // re-grabs the monitor and checks the list again. If the list is empty then and this -- // is the first activation of the function then we reset the _have_pending_events -- // flag, cleanup _current_poster to indicate that no thread is now servicing the -- // pending events list, and finally notify any thread that might be waiting. -- for (;;) { -- EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD, -- ("JVMTI [%s] method compile unload event triggered", -- JvmtiTrace::safe_get_thread_name(self))); -- -- // post the event for each environment that has this event enabled. -- JvmtiEnvIterator it; -- for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { -- if (env->is_enabled(JVMTI_EVENT_COMPILED_METHOD_UNLOAD)) { -- EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD, -- ("JVMTI [%s] class compile method unload event sent jmethodID " PTR_FORMAT, -- JvmtiTrace::safe_get_thread_name(self), method)); -- -- JvmtiEventMark jem(self); -- JvmtiJavaThreadEventTransition jet(self); -- jvmtiEventCompiledMethodUnload callback = env->callbacks()->CompiledMethodUnload; -- if (callback != NULL) { -- (*callback)(env->jvmti_external(), method, code_begin); -- } -- } -- } -- -- // event posted, now re-grab monitor and get the next event -- // If there's no next event then we are done. If this is the first -- // activiation of this function by this thread notify any waiters -- // so that they can post. -- { -- MutexLocker ml(JvmtiPendingEvent_lock); -- if (_pending_compiled_method_unload_method_ids->length() == 0) { -- if (first_activation) { -- _have_pending_compiled_method_unload_events = false; -- _current_poster = NULL; -- JvmtiPendingEvent_lock->notify_all(); -- } -- return; -- } -- method = _pending_compiled_method_unload_method_ids->pop(); -- code_begin = _pending_compiled_method_unload_code_begins->pop(); -- } -- } -+// interpreter generator needs the address of the counter -+address JvmtiExport::get_field_access_count_addr() { -+ // We don't grab a lock because we don't want to -+ // serialize field access between all threads. This means that a -+ // thread on another processor can see the wrong count value and -+ // may either miss making a needed call into post_field_access() -+ // or will make an unneeded call into post_field_access(). We pay -+ // this price to avoid slowing down the VM when we aren't watching -+ // field accesses. -+ // Other access/mutation safe by virtue of being in VM state. -+ return (address)(&_field_access_count); - } - --/////////////////////////////////////////////////////////////// - // --// JvmtiExport -+// field modification management - // - --void JvmtiExport::post_raw_breakpoint(JavaThread *thread, methodOop method, address location) { -- HandleMark hm(thread); -- methodHandle mh(thread, method); -- -- JvmtiThreadState *state = thread->jvmti_thread_state(); -- if (state == NULL) { -- return; -- } -- EVT_TRIG_TRACE(JVMTI_EVENT_BREAKPOINT, ("JVMTI [%s] Trg Breakpoint triggered", -- JvmtiTrace::safe_get_thread_name(thread))); -- JvmtiEnvThreadStateIterator it(state); -- for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { -- ets->compare_and_set_current_location(mh(), location, JVMTI_EVENT_BREAKPOINT); -- if (!ets->breakpoint_posted() && ets->is_enabled(JVMTI_EVENT_BREAKPOINT)) { -- ThreadState old_os_state = thread->osthread()->get_state(); -- thread->osthread()->set_state(BREAKPOINTED); -- EVT_TRACE(JVMTI_EVENT_BREAKPOINT, ("JVMTI [%s] Evt Breakpoint sent %s.%s @ %d", -- JvmtiTrace::safe_get_thread_name(thread), -- (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(), -- (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(), -- location - mh()->code_base() )); -+// interpreter generator needs the address of the counter -+address JvmtiExport::get_field_modification_count_addr() { -+ // We don't grab a lock because we don't -+ // want to serialize field modification between all threads. This -+ // means that a thread on another processor can see the wrong -+ // count value and may either miss making a needed call into -+ // post_field_modification() or will make an unneeded call into -+ // post_field_modification(). We pay this price to avoid slowing -+ // down the VM when we aren't watching field modifications. -+ // Other access/mutation safe by virtue of being in VM state. -+ return (address)(&_field_modification_count); -+} - -- JvmtiEnv *env = ets->get_env(); -- JvmtiLocationEventMark jem(thread, mh, location); -- JvmtiJavaThreadEventTransition jet(thread); -- jvmtiEventBreakpoint callback = env->callbacks()->Breakpoint; -- if (callback != NULL) { -- (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), -- jem.jni_methodID(), jem.location()); -- } - -- ets->set_breakpoint_posted(); -- thread->osthread()->set_state(old_os_state); -- } -- } --} -+/////////////////////////////////////////////////////////////// -+// Functions needed by java.lang.instrument for starting up javaagent. -+/////////////////////////////////////////////////////////////// - - jint - JvmtiExport::get_jvmti_interface(JavaVM *jvm, void **penv, jint version) { -@@ -516,65 +345,14 @@ - } - } - -+void JvmtiExport::enter_primordial_phase() { -+ JvmtiEnvBase::set_phase(JVMTI_PHASE_PRIMORDIAL); -+} - --////////////////////////////////////////////////////////////////////////////// -- --int JvmtiExport::_field_access_count = 0; --int JvmtiExport::_field_modification_count = 0; -- --bool JvmtiExport::_can_get_source_debug_extension = false; --bool JvmtiExport::_can_examine_or_deopt_anywhere = false; --bool JvmtiExport::_can_maintain_original_method_order = false; --bool JvmtiExport::_can_post_interpreter_events = false; --bool JvmtiExport::_can_hotswap_or_post_breakpoint = false; --bool JvmtiExport::_can_modify_any_class = false; --bool JvmtiExport::_can_walk_any_space = false; --bool JvmtiExport::_can_access_local_variables = false; --bool JvmtiExport::_can_post_exceptions = false; --bool JvmtiExport::_can_post_breakpoint = false; --bool JvmtiExport::_can_post_field_access = false; --bool JvmtiExport::_can_post_field_modification = false; --bool JvmtiExport::_can_post_method_entry = false; --bool JvmtiExport::_can_post_method_exit = false; --bool JvmtiExport::_can_pop_frame = false; --bool JvmtiExport::_can_force_early_return = false; -- --bool JvmtiExport::_should_post_single_step = false; --bool JvmtiExport::_should_post_field_access = false; --bool JvmtiExport::_should_post_field_modification = false; --bool JvmtiExport::_should_post_class_load = false; --bool JvmtiExport::_should_post_class_prepare = false; --bool JvmtiExport::_should_post_class_unload = false; --bool JvmtiExport::_should_post_thread_life = false; --bool JvmtiExport::_should_clean_up_heap_objects = false; --bool JvmtiExport::_should_post_class_file_load_hook = false; --bool JvmtiExport::_should_post_native_method_bind = false; --bool JvmtiExport::_should_post_dynamic_code_generated = false; --bool JvmtiExport::_should_post_data_dump = false; --bool JvmtiExport::_should_post_compiled_method_load = false; --bool JvmtiExport::_should_post_compiled_method_unload = false; --bool JvmtiExport::_should_post_monitor_contended_enter = false; --bool JvmtiExport::_should_post_monitor_contended_entered = false; --bool JvmtiExport::_should_post_monitor_wait = false; --bool JvmtiExport::_should_post_monitor_waited = false; --bool JvmtiExport::_should_post_garbage_collection_start = false; --bool JvmtiExport::_should_post_garbage_collection_finish = false; --bool JvmtiExport::_should_post_object_free = false; --bool JvmtiExport::_should_post_resource_exhausted = false; --bool JvmtiExport::_should_post_vm_object_alloc = false; --bool JvmtiExport::_has_redefined_a_class = false; --bool JvmtiExport::_all_dependencies_are_recorded = false; -- -- -- --void JvmtiExport::enter_primordial_phase() { -- JvmtiEnvBase::set_phase(JVMTI_PHASE_PRIMORDIAL); --} -- --void JvmtiExport::enter_start_phase() { -- JvmtiManageCapabilities::recompute_always_capabilities(); -- JvmtiEnvBase::set_phase(JVMTI_PHASE_START); --} -+void JvmtiExport::enter_start_phase() { -+ JvmtiManageCapabilities::recompute_always_capabilities(); -+ JvmtiEnvBase::set_phase(JVMTI_PHASE_START); -+} - - void JvmtiExport::enter_onload_phase() { - JvmtiEnvBase::set_phase(JVMTI_PHASE_ONLOAD); -@@ -584,191 +362,573 @@ - JvmtiEnvBase::set_phase(JVMTI_PHASE_LIVE); - } - -- -- --//////////////////////////////////////////////////////////////////////////////////////////////// -- -- --// --// field access management --// -- --// interpreter generator needs the address of the counter --address JvmtiExport::get_field_access_count_addr() { -- // We don't grab a lock because we don't want to -- // serialize field access between all threads. This means that a -- // thread on another processor can see the wrong count value and -- // may either miss making a needed call into post_field_access() -- // or will make an unneeded call into post_field_access(). We pay -- // this price to avoid slowing down the VM when we aren't watching -- // field accesses. -- // Other access/mutation safe by virtue of being in VM state. -- return (address)(&_field_access_count); --} -- -- - // --// field modification management -+// JVMTI events that the VM posts to the debugger and also startup agent -+// and call the agent's premain() for java.lang.instrument. - // - --// interpreter generator needs the address of the counter --address JvmtiExport::get_field_modification_count_addr() { -- // We don't grab a lock because we don't -- // want to serialize field modification between all threads. This -- // means that a thread on another processor can see the wrong -- // count value and may either miss making a needed call into -- // post_field_modification() or will make an unneeded call into -- // post_field_modification(). We pay this price to avoid slowing -- // down the VM when we aren't watching field modifications. -- // Other access/mutation safe by virtue of being in VM state. -- return (address)(&_field_modification_count); --} -- -+void JvmtiExport::post_vm_start() { -+ EVT_TRIG_TRACE(JVMTI_EVENT_VM_START, ("JVMTI Trg VM start event triggered" )); - --// --// JVMTI single step management --// --void JvmtiExport::at_single_stepping_point(JavaThread *thread, methodOop method, address location) { -- assert(JvmtiExport::should_post_single_step(), "must be single stepping"); -+ // can now enable some events -+ JvmtiEventController::vm_start(); - -- HandleMark hm(thread); -- methodHandle mh(thread, method); -+ JvmtiEnvIterator it; -+ for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { -+ if (env->is_enabled(JVMTI_EVENT_VM_START)) { -+ EVT_TRACE(JVMTI_EVENT_VM_START, ("JVMTI Evt VM start event sent" )); - -- // update information about current location and post a step event -- JvmtiThreadState *state = thread->jvmti_thread_state(); -- if (state == NULL) { -- return; -- } -- EVT_TRIG_TRACE(JVMTI_EVENT_SINGLE_STEP, ("JVMTI [%s] Trg Single Step triggered", -- JvmtiTrace::safe_get_thread_name(thread))); -- if (!state->hide_single_stepping()) { -- if (state->is_pending_step_for_popframe()) { -- state->process_pending_step_for_popframe(); -+ JavaThread *thread = JavaThread::current(); -+ JvmtiThreadEventMark jem(thread); -+ JvmtiJavaThreadEventTransition jet(thread); -+ jvmtiEventVMStart callback = env->callbacks()->VMStart; -+ if (callback != NULL) { -+ (*callback)(env->jvmti_external(), jem.jni_env()); - } -- if (state->is_pending_step_for_earlyret()) { -- state->process_pending_step_for_earlyret(); - } -- JvmtiExport::post_single_step(thread, mh(), location); - } - } - - --void JvmtiExport::expose_single_stepping(JavaThread *thread) { -- JvmtiThreadState *state = thread->jvmti_thread_state(); -- if (state != NULL) { -- state->clear_hide_single_stepping(); -- } --} -+void JvmtiExport::post_vm_initialized() { -+ EVT_TRIG_TRACE(JVMTI_EVENT_VM_INIT, ("JVMTI Trg VM init event triggered" )); - -+ // can now enable events -+ JvmtiEventController::vm_init(); - --bool JvmtiExport::hide_single_stepping(JavaThread *thread) { -- JvmtiThreadState *state = thread->jvmti_thread_state(); -- if (state != NULL && state->is_enabled(JVMTI_EVENT_SINGLE_STEP)) { -- state->set_hide_single_stepping(); -- return true; -- } else { -- return false; -+ JvmtiEnvIterator it; -+ for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { -+ if (env->is_enabled(JVMTI_EVENT_VM_INIT)) { -+ EVT_TRACE(JVMTI_EVENT_VM_INIT, ("JVMTI Evt VM init event sent" )); -+ -+ JavaThread *thread = JavaThread::current(); -+ JvmtiThreadEventMark jem(thread); -+ JvmtiJavaThreadEventTransition jet(thread); -+ jvmtiEventVMInit callback = env->callbacks()->VMInit; -+ if (callback != NULL) { -+ (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread()); -+ } -+ } - } - } - --// --// JVMTI events that the VM posts to the debugger --// -- --void JvmtiExport::post_vm_start() { -- EVT_TRIG_TRACE(JVMTI_EVENT_VM_START, ("JVMTI Trg VM start event triggered" )); - -- // can now enable some events -- JvmtiEventController::vm_start(); -+void JvmtiExport::post_vm_death() { -+ EVT_TRIG_TRACE(JVMTI_EVENT_VM_DEATH, ("JVMTI Trg VM death event triggered" )); - - JvmtiEnvIterator it; - for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { -- if (env->is_enabled(JVMTI_EVENT_VM_START)) { -- EVT_TRACE(JVMTI_EVENT_VM_START, ("JVMTI Evt VM start event sent" )); -+ if (env->is_enabled(JVMTI_EVENT_VM_DEATH)) { -+ EVT_TRACE(JVMTI_EVENT_VM_DEATH, ("JVMTI Evt VM death event sent" )); - - JavaThread *thread = JavaThread::current(); -- JvmtiThreadEventMark jem(thread); -+ JvmtiEventMark jem(thread); - JvmtiJavaThreadEventTransition jet(thread); -- jvmtiEventVMStart callback = env->callbacks()->VMStart; -+ jvmtiEventVMDeath callback = env->callbacks()->VMDeath; - if (callback != NULL) { - (*callback)(env->jvmti_external(), jem.jni_env()); - } - } - } -+ -+ JvmtiEnvBase::set_phase(JVMTI_PHASE_DEAD); -+ JvmtiEventController::vm_death(); -+} -+ -+char** -+JvmtiExport::get_all_native_method_prefixes(int* count_ptr) { -+ // Have to grab JVMTI thread state lock to be sure environment doesn't -+ // go away while we iterate them. No locks during VM bring-up. -+ if (Threads::number_of_threads() == 0 || SafepointSynchronize::is_at_safepoint()) { -+ return JvmtiEnvBase::get_all_native_method_prefixes(count_ptr); -+ } else { -+ MutexLocker mu(JvmtiThreadState_lock); -+ return JvmtiEnvBase::get_all_native_method_prefixes(count_ptr); -+ } - } - -+class JvmtiClassFileLoadHookPoster : public StackObj { -+ private: -+ symbolHandle _h_name; -+ Handle _class_loader; -+ Handle _h_protection_domain; -+ unsigned char ** _data_ptr; -+ unsigned char ** _end_ptr; -+ JavaThread * _thread; -+ jint _curr_len; -+ unsigned char * _curr_data; -+ JvmtiEnv * _curr_env; -+ jint * _cached_length_ptr; -+ unsigned char ** _cached_data_ptr; -+ JvmtiThreadState * _state; -+ KlassHandle * _h_class_being_redefined; -+ JvmtiClassLoadKind _load_kind; -+ -+ public: -+ inline JvmtiClassFileLoadHookPoster(symbolHandle h_name, Handle class_loader, -+ Handle h_protection_domain, -+ unsigned char **data_ptr, unsigned char **end_ptr, -+ unsigned char **cached_data_ptr, -+ jint *cached_length_ptr) { -+ _h_name = h_name; -+ _class_loader = class_loader; -+ _h_protection_domain = h_protection_domain; -+ _data_ptr = data_ptr; -+ _end_ptr = end_ptr; -+ _thread = JavaThread::current(); -+ _curr_len = *end_ptr - *data_ptr; -+ _curr_data = *data_ptr; -+ _curr_env = NULL; -+ _cached_length_ptr = cached_length_ptr; -+ _cached_data_ptr = cached_data_ptr; -+ *_cached_length_ptr = 0; -+ *_cached_data_ptr = NULL; -+ -+ _state = _thread->jvmti_thread_state(); -+ if (_state != NULL) { -+ _h_class_being_redefined = _state->get_class_being_redefined(); -+ _load_kind = _state->get_class_load_kind(); -+ // Clear class_being_redefined flag here. The action -+ // from agent handler could generate a new class file load -+ // hook event and if it is not cleared the new event generated -+ // from regular class file load could have this stale redefined -+ // class handle info. -+ _state->clear_class_being_redefined(); -+ } else { -+ // redefine and retransform will always set the thread state -+ _h_class_being_redefined = (KlassHandle *) NULL; -+ _load_kind = jvmti_class_load_kind_load; -+ } -+ } -+ -+ void post() { -+// EVT_TRIG_TRACE(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, -+// ("JVMTI [%s] class file load hook event triggered", -+// JvmtiTrace::safe_get_thread_name(_thread))); -+ post_all_envs(); -+ copy_modified_data(); -+ } -+ -+ private: -+ void post_all_envs() { -+ if (_load_kind != jvmti_class_load_kind_retransform) { -+ // for class load and redefine, -+ // call the non-retransformable agents -+ JvmtiEnvIterator it; -+ for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { -+ if (!env->is_retransformable() && env->is_enabled(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK)) { -+ // non-retransformable agents cannot retransform back, -+ // so no need to cache the original class file bytes -+ post_to_env(env, false); -+ } -+ } -+ } -+ JvmtiEnvIterator it; -+ for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { -+ // retransformable agents get all events -+ if (env->is_retransformable() && env->is_enabled(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK)) { -+ // retransformable agents need to cache the original class file -+ // bytes if changes are made via the ClassFileLoadHook -+ post_to_env(env, true); -+ } -+ } -+ } -+ -+ void post_to_env(JvmtiEnv* env, bool caching_needed) { -+ unsigned char *new_data = NULL; -+ jint new_len = 0; -+// EVT_TRACE(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, -+// ("JVMTI [%s] class file load hook event sent %s data_ptr = %d, data_len = %d", -+// JvmtiTrace::safe_get_thread_name(_thread), -+// _h_name.is_null() ? "NULL" : _h_name->as_utf8(), -+// _curr_data, _curr_len )); -+ JvmtiClassFileLoadEventMark jem(_thread, _h_name, _class_loader, -+ _h_protection_domain, -+ _h_class_being_redefined); -+ JvmtiJavaThreadEventTransition jet(_thread); -+ JNIEnv* jni_env = (JvmtiEnv::get_phase() == JVMTI_PHASE_PRIMORDIAL)? -+ NULL : jem.jni_env(); -+ jvmtiEventClassFileLoadHook callback = env->callbacks()->ClassFileLoadHook; -+ if (callback != NULL) { -+ (*callback)(env->jvmti_external(), jni_env, -+ jem.class_being_redefined(), -+ jem.jloader(), jem.class_name(), -+ jem.protection_domain(), -+ _curr_len, _curr_data, -+ &new_len, &new_data); -+ } -+ if (new_data != NULL) { -+ // this agent has modified class data. -+ if (caching_needed && *_cached_data_ptr == NULL) { -+ // data has been changed by the new retransformable agent -+ // and it hasn't already been cached, cache it -+ *_cached_data_ptr = (unsigned char *)os::malloc(_curr_len); -+ memcpy(*_cached_data_ptr, _curr_data, _curr_len); -+ *_cached_length_ptr = _curr_len; -+ } -+ -+ if (_curr_data != *_data_ptr) { -+ // curr_data is previous agent modified class data. -+ // And this has been changed by the new agent so -+ // we can delete it now. -+ _curr_env->Deallocate(_curr_data); -+ } -+ -+ // Class file data has changed by the current agent. -+ _curr_data = new_data; -+ _curr_len = new_len; -+ // Save the current agent env we need this to deallocate the -+ // memory allocated by this agent. -+ _curr_env = env; -+ } -+ } -+ -+ void copy_modified_data() { -+ // if one of the agent has modified class file data. -+ // Copy modified class data to new resources array. -+ if (_curr_data != *_data_ptr) { -+ *_data_ptr = NEW_RESOURCE_ARRAY(u1, _curr_len); -+ memcpy(*_data_ptr, _curr_data, _curr_len); -+ *_end_ptr = *_data_ptr + _curr_len; -+ _curr_env->Deallocate(_curr_data); -+ } -+ } -+}; -+ -+bool JvmtiExport::_should_post_class_file_load_hook = false; -+ -+// this entry is for class file load hook on class load, redefine and retransform -+void JvmtiExport::post_class_file_load_hook(symbolHandle h_name, -+ Handle class_loader, -+ Handle h_protection_domain, -+ unsigned char **data_ptr, -+ unsigned char **end_ptr, -+ unsigned char **cached_data_ptr, -+ jint *cached_length_ptr) { -+ JvmtiClassFileLoadHookPoster poster(h_name, class_loader, -+ h_protection_domain, -+ data_ptr, end_ptr, -+ cached_data_ptr, -+ cached_length_ptr); -+ poster.post(); -+} -+ -+void JvmtiExport::report_unsupported(bool on) { -+ // If any JVMTI service is turned on, we need to exit before native code -+ // tries to access nonexistant services. -+ if (on) { -+ vm_exit_during_initialization("Java Kernel does not support JVMTI."); -+ } -+} -+ -+ -+#ifndef JVMTI_KERNEL -+static inline klassOop oop_to_klassOop(oop obj) { -+ klassOop k = obj->klass(); -+ -+ // if the object is a java.lang.Class then return the java mirror -+ if (k == SystemDictionary::class_klass()) { -+ if (!java_lang_Class::is_primitive(obj)) { -+ k = java_lang_Class::as_klassOop(obj); -+ assert(k != NULL, "class for non-primitive mirror must exist"); -+ } -+ } -+ return k; -+} -+ -+class JvmtiVMObjectAllocEventMark : public JvmtiClassEventMark { -+ private: -+ jobject _jobj; -+ jlong _size; -+ public: -+ JvmtiVMObjectAllocEventMark(JavaThread *thread, oop obj) : JvmtiClassEventMark(thread, oop_to_klassOop(obj)) { -+ _jobj = (jobject)to_jobject(obj); -+ _size = obj->size() * wordSize; -+ }; -+ jobject jni_jobject() { return _jobj; } -+ jlong size() { return _size; } -+}; -+ -+class JvmtiCompiledMethodLoadEventMark : public JvmtiMethodEventMark { -+ private: -+ jint _code_size; -+ const void *_code_data; -+ jint _map_length; -+ jvmtiAddrLocationMap *_map; -+ const void *_compile_info; -+ public: -+ JvmtiCompiledMethodLoadEventMark(JavaThread *thread, nmethod *nm) -+ : JvmtiMethodEventMark(thread,methodHandle(thread, nm->method())) { -+ _code_data = nm->code_begin(); -+ _code_size = nm->code_size(); -+ _compile_info = NULL; /* no info for our VM. */ -+ JvmtiCodeBlobEvents::build_jvmti_addr_location_map(nm, &_map, &_map_length); -+ } -+ ~JvmtiCompiledMethodLoadEventMark() { -+ FREE_C_HEAP_ARRAY(jvmtiAddrLocationMap, _map); -+ } -+ -+ jint code_size() { return _code_size; } -+ const void *code_data() { return _code_data; } -+ jint map_length() { return _map_length; } -+ const jvmtiAddrLocationMap* map() { return _map; } -+ const void *compile_info() { return _compile_info; } -+}; -+ -+ -+ -+class JvmtiMonitorEventMark : public JvmtiThreadEventMark { -+private: -+ jobject _jobj; -+public: -+ JvmtiMonitorEventMark(JavaThread *thread, oop object) -+ : JvmtiThreadEventMark(thread){ -+ _jobj = to_jobject(object); -+ } -+ jobject jni_object() { return _jobj; } -+}; -+ -+/////////////////////////////////////////////////////////////// -+// -+// pending CompiledMethodUnload support -+// -+ -+bool JvmtiExport::_have_pending_compiled_method_unload_events; -+GrowableArray* JvmtiExport::_pending_compiled_method_unload_method_ids; -+GrowableArray* JvmtiExport::_pending_compiled_method_unload_code_begins; -+JavaThread* JvmtiExport::_current_poster; -+ -+// post any pending CompiledMethodUnload events -+ -+void JvmtiExport::post_pending_compiled_method_unload_events() { -+ JavaThread* self = JavaThread::current(); -+ assert(!self->owns_locks(), "can't hold locks"); -+ -+ // Indicates if this is the first activiation of this function. -+ // In theory the profiler's callback could call back into VM and provoke -+ // another CompiledMethodLoad event to be posted from this thread. As the -+ // stack rewinds we need to ensure that the original activation does the -+ // completion and notifies any waiters. -+ bool first_activation = false; -+ -+ // the jmethodID (may not be valid) to be used for a single event -+ jmethodID method; -+ const void *code_begin; -+ -+ // grab the monitor and check if another thread is already posting -+ // events. If there is another thread posting events then we wait -+ // until it completes. (In theory we could check the pending events to -+ // see if any of the addresses overlap with the event that we want to -+ // post but as it will happen so rarely we just block any thread waiting -+ // to post a CompiledMethodLoad or DynamicCodeGenerated event until all -+ // pending CompiledMethodUnload events have been posted). -+ // -+ // If another thread isn't posting we examine the list of pending jmethodIDs. -+ // If the list is empty then we are done. If it's not empty then this thread -+ // (self) becomes the pending event poster and we remove the top (last) -+ // event from the list. Note that this means we remove the newest event first -+ // but as they are all CompiledMethodUnload events the order doesn't matter. -+ // Once we have removed a jmethodID then we exit the monitor. Any other thread -+ // wanting to post a CompiledMethodLoad or DynamicCodeGenerated event will -+ // be forced to wait on the monitor. -+ { -+ MutexLocker mu(JvmtiPendingEvent_lock); -+ if (_current_poster != self) { -+ while (_current_poster != NULL) { -+ JvmtiPendingEvent_lock->wait(); -+ } -+ } -+ if ((_pending_compiled_method_unload_method_ids == NULL) || -+ (_pending_compiled_method_unload_method_ids->length() == 0)) { -+ return; -+ } -+ if (_current_poster == NULL) { -+ _current_poster = self; -+ first_activation = true; -+ } else { -+ // re-entrant -+ guarantee(_current_poster == self, "checking"); -+ } -+ method = _pending_compiled_method_unload_method_ids->pop(); -+ code_begin = _pending_compiled_method_unload_code_begins->pop(); -+ } -+ -+ // This thread is the pending event poster so it first posts the CompiledMethodUnload -+ // event for the jmethodID that has been removed from the list. Once posted it -+ // re-grabs the monitor and checks the list again. If the list is empty then and this -+ // is the first activation of the function then we reset the _have_pending_events -+ // flag, cleanup _current_poster to indicate that no thread is now servicing the -+ // pending events list, and finally notify any thread that might be waiting. -+ for (;;) { -+ EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD, -+ ("JVMTI [%s] method compile unload event triggered", -+ JvmtiTrace::safe_get_thread_name(self))); -+ -+ // post the event for each environment that has this event enabled. -+ JvmtiEnvIterator it; -+ for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { -+ if (env->is_enabled(JVMTI_EVENT_COMPILED_METHOD_UNLOAD)) { -+ EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD, -+ ("JVMTI [%s] class compile method unload event sent jmethodID " PTR_FORMAT, -+ JvmtiTrace::safe_get_thread_name(self), method)); -+ -+ JvmtiEventMark jem(self); -+ JvmtiJavaThreadEventTransition jet(self); -+ jvmtiEventCompiledMethodUnload callback = env->callbacks()->CompiledMethodUnload; -+ if (callback != NULL) { -+ (*callback)(env->jvmti_external(), method, code_begin); -+ } -+ } -+ } -+ -+ // event posted, now re-grab monitor and get the next event -+ // If there's no next event then we are done. If this is the first -+ // activiation of this function by this thread notify any waiters -+ // so that they can post. -+ { -+ MutexLocker ml(JvmtiPendingEvent_lock); -+ if (_pending_compiled_method_unload_method_ids->length() == 0) { -+ if (first_activation) { -+ _have_pending_compiled_method_unload_events = false; -+ _current_poster = NULL; -+ JvmtiPendingEvent_lock->notify_all(); -+ } -+ return; -+ } -+ method = _pending_compiled_method_unload_method_ids->pop(); -+ code_begin = _pending_compiled_method_unload_code_begins->pop(); -+ } -+ } -+} -+ -+/////////////////////////////////////////////////////////////// -+// -+// JvmtiExport -+// -+ -+void JvmtiExport::post_raw_breakpoint(JavaThread *thread, methodOop method, address location) { -+ HandleMark hm(thread); -+ methodHandle mh(thread, method); -+ -+ JvmtiThreadState *state = thread->jvmti_thread_state(); -+ if (state == NULL) { -+ return; -+ } -+ EVT_TRIG_TRACE(JVMTI_EVENT_BREAKPOINT, ("JVMTI [%s] Trg Breakpoint triggered", -+ JvmtiTrace::safe_get_thread_name(thread))); -+ JvmtiEnvThreadStateIterator it(state); -+ for (JvmtiEnvThreadState* ets = it.first(); ets != NULL; ets = it.next(ets)) { -+ ets->compare_and_set_current_location(mh(), location, JVMTI_EVENT_BREAKPOINT); -+ if (!ets->breakpoint_posted() && ets->is_enabled(JVMTI_EVENT_BREAKPOINT)) { -+ ThreadState old_os_state = thread->osthread()->get_state(); -+ thread->osthread()->set_state(BREAKPOINTED); -+ EVT_TRACE(JVMTI_EVENT_BREAKPOINT, ("JVMTI [%s] Evt Breakpoint sent %s.%s @ %d", -+ JvmtiTrace::safe_get_thread_name(thread), -+ (mh() == NULL) ? "NULL" : mh()->klass_name()->as_C_string(), -+ (mh() == NULL) ? "NULL" : mh()->name()->as_C_string(), -+ location - mh()->code_base() )); -+ -+ JvmtiEnv *env = ets->get_env(); -+ JvmtiLocationEventMark jem(thread, mh, location); -+ JvmtiJavaThreadEventTransition jet(thread); -+ jvmtiEventBreakpoint callback = env->callbacks()->Breakpoint; -+ if (callback != NULL) { -+ (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread(), -+ jem.jni_methodID(), jem.location()); -+ } -+ -+ ets->set_breakpoint_posted(); -+ thread->osthread()->set_state(old_os_state); -+ } -+ } -+} -+ -+////////////////////////////////////////////////////////////////////////////// -+ -+bool JvmtiExport::_can_get_source_debug_extension = false; -+bool JvmtiExport::_can_maintain_original_method_order = false; -+bool JvmtiExport::_can_post_interpreter_events = false; -+bool JvmtiExport::_can_post_exceptions = false; -+bool JvmtiExport::_can_post_breakpoint = false; -+bool JvmtiExport::_can_post_field_access = false; -+bool JvmtiExport::_can_post_field_modification = false; -+bool JvmtiExport::_can_post_method_entry = false; -+bool JvmtiExport::_can_post_method_exit = false; -+bool JvmtiExport::_can_pop_frame = false; -+bool JvmtiExport::_can_force_early_return = false; -+ -+bool JvmtiExport::_should_post_single_step = false; -+bool JvmtiExport::_should_post_field_access = false; -+bool JvmtiExport::_should_post_field_modification = false; -+bool JvmtiExport::_should_post_class_load = false; -+bool JvmtiExport::_should_post_class_prepare = false; -+bool JvmtiExport::_should_post_class_unload = false; -+bool JvmtiExport::_should_post_thread_life = false; -+bool JvmtiExport::_should_clean_up_heap_objects = false; -+bool JvmtiExport::_should_post_native_method_bind = false; -+bool JvmtiExport::_should_post_dynamic_code_generated = false; -+bool JvmtiExport::_should_post_data_dump = false; -+bool JvmtiExport::_should_post_compiled_method_load = false; -+bool JvmtiExport::_should_post_compiled_method_unload = false; -+bool JvmtiExport::_should_post_monitor_contended_enter = false; -+bool JvmtiExport::_should_post_monitor_contended_entered = false; -+bool JvmtiExport::_should_post_monitor_wait = false; -+bool JvmtiExport::_should_post_monitor_waited = false; -+bool JvmtiExport::_should_post_garbage_collection_start = false; -+bool JvmtiExport::_should_post_garbage_collection_finish = false; -+bool JvmtiExport::_should_post_object_free = false; -+bool JvmtiExport::_should_post_resource_exhausted = false; -+bool JvmtiExport::_should_post_vm_object_alloc = false; -+ -+//////////////////////////////////////////////////////////////////////////////////////////////// - --void JvmtiExport::post_vm_initialized() { -- EVT_TRIG_TRACE(JVMTI_EVENT_VM_INIT, ("JVMTI Trg VM init event triggered" )); - -- // can now enable events -- JvmtiEventController::vm_init(); -+// -+// JVMTI single step management -+// -+void JvmtiExport::at_single_stepping_point(JavaThread *thread, methodOop method, address location) { -+ assert(JvmtiExport::should_post_single_step(), "must be single stepping"); - -- JvmtiEnvIterator it; -- for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { -- if (env->is_enabled(JVMTI_EVENT_VM_INIT)) { -- EVT_TRACE(JVMTI_EVENT_VM_INIT, ("JVMTI Evt VM init event sent" )); -+ HandleMark hm(thread); -+ methodHandle mh(thread, method); - -- JavaThread *thread = JavaThread::current(); -- JvmtiThreadEventMark jem(thread); -- JvmtiJavaThreadEventTransition jet(thread); -- jvmtiEventVMInit callback = env->callbacks()->VMInit; -- if (callback != NULL) { -- (*callback)(env->jvmti_external(), jem.jni_env(), jem.jni_thread()); -+ // update information about current location and post a step event -+ JvmtiThreadState *state = thread->jvmti_thread_state(); -+ if (state == NULL) { -+ return; -+ } -+ EVT_TRIG_TRACE(JVMTI_EVENT_SINGLE_STEP, ("JVMTI [%s] Trg Single Step triggered", -+ JvmtiTrace::safe_get_thread_name(thread))); -+ if (!state->hide_single_stepping()) { -+ if (state->is_pending_step_for_popframe()) { -+ state->process_pending_step_for_popframe(); - } -+ if (state->is_pending_step_for_earlyret()) { -+ state->process_pending_step_for_earlyret(); - } -+ JvmtiExport::post_single_step(thread, mh(), location); - } - } - - --extern "C" { -- typedef void (JNICALL *Agent_OnUnload_t)(JavaVM *); --} -- --void JvmtiExport::post_vm_death() { -- EVT_TRIG_TRACE(JVMTI_EVENT_VM_DEATH, ("JVMTI Trg VM death event triggered" )); -- -- JvmtiEnvIterator it; -- for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { -- if (env->is_enabled(JVMTI_EVENT_VM_DEATH)) { -- EVT_TRACE(JVMTI_EVENT_VM_DEATH, ("JVMTI Evt VM death event sent" )); -- -- JavaThread *thread = JavaThread::current(); -- JvmtiEventMark jem(thread); -- JvmtiJavaThreadEventTransition jet(thread); -- jvmtiEventVMDeath callback = env->callbacks()->VMDeath; -- if (callback != NULL) { -- (*callback)(env->jvmti_external(), jem.jni_env()); -- } -- } -+void JvmtiExport::expose_single_stepping(JavaThread *thread) { -+ JvmtiThreadState *state = thread->jvmti_thread_state(); -+ if (state != NULL) { -+ state->clear_hide_single_stepping(); - } -+} - -- JvmtiEnvBase::set_phase(JVMTI_PHASE_DEAD); -- JvmtiEventController::vm_death(); -- -- // Send any Agent_OnUnload notifications -- const char *on_unload_symbols[] = AGENT_ONUNLOAD_SYMBOLS; -- extern struct JavaVM_ main_vm; -- for (AgentLibrary* agent = Arguments::agents(); agent != NULL; agent = agent->next()) { -- -- // Find the Agent_OnUnload function. -- for (uint symbol_index = 0; symbol_index < ARRAY_SIZE(on_unload_symbols); symbol_index++) { -- Agent_OnUnload_t unload_entry = CAST_TO_FN_PTR(Agent_OnUnload_t, -- hpi::dll_lookup(agent->os_lib(), on_unload_symbols[symbol_index])); - -- // Invoke the Agent_OnUnload function -- if (unload_entry != NULL) { -- JavaThread* thread = JavaThread::current(); -- ThreadToNativeFromVM ttn(thread); -- HandleMark hm(thread); -- (*unload_entry)(&main_vm); -- break; -- } -- } -+bool JvmtiExport::hide_single_stepping(JavaThread *thread) { -+ JvmtiThreadState *state = thread->jvmti_thread_state(); -+ if (state != NULL && state->is_enabled(JVMTI_EVENT_SINGLE_STEP)) { -+ state->set_hide_single_stepping(); -+ return true; -+ } else { -+ return false; - } - } - -- - void JvmtiExport::post_class_load(JavaThread *thread, klassOop klass) { - HandleMark hm(thread); - KlassHandle kh(thread, klass); -@@ -1533,170 +1693,6 @@ - } - } - --class JvmtiClassFileLoadHookPoster : public StackObj { -- private: -- symbolHandle _h_name; -- Handle _class_loader; -- Handle _h_protection_domain; -- unsigned char ** _data_ptr; -- unsigned char ** _end_ptr; -- JavaThread * _thread; -- jint _curr_len; -- unsigned char * _curr_data; -- JvmtiEnv * _curr_env; -- jint * _cached_length_ptr; -- unsigned char ** _cached_data_ptr; -- JvmtiThreadState * _state; -- KlassHandle * _h_class_being_redefined; -- JvmtiClassLoadKind _load_kind; -- -- public: -- inline JvmtiClassFileLoadHookPoster(symbolHandle h_name, Handle class_loader, -- Handle h_protection_domain, -- unsigned char **data_ptr, unsigned char **end_ptr, -- unsigned char **cached_data_ptr, -- jint *cached_length_ptr) { -- _h_name = h_name; -- _class_loader = class_loader; -- _h_protection_domain = h_protection_domain; -- _data_ptr = data_ptr; -- _end_ptr = end_ptr; -- _thread = JavaThread::current(); -- _curr_len = *end_ptr - *data_ptr; -- _curr_data = *data_ptr; -- _curr_env = NULL; -- _cached_length_ptr = cached_length_ptr; -- _cached_data_ptr = cached_data_ptr; -- *_cached_length_ptr = 0; -- *_cached_data_ptr = NULL; -- -- _state = _thread->jvmti_thread_state(); -- if (_state != NULL) { -- _h_class_being_redefined = _state->get_class_being_redefined(); -- _load_kind = _state->get_class_load_kind(); -- // Clear class_being_redefined flag here. The action -- // from agent handler could generate a new class file load -- // hook event and if it is not cleared the new event generated -- // from regular class file load could have this stale redefined -- // class handle info. -- _state->clear_class_being_redefined(); -- } else { -- // redefine and retransform will always set the thread state -- _h_class_being_redefined = (KlassHandle *) NULL; -- _load_kind = jvmti_class_load_kind_load; -- } -- } -- -- void post() { --// EVT_TRIG_TRACE(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, --// ("JVMTI [%s] class file load hook event triggered", --// JvmtiTrace::safe_get_thread_name(_thread))); -- post_all_envs(); -- copy_modified_data(); -- } -- -- private: -- void post_all_envs() { -- if (_load_kind != jvmti_class_load_kind_retransform) { -- // for class load and redefine, -- // call the non-retransformable agents -- JvmtiEnvIterator it; -- for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { -- if (!env->is_retransformable() && env->is_enabled(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK)) { -- // non-retransformable agents cannot retransform back, -- // so no need to cache the original class file bytes -- post_to_env(env, false); -- } -- } -- } -- JvmtiEnvIterator it; -- for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { -- // retransformable agents get all events -- if (env->is_retransformable() && env->is_enabled(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK)) { -- // retransformable agents need to cache the original class file -- // bytes if changes are made via the ClassFileLoadHook -- post_to_env(env, true); -- } -- } -- } -- -- void post_to_env(JvmtiEnv* env, bool caching_needed) { -- unsigned char *new_data = NULL; -- jint new_len = 0; --// EVT_TRACE(JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, --// ("JVMTI [%s] class file load hook event sent %s data_ptr = %d, data_len = %d", --// JvmtiTrace::safe_get_thread_name(_thread), --// _h_name.is_null() ? "NULL" : _h_name->as_utf8(), --// _curr_data, _curr_len )); -- JvmtiClassFileLoadEventMark jem(_thread, _h_name, _class_loader, -- _h_protection_domain, -- _h_class_being_redefined); -- JvmtiJavaThreadEventTransition jet(_thread); -- JNIEnv* jni_env = (JvmtiEnv::get_phase() == JVMTI_PHASE_PRIMORDIAL)? -- NULL : jem.jni_env(); -- jvmtiEventClassFileLoadHook callback = env->callbacks()->ClassFileLoadHook; -- if (callback != NULL) { -- (*callback)(env->jvmti_external(), jni_env, -- jem.class_being_redefined(), -- jem.jloader(), jem.class_name(), -- jem.protection_domain(), -- _curr_len, _curr_data, -- &new_len, &new_data); -- } -- if (new_data != NULL) { -- // this agent has modified class data. -- if (caching_needed && *_cached_data_ptr == NULL) { -- // data has been changed by the new retransformable agent -- // and it hasn't already been cached, cache it -- *_cached_data_ptr = (unsigned char *)os::malloc(_curr_len); -- memcpy(*_cached_data_ptr, _curr_data, _curr_len); -- *_cached_length_ptr = _curr_len; -- } -- -- if (_curr_data != *_data_ptr) { -- // curr_data is previous agent modified class data. -- // And this has been changed by the new agent so -- // we can delete it now. -- _curr_env->Deallocate(_curr_data); -- } -- -- // Class file data has changed by the current agent. -- _curr_data = new_data; -- _curr_len = new_len; -- // Save the current agent env we need this to deallocate the -- // memory allocated by this agent. -- _curr_env = env; -- } -- } -- -- void copy_modified_data() { -- // if one of the agent has modified class file data. -- // Copy modified class data to new resources array. -- if (_curr_data != *_data_ptr) { -- *_data_ptr = NEW_RESOURCE_ARRAY(u1, _curr_len); -- memcpy(*_data_ptr, _curr_data, _curr_len); -- *_end_ptr = *_data_ptr + _curr_len; -- _curr_env->Deallocate(_curr_data); -- } -- } --}; -- --// this entry is for class file load hook on class load, redefine and retransform --void JvmtiExport::post_class_file_load_hook(symbolHandle h_name, -- Handle class_loader, -- Handle h_protection_domain, -- unsigned char **data_ptr, -- unsigned char **end_ptr, -- unsigned char **cached_data_ptr, -- jint *cached_length_ptr) { -- JvmtiClassFileLoadHookPoster poster(h_name, class_loader, -- h_protection_domain, -- data_ptr, end_ptr, -- cached_data_ptr, -- cached_length_ptr); -- poster.post(); --} -- - void JvmtiExport::post_native_method_bind(methodOop method, address* function_ptr) { - JavaThread* thread = JavaThread::current(); - assert(thread->thread_state() == _thread_in_vm, "must be in vm state"); -@@ -2133,19 +2129,6 @@ - } - } - -- --char** --JvmtiExport::get_all_native_method_prefixes(int* count_ptr) { -- // Have to grab JVMTI thread state lock to be sure environment doesn't -- // go away while we iterate them. No locks during VM bring-up. -- if (Threads::number_of_threads() == 0 || SafepointSynchronize::is_at_safepoint()) { -- return JvmtiEnvBase::get_all_native_method_prefixes(count_ptr); -- } else { -- MutexLocker mu(JvmtiThreadState_lock); -- return JvmtiEnvBase::get_all_native_method_prefixes(count_ptr); -- } --} -- - //////////////////////////////////////////////////////////////////////////////////////////////// - - void JvmtiExport::cleanup_thread(JavaThread* thread) { -@@ -2175,6 +2158,7 @@ - typedef jint (JNICALL *OnAttachEntry_t)(JavaVM*, char *, void *); - } - -+#ifndef SERVICES_KERNEL - jint JvmtiExport::load_agent_library(AttachOperation* op, outputStream* st) { - char ebuf[1024]; - char buffer[JVM_MAXPATHLEN]; -@@ -2252,6 +2236,7 @@ - } - return result; - } -+#endif // SERVICES_KERNEL - - // CMS has completed referencing processing so may need to update - // tag maps. -@@ -2506,5 +2491,4 @@ - // Notify heap/object tagging support - JvmtiTagMap::gc_epilogue(_full); - } -- -- -+#endif // JVMTI_KERNEL -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiExport.hpp openjdk/hotspot/src/share/vm/prims/jvmtiExport.hpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiExport.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiExport.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)jvmtiExport.hpp 1.95 07/05/05 17:06:37 JVM" --#endif - /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -36,6 +33,23 @@ - class JvmtiThreadState; - class AttachOperation; - -+#ifndef JVMTI_KERNEL -+#define JVMTI_SUPPORT_FLAG(key) \ -+ private: \ -+ static bool _##key; \ -+ public: \ -+ inline static void set_##key(bool on) { _##key = (on != 0); } \ -+ inline static bool key() { return _##key; } -+#else // JVMTI_KERNEL -+#define JVMTI_SUPPORT_FLAG(key) \ -+ private: \ -+ const static bool _##key = false; \ -+ public: \ -+ inline static void set_##key(bool on) { report_unsupported(on); } \ -+ inline static bool key() { return _##key; } -+#endif // JVMTI_KERNEL -+ -+ - // This class contains the JVMTI interface for the rest of hotspot. - // - class JvmtiExport : public AllStatic { -@@ -43,93 +57,65 @@ - static int _field_access_count; - static int _field_modification_count; - -- static bool _can_get_source_debug_extension; -+ static bool _can_access_local_variables; - static bool _can_examine_or_deopt_anywhere; -- static bool _can_maintain_original_method_order; -- static bool _can_post_interpreter_events; - static bool _can_hotswap_or_post_breakpoint; - static bool _can_modify_any_class; - static bool _can_walk_any_space; -- static bool _can_access_local_variables; -- static bool _can_post_exceptions; -- static bool _can_post_breakpoint; -- static bool _can_post_field_access; -- static bool _can_post_field_modification; -- static bool _can_post_method_entry; -- static bool _can_post_method_exit; -- static bool _can_pop_frame; -- static bool _can_force_early_return; -- -- static bool _should_post_single_step; -- static bool _should_post_field_access; -- static bool _should_post_field_modification; -- static bool _should_post_class_load; -- static bool _should_post_class_prepare; -- static bool _should_post_class_unload; -- static bool _should_post_class_file_load_hook; -- static bool _should_post_native_method_bind; -- static bool _should_post_compiled_method_load; -- static bool _should_post_compiled_method_unload; -- static bool _should_post_dynamic_code_generated; -- static bool _should_post_monitor_contended_enter; -- static bool _should_post_monitor_contended_entered; -- static bool _should_post_monitor_wait; -- static bool _should_post_monitor_waited; -- static bool _should_post_data_dump; -- static bool _should_post_garbage_collection_start; -- static bool _should_post_garbage_collection_finish; -- static bool _should_post_thread_life; -- static bool _should_post_object_free; -- static bool _should_post_resource_exhausted; -- static bool _should_clean_up_heap_objects; -- static bool _should_post_vm_object_alloc; - -+ JVMTI_SUPPORT_FLAG(can_get_source_debug_extension) -+ JVMTI_SUPPORT_FLAG(can_maintain_original_method_order) -+ JVMTI_SUPPORT_FLAG(can_post_interpreter_events) -+ JVMTI_SUPPORT_FLAG(can_post_exceptions) -+ JVMTI_SUPPORT_FLAG(can_post_breakpoint) -+ JVMTI_SUPPORT_FLAG(can_post_field_access) -+ JVMTI_SUPPORT_FLAG(can_post_field_modification) -+ JVMTI_SUPPORT_FLAG(can_post_method_entry) -+ JVMTI_SUPPORT_FLAG(can_post_method_exit) -+ JVMTI_SUPPORT_FLAG(can_pop_frame) -+ JVMTI_SUPPORT_FLAG(can_force_early_return) -+ -+ friend class JvmtiEventControllerPrivate; // should only modify these flags -+ JVMTI_SUPPORT_FLAG(should_post_single_step) -+ JVMTI_SUPPORT_FLAG(should_post_field_access) -+ JVMTI_SUPPORT_FLAG(should_post_field_modification) -+ JVMTI_SUPPORT_FLAG(should_post_class_load) -+ JVMTI_SUPPORT_FLAG(should_post_class_prepare) -+ JVMTI_SUPPORT_FLAG(should_post_class_unload) -+ JVMTI_SUPPORT_FLAG(should_post_native_method_bind) -+ JVMTI_SUPPORT_FLAG(should_post_compiled_method_load) -+ JVMTI_SUPPORT_FLAG(should_post_compiled_method_unload) -+ JVMTI_SUPPORT_FLAG(should_post_dynamic_code_generated) -+ JVMTI_SUPPORT_FLAG(should_post_monitor_contended_enter) -+ JVMTI_SUPPORT_FLAG(should_post_monitor_contended_entered) -+ JVMTI_SUPPORT_FLAG(should_post_monitor_wait) -+ JVMTI_SUPPORT_FLAG(should_post_monitor_waited) -+ JVMTI_SUPPORT_FLAG(should_post_data_dump) -+ JVMTI_SUPPORT_FLAG(should_post_garbage_collection_start) -+ JVMTI_SUPPORT_FLAG(should_post_garbage_collection_finish) -+ -+ // ------ the below maybe don't have to be (but are for now) -+ // fixed conditions here ------------ -+ // any events can be enabled -+ JVMTI_SUPPORT_FLAG(should_post_thread_life) -+ JVMTI_SUPPORT_FLAG(should_post_object_free) -+ JVMTI_SUPPORT_FLAG(should_post_resource_exhausted) -+ -+ // we are holding objects on the heap - need to talk to GC - e.g. -+ // breakpoint info -+ JVMTI_SUPPORT_FLAG(should_clean_up_heap_objects) -+ JVMTI_SUPPORT_FLAG(should_post_vm_object_alloc) -+ -+ // If flag cannot be implemented, give an error if on=true -+ static void report_unsupported(bool on); - - // these should only be called by the friend class - friend class JvmtiManageCapabilities; -- inline static void set_can_get_source_debug_extension(bool on) { _can_get_source_debug_extension = (on != 0); } - inline static void set_can_examine_or_deopt_anywhere(bool on) { _can_examine_or_deopt_anywhere = (on != 0); } -- inline static void set_can_maintain_original_method_order(bool on) { _can_maintain_original_method_order = (on != 0); } -- inline static void set_can_post_interpreter_events(bool on) { _can_post_interpreter_events = (on != 0); } -- inline static void set_can_hotswap_or_post_breakpoint(bool on) { _can_hotswap_or_post_breakpoint = (on != 0); } - inline static void set_can_modify_any_class(bool on) { _can_modify_any_class = (on != 0); } -- inline static void set_can_walk_any_space(bool on) { _can_walk_any_space = (on != 0); } - inline static void set_can_access_local_variables(bool on) { _can_access_local_variables = (on != 0); } -- inline static void set_can_post_exceptions(bool on) { _can_post_exceptions = (on != 0); } -- inline static void set_can_post_breakpoint(bool on) { _can_post_breakpoint = (on != 0); } -- inline static void set_can_post_field_access(bool on) { _can_post_field_access = (on != 0); } -- inline static void set_can_post_field_modification(bool on) { _can_post_field_modification = (on != 0); } -- inline static void set_can_post_method_entry(bool on) { _can_post_method_entry = (on != 0); } -- inline static void set_can_post_method_exit(bool on) { _can_post_method_exit = (on != 0); } -- inline static void set_can_pop_frame(bool on) { _can_pop_frame = (on != 0); } -- inline static void set_can_force_early_return(bool on) { _can_force_early_return = (on != 0); } -- -- // these should only be called by the friend class -- friend class JvmtiEventControllerPrivate; -- inline static void set_should_post_single_step(bool on) { _should_post_single_step = on; } -- inline static void set_should_post_field_access(bool on) { _should_post_field_access = on; } -- inline static void set_should_post_field_modification(bool on) { _should_post_field_modification = on; } -- inline static void set_should_post_class_load(bool on) { _should_post_class_load = on; } -- inline static void set_should_post_class_prepare(bool on) { _should_post_class_prepare = on; } -- inline static void set_should_post_class_unload(bool on) { _should_post_class_unload = on; } -- inline static void set_should_post_class_file_load_hook(bool on) { _should_post_class_file_load_hook = on; } -- inline static void set_should_post_native_method_bind(bool on) { _should_post_native_method_bind = on; } -- inline static void set_should_post_compiled_method_load(bool on) { _should_post_compiled_method_load = on; } -- inline static void set_should_post_compiled_method_unload(bool on) { _should_post_compiled_method_unload = on; } -- inline static void set_should_post_dynamic_code_generated(bool on) { _should_post_dynamic_code_generated = on; } -- inline static void set_should_post_monitor_contended_enter(bool on) { _should_post_monitor_contended_enter = on; } -- inline static void set_should_post_monitor_contended_entered(bool on){ _should_post_monitor_contended_entered = on; } -- inline static void set_should_post_monitor_wait(bool on) { _should_post_monitor_wait = on; } -- inline static void set_should_post_monitor_waited(bool on) { _should_post_monitor_waited = on; } -- inline static void set_should_post_garbage_collection_start(bool on) { _should_post_garbage_collection_start = on; } -- inline static void set_should_post_garbage_collection_finish(bool on){ _should_post_garbage_collection_finish = on; } -- inline static void set_should_post_data_dump(bool on) { _should_post_data_dump = on; } -- inline static void set_should_post_object_free(bool on) { _should_post_object_free = on; } -- inline static void set_should_post_resource_exhausted(bool on) { _should_post_resource_exhausted = on; } -- inline static void set_should_post_vm_object_alloc(bool on) { _should_post_vm_object_alloc = on; } -- -- inline static void set_should_post_thread_life(bool on) { _should_post_thread_life = on; } -- inline static void set_should_clean_up_heap_objects(bool on) { _should_clean_up_heap_objects = on; } -+ inline static void set_can_hotswap_or_post_breakpoint(bool on) { _can_hotswap_or_post_breakpoint = (on != 0); } -+ inline static void set_can_walk_any_space(bool on) { _can_walk_any_space = (on != 0); } - - enum { - JVMTI_VERSION_MASK = 0x70000000, -@@ -162,7 +148,7 @@ - // posts a DynamicCodeGenerated event (internal/private implementation). - // The public post_dynamic_code_generated* functions make use of the - // internal implementation. -- static void post_dynamic_code_generated_internal(const char *name, const void *code_begin, const void *code_end); -+ static void post_dynamic_code_generated_internal(const char *name, const void *code_begin, const void *code_end) KERNEL_RETURN; - - - // GenerateEvents support to allow posting of CompiledMethodLoad and -@@ -171,9 +157,9 @@ - - static void post_compiled_method_load(JvmtiEnv* env, const jmethodID method, const jint length, - const void *code_begin, const jint map_length, -- const jvmtiAddrLocationMap* map); -+ const jvmtiAddrLocationMap* map) KERNEL_RETURN; - static void post_dynamic_code_generated(JvmtiEnv* env, const char *name, const void *code_begin, -- const void *code_end); -+ const void *code_end) KERNEL_RETURN; - - // The RedefineClasses() API breaks some invariants in the "regular" - // system. For example, there are sanity checks when GC'ing nmethods -@@ -233,70 +219,11 @@ - static void enter_live_phase(); - - // ------ can_* conditions (below) are set at OnLoad and never changed ------------ -- -- inline static bool can_get_source_debug_extension() { return _can_get_source_debug_extension; } -- -- // BP, expression stack, hotswap, interp_only, local_var, monitor info - inline static bool can_examine_or_deopt_anywhere() { return _can_examine_or_deopt_anywhere; } -- -- // JVMDI spec requires this, does this matter for JVMTI? -- inline static bool can_maintain_original_method_order() { return _can_maintain_original_method_order; } -- -- // any of single-step, method-entry/exit, frame-pop, and field-access/modification -- inline static bool can_post_interpreter_events() { return _can_post_interpreter_events; } -- -- inline static bool can_hotswap_or_post_breakpoint() { return _can_hotswap_or_post_breakpoint; } -- - inline static bool can_modify_any_class() { return _can_modify_any_class; } -- -- inline static bool can_walk_any_space() { return _can_walk_any_space; } -- -- // can retrieve frames, set/get local variables or hotswap - inline static bool can_access_local_variables() { return _can_access_local_variables; } -- -- // throw or catch -- inline static bool can_post_exceptions() { return _can_post_exceptions; } -- -- inline static bool can_post_breakpoint() { return _can_post_breakpoint; } -- inline static bool can_post_field_access() { return _can_post_field_access; } -- inline static bool can_post_field_modification() { return _can_post_field_modification; } -- inline static bool can_post_method_entry() { return _can_post_method_entry; } -- inline static bool can_post_method_exit() { return _can_post_method_exit; } -- inline static bool can_pop_frame() { return _can_pop_frame; } -- inline static bool can_force_early_return() { return _can_force_early_return; } -- -- -- // ------ the below maybe don't have to be (but are for now) fixed conditions here ------------ -- // any events can be enabled -- inline static bool should_post_thread_life() { return _should_post_thread_life; } -- -- -- // ------ DYNAMIC conditions here ------------ -- -- inline static bool should_post_single_step() { return _should_post_single_step; } -- inline static bool should_post_field_access() { return _should_post_field_access; } -- inline static bool should_post_field_modification() { return _should_post_field_modification; } -- inline static bool should_post_class_load() { return _should_post_class_load; } -- inline static bool should_post_class_prepare() { return _should_post_class_prepare; } -- inline static bool should_post_class_unload() { return _should_post_class_unload; } -- inline static bool should_post_class_file_load_hook() { return _should_post_class_file_load_hook; } -- inline static bool should_post_native_method_bind() { return _should_post_native_method_bind; } -- inline static bool should_post_compiled_method_load() { return _should_post_compiled_method_load; } -- inline static bool should_post_compiled_method_unload() { return _should_post_compiled_method_unload; } -- inline static bool should_post_dynamic_code_generated() { return _should_post_dynamic_code_generated; } -- inline static bool should_post_monitor_contended_enter() { return _should_post_monitor_contended_enter; } -- inline static bool should_post_monitor_contended_entered() { return _should_post_monitor_contended_entered; } -- inline static bool should_post_monitor_wait() { return _should_post_monitor_wait; } -- inline static bool should_post_monitor_waited() { return _should_post_monitor_waited; } -- inline static bool should_post_data_dump() { return _should_post_data_dump; } -- inline static bool should_post_garbage_collection_start() { return _should_post_garbage_collection_start; } -- inline static bool should_post_garbage_collection_finish() { return _should_post_garbage_collection_finish; } -- inline static bool should_post_object_free() { return _should_post_object_free; } -- inline static bool should_post_resource_exhausted() { return _should_post_resource_exhausted; } -- inline static bool should_post_vm_object_alloc() { return _should_post_vm_object_alloc; } -- -- // we are holding objects on the heap - need to talk to GC - e.g. breakpoint info -- inline static bool should_clean_up_heap_objects() { return _should_clean_up_heap_objects; } -+ inline static bool can_hotswap_or_post_breakpoint() { return _can_hotswap_or_post_breakpoint; } -+ inline static bool can_walk_any_space() { return _can_walk_any_space; } - - // field access management - static address get_field_access_count_addr(); -@@ -310,84 +237,89 @@ - static bool is_jvmdi_version(jint version) { return (version & JVMTI_VERSION_MASK) == JVMDI_VERSION_VALUE; } - static jint get_jvmti_interface(JavaVM *jvm, void **penv, jint version); - -- - // single stepping management methods -- static void at_single_stepping_point(JavaThread *thread, methodOop method, address location); -- static void expose_single_stepping(JavaThread *thread); -- static bool hide_single_stepping(JavaThread *thread); -+ static void at_single_stepping_point(JavaThread *thread, methodOop method, address location) KERNEL_RETURN; -+ static void expose_single_stepping(JavaThread *thread) KERNEL_RETURN; -+ static bool hide_single_stepping(JavaThread *thread) KERNEL_RETURN_(return false;); - - // Methods that notify the debugger that something interesting has happened in the VM. - static void post_vm_start (); - static void post_vm_initialized (); - static void post_vm_death (); - -- static void post_single_step (JavaThread *thread, methodOop method, address location); -- static void post_raw_breakpoint (JavaThread *thread, methodOop method, address location); -+ static void post_single_step (JavaThread *thread, methodOop method, address location) KERNEL_RETURN; -+ static void post_raw_breakpoint (JavaThread *thread, methodOop method, address location) KERNEL_RETURN; - -- static void post_exception_throw (JavaThread *thread, methodOop method, address location, oop exception); -- static void notice_unwind_due_to_exception (JavaThread *thread, methodOop method, address location, oop exception, bool in_handler_frame); -+ static void post_exception_throw (JavaThread *thread, methodOop method, address location, oop exception) KERNEL_RETURN; -+ static void notice_unwind_due_to_exception (JavaThread *thread, methodOop method, address location, oop exception, bool in_handler_frame) KERNEL_RETURN; - - static oop jni_GetField_probe (JavaThread *thread, jobject jobj, -- oop obj, klassOop klass, jfieldID fieldID, bool is_static); -+ oop obj, klassOop klass, jfieldID fieldID, bool is_static) -+ KERNEL_RETURN_(return NULL;); - static oop jni_GetField_probe_nh (JavaThread *thread, jobject jobj, -- oop obj, klassOop klass, jfieldID fieldID, bool is_static); -+ oop obj, klassOop klass, jfieldID fieldID, bool is_static) -+ KERNEL_RETURN_(return NULL;); - static void post_field_access_by_jni (JavaThread *thread, oop obj, -- klassOop klass, jfieldID fieldID, bool is_static); -+ klassOop klass, jfieldID fieldID, bool is_static) KERNEL_RETURN; - static void post_field_access (JavaThread *thread, methodOop method, -- address location, KlassHandle field_klass, Handle object, jfieldID field); -+ address location, KlassHandle field_klass, Handle object, jfieldID field) KERNEL_RETURN; - static oop jni_SetField_probe (JavaThread *thread, jobject jobj, - oop obj, klassOop klass, jfieldID fieldID, bool is_static, char sig_type, -- jvalue *value); -+ jvalue *value) KERNEL_RETURN_(return NULL;); - static oop jni_SetField_probe_nh (JavaThread *thread, jobject jobj, - oop obj, klassOop klass, jfieldID fieldID, bool is_static, char sig_type, -- jvalue *value); -+ jvalue *value) KERNEL_RETURN_(return NULL;); - static void post_field_modification_by_jni(JavaThread *thread, oop obj, - klassOop klass, jfieldID fieldID, bool is_static, char sig_type, - jvalue *value); - static void post_raw_field_modification(JavaThread *thread, methodOop method, - address location, KlassHandle field_klass, Handle object, jfieldID field, -- char sig_type, jvalue *value); -+ char sig_type, jvalue *value) KERNEL_RETURN; - -- static void post_method_entry (JavaThread *thread, methodOop method, frame current_frame); -- static void post_method_exit (JavaThread *thread, methodOop method, frame current_frame); -+ static void post_method_entry (JavaThread *thread, methodOop method, frame current_frame) KERNEL_RETURN; -+ static void post_method_exit (JavaThread *thread, methodOop method, frame current_frame) KERNEL_RETURN; - -- static void post_class_load (JavaThread *thread, klassOop klass); -- static void post_class_unload (klassOop klass); -- static void post_class_prepare (JavaThread *thread, klassOop klass); -+ static void post_class_load (JavaThread *thread, klassOop klass) KERNEL_RETURN; -+ static void post_class_unload (klassOop klass) KERNEL_RETURN; -+ static void post_class_prepare (JavaThread *thread, klassOop klass) KERNEL_RETURN; - -- static void post_thread_start (JavaThread *thread); -- static void post_thread_end (JavaThread *thread); -+ static void post_thread_start (JavaThread *thread) KERNEL_RETURN; -+ static void post_thread_end (JavaThread *thread) KERNEL_RETURN; - -+ // Support for java.lang.instrument agent loading. -+ static bool _should_post_class_file_load_hook; -+ inline static void set_should_post_class_file_load_hook(bool on) { _should_post_class_file_load_hook = on; } -+ inline static bool should_post_class_file_load_hook() { return _should_post_class_file_load_hook; } - static void post_class_file_load_hook(symbolHandle h_name, Handle class_loader, - Handle h_protection_domain, - unsigned char **data_ptr, unsigned char **end_ptr, - unsigned char **cached_data_ptr, - jint *cached_length_ptr); -- static void post_native_method_bind(methodOop method, address* function_ptr); -- static void post_compiled_method_load(nmethod *nm); -- static void post_dynamic_code_generated(const char *name, const void *code_begin, const void *code_end); -+ static void post_native_method_bind(methodOop method, address* function_ptr) KERNEL_RETURN; -+ static void post_compiled_method_load(nmethod *nm) KERNEL_RETURN; -+ static void post_dynamic_code_generated(const char *name, const void *code_begin, const void *code_end) KERNEL_RETURN; - - // used at a safepoint to post a CompiledMethodUnload event -- static void post_compiled_method_unload_at_safepoint(jmethodID mid, const void *code_begin); -+ static void post_compiled_method_unload_at_safepoint(jmethodID mid, const void *code_begin) KERNEL_RETURN; - - // similiar to post_dynamic_code_generated except that it can be used to - // post a DynamicCodeGenerated event while holding locks in the VM. Any event - // posted using this function is recorded by the enclosing event collector - // -- JvmtiDynamicCodeEventCollector. -- static void post_dynamic_code_generated_while_holding_locks(const char* name, address code_begin, address code_end); -+ static void post_dynamic_code_generated_while_holding_locks(const char* name, address code_begin, address code_end) KERNEL_RETURN; - -- static void post_garbage_collection_finish(); -- static void post_garbage_collection_start(); -- static void post_data_dump(); -- static void post_monitor_contended_enter(JavaThread *thread, ObjectMonitor *obj_mntr); -- static void post_monitor_contended_entered(JavaThread *thread, ObjectMonitor *obj_mntr); -- static void post_monitor_wait(JavaThread *thread, oop obj, jlong timeout); -- static void post_monitor_waited(JavaThread *thread, ObjectMonitor *obj_mntr, jboolean timed_out); -- static void post_object_free(JvmtiEnv* env, jlong tag); -- static void post_resource_exhausted(jint resource_exhausted_flags, const char* detail); -- static void record_vm_internal_object_allocation(oop object); -+ static void post_garbage_collection_finish() KERNEL_RETURN; -+ static void post_garbage_collection_start() KERNEL_RETURN; -+ static void post_data_dump() KERNEL_RETURN; -+ static void post_monitor_contended_enter(JavaThread *thread, ObjectMonitor *obj_mntr) KERNEL_RETURN; -+ static void post_monitor_contended_entered(JavaThread *thread, ObjectMonitor *obj_mntr) KERNEL_RETURN; -+ static void post_monitor_wait(JavaThread *thread, oop obj, jlong timeout) KERNEL_RETURN; -+ static void post_monitor_waited(JavaThread *thread, ObjectMonitor *obj_mntr, jboolean timed_out) KERNEL_RETURN; -+ static void post_object_free(JvmtiEnv* env, jlong tag) KERNEL_RETURN; -+ static void post_resource_exhausted(jint resource_exhausted_flags, const char* detail) KERNEL_RETURN; -+ static void record_vm_internal_object_allocation(oop object) KERNEL_RETURN; - // Post objects collected by vm_object_alloc_event_collector. -- static void post_vm_object_alloc(JavaThread *thread, oop object); -+ static void post_vm_object_alloc(JavaThread *thread, oop object) KERNEL_RETURN; - // Collects vm internal objects for later event posting. - inline static void vm_object_alloc_event_collector(oop object) { - if (should_post_vm_object_alloc()) { -@@ -395,20 +327,22 @@ - } - } - -- static void cleanup_thread (JavaThread* thread); -+ static void cleanup_thread (JavaThread* thread) KERNEL_RETURN; - -- static void oops_do(OopClosure* f); -+ static void oops_do(OopClosure* f) KERNEL_RETURN; - -- static void transition_pending_onload_raw_monitors(); -+ static void transition_pending_onload_raw_monitors() KERNEL_RETURN; - -+#ifndef SERVICES_KERNEL - // attach support - static jint load_agent_library(AttachOperation* op, outputStream* out); -+#endif // SERVICES_KERNEL - - // SetNativeMethodPrefix support - static char** get_all_native_method_prefixes(int* count_ptr); - - // call after CMS has completed referencing processing -- static void cms_ref_processing_epilogue(); -+ static void cms_ref_processing_epilogue() KERNEL_RETURN; - }; - - // Support class used by JvmtiDynamicCodeEventCollector and others. It -@@ -471,8 +405,8 @@ - void register_stub(const char* name, address start, address end); - - public: -- JvmtiDynamicCodeEventCollector(); -- ~JvmtiDynamicCodeEventCollector(); -+ JvmtiDynamicCodeEventCollector() KERNEL_RETURN; -+ ~JvmtiDynamicCodeEventCollector() KERNEL_RETURN; - bool is_dynamic_code_event() { return true; } - - }; -@@ -504,8 +438,8 @@ - static void oops_do_for_all_threads(OopClosure* f); - - public: -- JvmtiVMObjectAllocEventCollector(); -- ~JvmtiVMObjectAllocEventCollector(); -+ JvmtiVMObjectAllocEventCollector() KERNEL_RETURN; -+ ~JvmtiVMObjectAllocEventCollector() KERNEL_RETURN; - bool is_vm_object_alloc_event() { return true; } - - bool is_enabled() { return _enable; } -@@ -535,8 +469,8 @@ - bool was_enabled() { return _collector != NULL; } - - public: -- NoJvmtiVMObjectAllocMark(); -- ~NoJvmtiVMObjectAllocMark(); -+ NoJvmtiVMObjectAllocMark() KERNEL_RETURN; -+ ~NoJvmtiVMObjectAllocMark() KERNEL_RETURN; - }; - - -@@ -546,8 +480,8 @@ - bool _full; // marks a "full" GC - unsigned int _invocation_count; // GC invocation count - protected: -- JvmtiGCMarker(bool full); // protected -- ~JvmtiGCMarker(); // protected -+ JvmtiGCMarker(bool full) KERNEL_RETURN; // protected -+ ~JvmtiGCMarker() KERNEL_RETURN; // protected - }; - - -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiExtensions.cpp openjdk/hotspot/src/share/vm/prims/jvmtiExtensions.cpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiExtensions.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiExtensions.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)jvmtiExtensions.cpp 1.11 07/05/05 17:06:38 JVM" --#endif - /* - * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiExtensions.hpp openjdk/hotspot/src/share/vm/prims/jvmtiExtensions.hpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiExtensions.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiExtensions.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)jvmtiExtensions.hpp 1.8 07/05/05 17:06:38 JVM" --#endif - /* - * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiGetLoadedClasses.cpp openjdk/hotspot/src/share/vm/prims/jvmtiGetLoadedClasses.cpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiGetLoadedClasses.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiGetLoadedClasses.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)jvmtiGetLoadedClasses.cpp 1.13 07/05/05 17:06:38 JVM" --#endif - /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiGetLoadedClasses.hpp openjdk/hotspot/src/share/vm/prims/jvmtiGetLoadedClasses.hpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiGetLoadedClasses.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiGetLoadedClasses.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)jvmtiGetLoadedClasses.hpp 1.8 07/05/05 17:06:38 JVM" --#endif - /* - * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiImpl.cpp openjdk/hotspot/src/share/vm/prims/jvmtiImpl.cpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiImpl.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiImpl.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)jvmtiImpl.cpp 1.63 07/05/17 16:05:04 JVM" --#endif - /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -80,291 +77,6 @@ - _start_fn(_env->jvmti_external(), jni_environment(), (void*)_start_arg); - } - --// --// class JvmtiUtil --// -- --ResourceArea* JvmtiUtil::_single_threaded_resource_area = NULL; -- --ResourceArea* JvmtiUtil::single_threaded_resource_area() { -- if (_single_threaded_resource_area == NULL) { -- // lazily create the single threaded resource area -- // pick a size which is not a standard since the pools don't exist yet -- _single_threaded_resource_area = new ResourceArea(Chunk::non_pool_size); -- } -- return _single_threaded_resource_area; --} -- --// --// class JvmtiTrace --// --// Support for JVMTI tracing code --// --// ------------ --// Usage: --// -XX:TraceJVMTI=DESC,DESC,DESC --// --// DESC is DOMAIN ACTION KIND --// --// DOMAIN is function name --// event name --// "all" (all functions and events) --// "func" (all functions except boring) --// "allfunc" (all functions) --// "event" (all events) --// "ec" (event controller) --// --// ACTION is "+" (add) --// "-" (remove) --// --// KIND is --// for func --// "i" (input params) --// "e" (error returns) --// "o" (output) --// for event --// "t" (event triggered aka posted) --// "s" (event sent) --// --// Example: --// -XX:TraceJVMTI=ec+,GetCallerFrame+ie,Breakpoint+s -- --#ifdef JVMTI_TRACE -- --bool JvmtiTrace::_initialized = false; --bool JvmtiTrace::_on = false; --bool JvmtiTrace::_trace_event_controller = false; -- --void JvmtiTrace::initialize() { -- if (_initialized) { -- return; -- } -- SafeResourceMark rm; -- -- const char *very_end; -- const char *curr; -- if (strlen(TraceJVMTI)) { -- curr = TraceJVMTI; -- } else { -- curr = ""; // hack in fixed tracing here -- } -- very_end = curr + strlen(curr); -- while (curr < very_end) { -- const char *curr_end = strchr(curr, ','); -- if (curr_end == NULL) { -- curr_end = very_end; -- } -- const char *op_pos = strchr(curr, '+'); -- const char *minus_pos = strchr(curr, '-'); -- if (minus_pos != NULL && (minus_pos < op_pos || op_pos == NULL)) { -- op_pos = minus_pos; -- } -- char op; -- const char *flags = op_pos + 1; -- const char *flags_end = curr_end; -- if (op_pos == NULL || op_pos > curr_end) { -- flags = "ies"; -- flags_end = flags + strlen(flags); -- op_pos = curr_end; -- op = '+'; -- } else { -- op = *op_pos; -- } -- jbyte bits = 0; -- for (; flags < flags_end; ++flags) { -- switch (*flags) { -- case 'i': -- bits |= SHOW_IN; -- break; -- case 'I': -- bits |= SHOW_IN_DETAIL; -- break; -- case 'e': -- bits |= SHOW_ERROR; -- break; -- case 'o': -- bits |= SHOW_OUT; -- break; -- case 'O': -- bits |= SHOW_OUT_DETAIL; -- break; -- case 't': -- bits |= SHOW_EVENT_TRIGGER; -- break; -- case 's': -- bits |= SHOW_EVENT_SENT; -- break; -- default: -- tty->print_cr("Invalid trace flag '%c'", *flags); -- break; -- } -- } -- const int FUNC = 1; -- const int EXCLUDE = 2; -- const int ALL_FUNC = 4; -- const int EVENT = 8; -- const int ALL_EVENT = 16; -- int domain = 0; -- size_t len = op_pos - curr; -- if (op_pos == curr) { -- domain = ALL_FUNC | FUNC | ALL_EVENT | EVENT | EXCLUDE; -- } else if (len==3 && strncmp(curr, "all", 3)==0) { -- domain = ALL_FUNC | FUNC | ALL_EVENT | EVENT; -- } else if (len==7 && strncmp(curr, "allfunc", 7)==0) { -- domain = ALL_FUNC | FUNC; -- } else if (len==4 && strncmp(curr, "func", 4)==0) { -- domain = ALL_FUNC | FUNC | EXCLUDE; -- } else if (len==8 && strncmp(curr, "allevent", 8)==0) { -- domain = ALL_EVENT | EVENT; -- } else if (len==5 && strncmp(curr, "event", 5)==0) { -- domain = ALL_EVENT | EVENT; -- } else if (len==2 && strncmp(curr, "ec", 2)==0) { -- _trace_event_controller = true; -- tty->print_cr("JVMTI Tracing the event controller"); -- } else { -- domain = FUNC | EVENT; // go searching -- } -- -- int exclude_index = 0; -- if (domain & FUNC) { -- if (domain & ALL_FUNC) { -- if (domain & EXCLUDE) { -- tty->print("JVMTI Tracing all significant functions"); -- } else { -- tty->print_cr("JVMTI Tracing all functions"); -- } -- } -- for (int i = 0; i <= _max_function_index; ++i) { -- if (domain & EXCLUDE && i == _exclude_functions[exclude_index]) { -- ++exclude_index; -- } else { -- bool do_op = false; -- if (domain & ALL_FUNC) { -- do_op = true; -- } else { -- const char *fname = function_name(i); -- if (fname != NULL) { -- size_t fnlen = strlen(fname); -- if (len==fnlen && strncmp(curr, fname, fnlen)==0) { -- tty->print_cr("JVMTI Tracing the function: %s", fname); -- do_op = true; -- } -- } -- } -- if (do_op) { -- if (op == '+') { -- _trace_flags[i] |= bits; -- } else { -- _trace_flags[i] &= ~bits; -- } -- _on = true; -- } -- } -- } -- } -- if (domain & EVENT) { -- if (domain & ALL_EVENT) { -- tty->print_cr("JVMTI Tracing all events"); -- } -- for (int i = 0; i <= _max_event_index; ++i) { -- bool do_op = false; -- if (domain & ALL_EVENT) { -- do_op = true; -- } else { -- const char *ename = event_name(i); -- if (ename != NULL) { -- size_t evtlen = strlen(ename); -- if (len==evtlen && strncmp(curr, ename, evtlen)==0) { -- tty->print_cr("JVMTI Tracing the event: %s", ename); -- do_op = true; -- } -- } -- } -- if (do_op) { -- if (op == '+') { -- _event_trace_flags[i] |= bits; -- } else { -- _event_trace_flags[i] &= ~bits; -- } -- _on = true; -- } -- } -- } -- if (!_on && (domain & (FUNC|EVENT))) { -- tty->print_cr("JVMTI Trace domain not found"); -- } -- curr = curr_end + 1; -- } -- _initialized = true; --} -- -- --void JvmtiTrace::shutdown() { -- int i; -- _on = false; -- _trace_event_controller = false; -- for (i = 0; i <= _max_function_index; ++i) { -- _trace_flags[i] = 0; -- } -- for (i = 0; i <= _max_event_index; ++i) { -- _event_trace_flags[i] = 0; -- } --} -- -- --const char* JvmtiTrace::enum_name(const char** names, const jint* values, jint value) { -- for (int index = 0; names[index] != 0; ++index) { -- if (values[index] == value) { -- return names[index]; -- } -- } -- return "*INVALID-ENUM-VALUE*"; --} -- -- --// return a valid string no matter what state the thread is in --const char *JvmtiTrace::safe_get_thread_name(Thread *thread) { -- if (thread == NULL) { -- return "NULL"; -- } -- if (!thread->is_Java_thread()) { -- return thread->name(); -- } -- JavaThread *java_thread = (JavaThread *)thread; -- oop threadObj = java_thread->threadObj(); -- if (threadObj == NULL) { -- return "NULL"; -- } -- typeArrayOop name = java_lang_Thread::name(threadObj); -- if (name == NULL) { -- return ""; -- } -- return UNICODE::as_utf8((jchar*) name->base(T_CHAR), name->length()); --} -- -- --// return the name of the current thread --const char *JvmtiTrace::safe_get_current_thread_name() { -- if (JvmtiEnv::is_vm_live()) { -- return JvmtiTrace::safe_get_thread_name(Thread::current()); -- } else { -- return "VM not live"; -- } --} -- --// return a valid string no matter what the state of k_mirror --const char * JvmtiTrace::get_class_name(oop k_mirror) { -- if (java_lang_Class::is_primitive(k_mirror)) { -- return "primitive"; -- } -- klassOop k_oop = java_lang_Class::as_klassOop(k_mirror); -- if (k_oop == NULL) { -- return "INVALID"; -- } -- return Klass::cast(k_oop)->external_name(); --} -- --#endif /*JVMTI_TRACE */ - - // - // class GrowableCache - private methods -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiImpl.hpp openjdk/hotspot/src/share/vm/prims/jvmtiImpl.hpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiImpl.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiImpl.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)jvmtiImpl.hpp 1.102 07/05/23 10:53:50 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -476,147 +473,5 @@ - static void print(); - }; - -- --/////////////////////////////////////////////////////////////// --// --// class JvmtiUtil --// --// class for miscellaneous jvmti utility static methods --// -- --class JvmtiUtil : AllStatic { -- -- static ResourceArea* _single_threaded_resource_area; -- -- static const char* _error_names[]; -- static const bool _event_threaded[]; -- --public: -- -- static ResourceArea* single_threaded_resource_area(); -- -- static const char* error_name(int num) { return _error_names[num]; } // To Do: add range checking -- -- static const bool has_event_capability(jvmtiEvent event_type, const jvmtiCapabilities* capabilities_ptr); -- -- static const bool event_threaded(int num) { -- if (num >= JVMTI_MIN_EVENT_TYPE_VAL && num <= JVMTI_MAX_EVENT_TYPE_VAL) { -- return _event_threaded[num]; -- } -- if (num >= EXT_MIN_EVENT_TYPE_VAL && num <= EXT_MAX_EVENT_TYPE_VAL) { -- return false; -- } -- ShouldNotReachHere(); -- return false; -- } --}; -- -- --/////////////////////////////////////////////////////////////// --// --// class SafeResourceMark --// --// ResourceMarks that work before threads exist --// -- --class SafeResourceMark : public ResourceMark { -- -- ResourceArea* safe_resource_area() { -- Thread* thread; -- -- if (Threads::number_of_threads() == 0) { -- return JvmtiUtil::single_threaded_resource_area(); -- } -- thread = ThreadLocalStorage::thread(); -- if (thread == NULL) { -- return JvmtiUtil::single_threaded_resource_area(); -- } -- return thread->resource_area(); -- } -- -- public: -- -- SafeResourceMark() : ResourceMark(safe_resource_area()) {} -- --}; -- -- --/////////////////////////////////////////////////////////////// --// --// class JvmtiTrace --// --// Support for JVMTI tracing code --// -- --// Support tracing except in product build on the client compiler --#ifndef PRODUCT --#define JVMTI_TRACE 1 --#else --#ifdef COMPILER2 --#define JVMTI_TRACE 1 --#endif --#endif -- --#ifdef JVMTI_TRACE -- --class JvmtiTrace : AllStatic { -- -- static bool _initialized; -- static bool _on; -- static bool _trace_event_controller; -- static jbyte _trace_flags[]; -- static jbyte _event_trace_flags[]; -- static const char* _event_names[]; -- static jint _max_function_index; -- static jint _max_event_index; -- static short _exclude_functions[]; -- static const char* _function_names[]; -- --public: -- -- enum { -- SHOW_IN = 01, -- SHOW_OUT = 02, -- SHOW_ERROR = 04, -- SHOW_IN_DETAIL = 010, -- SHOW_OUT_DETAIL = 020, -- SHOW_EVENT_TRIGGER = 040, -- SHOW_EVENT_SENT = 0100 -- }; -- -- static bool tracing() { return _on; } -- static bool trace_event_controller() { return _trace_event_controller; } -- static jbyte trace_flags(int num) { return _trace_flags[num]; } -- static jbyte event_trace_flags(int num) { return _event_trace_flags[num]; } -- static const char* function_name(int num) { return _function_names[num]; } // To Do: add range checking -- -- static const char* event_name(int num) { -- static char* ext_event_name = (char*)"(extension event)"; -- if (num >= JVMTI_MIN_EVENT_TYPE_VAL && num <= JVMTI_MAX_EVENT_TYPE_VAL) { -- return _event_names[num]; -- } else { -- return ext_event_name; -- } -- } -- -- static const char* enum_name(const char** names, const jint* values, jint value); -- -- static void initialize(); -- static void shutdown(); -- -- // return a valid string no matter what state the thread is in -- static const char *safe_get_thread_name(Thread *thread); -- -- // return the name of the current thread -- static const char *safe_get_current_thread_name(); -- -- // return a valid string no matter what the state of k_mirror -- static const char *get_class_name(oop k_mirror); --}; -- --#endif /*JVMTI_TRACE */ -- -- - // Utility macro that checks for NULL pointers: - #define NULL_CHECK(X, Y) if ((X) == NULL) { return (Y); } -- -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiManageCapabilities.cpp openjdk/hotspot/src/share/vm/prims/jvmtiManageCapabilities.cpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiManageCapabilities.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiManageCapabilities.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)jvmtiManageCapabilities.cpp 1.44 07/05/05 17:06:40 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -458,5 +455,3 @@ - } - - #endif -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiManageCapabilities.hpp openjdk/hotspot/src/share/vm/prims/jvmtiManageCapabilities.hpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiManageCapabilities.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiManageCapabilities.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)jvmtiManageCapabilities.hpp 1.11 07/05/05 17:06:39 JVM" --#endif - /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp openjdk/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)jvmtiRedefineClasses.cpp 1.78 07/05/05 17:06:41 JVM" --#endif - /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -3050,9 +3047,11 @@ - klassOop the_class_oop = java_lang_Class::as_klassOop(the_class_mirror); - instanceKlassHandle the_class = instanceKlassHandle(THREAD, the_class_oop); - -+#ifndef JVMTI_KERNEL - // Remove all breakpoints in methods of this class - JvmtiBreakpoints& jvmti_breakpoints = JvmtiCurrentBreakpoints::get_jvmti_breakpoints(); - jvmti_breakpoints.clearall_in_class_at_safepoint(the_class_oop); -+#endif // !JVMTI_KERNEL - - if (the_class_oop == Universe::reflect_invoke_cache()->klass()) { - // We are redefining java.lang.reflect.Method. Method.invoke() is -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp openjdk/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiRedefineClasses.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)jvmtiRedefineClasses.hpp 1.41 08/06/19 12:45:49 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -334,108 +331,6 @@ - // coordinate a cleanup of these constants with Runtime. - // - -- --// RedefineClasses tracing support via the TraceRedefineClasses --// option. A bit is assigned to each group of trace messages. --// Groups of messages are individually selectable. We have to use --// decimal values on the command line since the command option --// parsing logic doesn't like non-decimal numerics. The HEX values --// are used in the actual RC_TRACE() calls for sanity. To achieve --// the old cumulative behavior, pick the level after the one in --// which you are interested and subtract one, e.g., 33554431 will --// print every tracing message. --// --// 0x00000000 | 0 - default; no tracing messages --// 0x00000001 | 1 - name each target class before loading, after --// loading and after redefinition is completed --// 0x00000002 | 2 - print info if parsing, linking or --// verification throws an exception --// 0x00000004 | 4 - print timer info for the VM operation --// 0x00000008 | 8 - print subclass counter updates --// 0x00000010 | 16 - unused --// 0x00000020 | 32 - unused --// 0x00000040 | 64 - unused --// 0x00000080 | 128 - unused --// 0x00000100 | 256 - previous class weak reference addition --// 0x00000200 | 512 - previous class weak reference mgmt during --// class unloading checks (GC) --// 0x00000400 | 1024 - previous class weak reference mgmt during --// add previous ops (GC) --// 0x00000800 | 2048 - previous class breakpoint mgmt --// 0x00001000 | 4096 - unused --// 0x00002000 | 8192 - unused --// 0x00004000 | 16384 - unused --// 0x00008000 | 32768 - old/new method matching/add/delete --// 0x00010000 | 65536 - impl details: CP size info --// 0x00020000 | 131072 - impl details: CP merge pass info --// 0x00040000 | 262144 - impl details: CP index maps --// 0x00080000 | 524288 - impl details: modified CP index values --// 0x00100000 | 1048576 - impl details: vtable updates --// 0x00200000 | 2097152 - impl details: itable updates --// 0x00400000 | 4194304 - impl details: constant pool cache updates --// 0x00800000 | 8388608 - impl details: methodComparator info --// 0x01000000 | 16777216 - impl details: nmethod evolution info --// 0x02000000 | 33554432 - impl details: annotation updates --// 0x04000000 | 67108864 - impl details: StackMapTable updates --// 0x08000000 | 134217728 - impl details: OopMapCache updates --// 0x10000000 | 268435456 - unused --// 0x20000000 | 536870912 - unused --// 0x40000000 | 1073741824 - unused --// 0x80000000 | 2147483648 - unused --// --// Note: The ResourceMark is to cleanup resource allocated args. --// The "while (0)" is so we can use semi-colon at end of RC_TRACE(). --#define RC_TRACE(level, args) \ -- if ((TraceRedefineClasses & level) != 0) { \ -- ResourceMark rm; \ -- tty->print("RedefineClasses-0x%x: ", level); \ -- tty->print_cr args; \ -- } while (0) -- --#define RC_TRACE_WITH_THREAD(level, thread, args) \ -- if ((TraceRedefineClasses & level) != 0) { \ -- ResourceMark rm(thread); \ -- tty->print("RedefineClasses-0x%x: ", level); \ -- tty->print_cr args; \ -- } while (0) -- --#define RC_TRACE_MESG(args) \ -- { \ -- ResourceMark rm; \ -- tty->print("RedefineClasses: "); \ -- tty->print_cr args; \ -- } while (0) -- --// Macro for checking if TraceRedefineClasses has a specific bit --// enabled. Returns true if the bit specified by level is set. --#define RC_TRACE_ENABLED(level) ((TraceRedefineClasses & level) != 0) -- --// Macro for checking if TraceRedefineClasses has one or more bits --// set in a range of bit values. Returns true if one or more bits --// is set in the range from low..high inclusive. Assumes that low --// and high are single bit values. --// --// ((high << 1) - 1) --// Yields a mask that removes bits greater than the high bit value. --// This algorithm doesn't work with highest bit. --// ~(low - 1) --// Yields a mask that removes bits lower than the low bit value. --#define RC_TRACE_IN_RANGE(low, high) \ --(((TraceRedefineClasses & ((high << 1) - 1)) & ~(low - 1)) != 0) -- --// Timer support macros. Only do timer operations if timer tracing --// is enabled. The "while (0)" is so we can use semi-colon at end of --// the macro. --#define RC_TIMER_START(t) \ -- if (RC_TRACE_ENABLED(0x00000004)) { \ -- t.start(); \ -- } while (0) --#define RC_TIMER_STOP(t) \ -- if (RC_TRACE_ENABLED(0x00000004)) { \ -- t.stop(); \ -- } while (0) -- -- - class VM_RedefineClasses: public VM_Operation { - private: - // These static fields are needed by SystemDictionary::classes_do() -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp openjdk/hotspot/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp 1970-01-01 01:00:00.000000000 +0100 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiRedefineClassesTrace.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -0,0 +1,123 @@ -+/* -+ * Copyright 2003-2006 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, -+ * CA 95054 USA or visit www.sun.com if you need additional information or -+ * have any questions. -+ * -+ */ -+ -+// RedefineClasses tracing support via the TraceRedefineClasses -+// option. A bit is assigned to each group of trace messages. -+// Groups of messages are individually selectable. We have to use -+// decimal values on the command line since the command option -+// parsing logic doesn't like non-decimal numerics. The HEX values -+// are used in the actual RC_TRACE() calls for sanity. To achieve -+// the old cumulative behavior, pick the level after the one in -+// which you are interested and subtract one, e.g., 33554431 will -+// print every tracing message. -+// -+// 0x00000000 | 0 - default; no tracing messages -+// 0x00000001 | 1 - name each target class before loading, after -+// loading and after redefinition is completed -+// 0x00000002 | 2 - print info if parsing, linking or -+// verification throws an exception -+// 0x00000004 | 4 - print timer info for the VM operation -+// 0x00000008 | 8 - print subclass counter updates -+// 0x00000010 | 16 - unused -+// 0x00000020 | 32 - unused -+// 0x00000040 | 64 - unused -+// 0x00000080 | 128 - unused -+// 0x00000100 | 256 - previous class weak reference addition -+// 0x00000200 | 512 - previous class weak reference mgmt during -+// class unloading checks (GC) -+// 0x00000400 | 1024 - previous class weak reference mgmt during -+// add previous ops (GC) -+// 0x00000800 | 2048 - previous class breakpoint mgmt -+// 0x00001000 | 4096 - unused -+// 0x00002000 | 8192 - unused -+// 0x00004000 | 16384 - unused -+// 0x00008000 | 32768 - old/new method matching/add/delete -+// 0x00010000 | 65536 - impl details: CP size info -+// 0x00020000 | 131072 - impl details: CP merge pass info -+// 0x00040000 | 262144 - impl details: CP index maps -+// 0x00080000 | 524288 - impl details: modified CP index values -+// 0x00100000 | 1048576 - impl details: vtable updates -+// 0x00200000 | 2097152 - impl details: itable updates -+// 0x00400000 | 4194304 - impl details: constant pool cache updates -+// 0x00800000 | 8388608 - impl details: methodComparator info -+// 0x01000000 | 16777216 - impl details: nmethod evolution info -+// 0x02000000 | 33554432 - impl details: annotation updates -+// 0x04000000 | 67108864 - impl details: StackMapTable updates -+// 0x08000000 | 134217728 - unused -+// 0x10000000 | 268435456 - unused -+// 0x20000000 | 536870912 - unused -+// 0x40000000 | 1073741824 - unused -+// 0x80000000 | 2147483648 - unused -+// -+// Note: The ResourceMark is to cleanup resource allocated args. -+// The "while (0)" is so we can use semi-colon at end of RC_TRACE(). -+#define RC_TRACE(level, args) \ -+ if ((TraceRedefineClasses & level) != 0) { \ -+ ResourceMark rm; \ -+ tty->print("RedefineClasses-0x%x: ", level); \ -+ tty->print_cr args; \ -+ } while (0) -+ -+#define RC_TRACE_WITH_THREAD(level, thread, args) \ -+ if ((TraceRedefineClasses & level) != 0) { \ -+ ResourceMark rm(thread); \ -+ tty->print("RedefineClasses-0x%x: ", level); \ -+ tty->print_cr args; \ -+ } while (0) -+ -+#define RC_TRACE_MESG(args) \ -+ { \ -+ ResourceMark rm; \ -+ tty->print("RedefineClasses: "); \ -+ tty->print_cr args; \ -+ } while (0) -+ -+// Macro for checking if TraceRedefineClasses has a specific bit -+// enabled. Returns true if the bit specified by level is set. -+#define RC_TRACE_ENABLED(level) ((TraceRedefineClasses & level) != 0) -+ -+// Macro for checking if TraceRedefineClasses has one or more bits -+// set in a range of bit values. Returns true if one or more bits -+// is set in the range from low..high inclusive. Assumes that low -+// and high are single bit values. -+// -+// ((high << 1) - 1) -+// Yields a mask that removes bits greater than the high bit value. -+// This algorithm doesn't work with highest bit. -+// ~(low - 1) -+// Yields a mask that removes bits lower than the low bit value. -+#define RC_TRACE_IN_RANGE(low, high) \ -+(((TraceRedefineClasses & ((high << 1) - 1)) & ~(low - 1)) != 0) -+ -+// Timer support macros. Only do timer operations if timer tracing -+// is enabled. The "while (0)" is so we can use semi-colon at end of -+// the macro. -+#define RC_TIMER_START(t) \ -+ if (RC_TRACE_ENABLED(0x00000004)) { \ -+ t.start(); \ -+ } while (0) -+#define RC_TIMER_STOP(t) \ -+ if (RC_TRACE_ENABLED(0x00000004)) { \ -+ t.stop(); \ -+ } while (0) -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiTagMap.cpp openjdk/hotspot/src/share/vm/prims/jvmtiTagMap.cpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiTagMap.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiTagMap.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)jvmtiTagMap.cpp 1.84 07/06/06 13:18:31 JVM" --#endif - /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -2251,6 +2248,15 @@ - return true; - } - -+// This mask is used to pass reference_info to a jvmtiHeapReferenceCallback -+// only for ref_kinds defined by the JVM TI spec. Otherwise, NULL is passed. -+#define REF_INFO_MASK ((1 << JVMTI_HEAP_REFERENCE_FIELD) \ -+ | (1 << JVMTI_HEAP_REFERENCE_STATIC_FIELD) \ -+ | (1 << JVMTI_HEAP_REFERENCE_ARRAY_ELEMENT) \ -+ | (1 << JVMTI_HEAP_REFERENCE_CONSTANT_POOL) \ -+ | (1 << JVMTI_HEAP_REFERENCE_STACK_LOCAL) \ -+ | (1 << JVMTI_HEAP_REFERENCE_JNI_LOCAL)) -+ - // invoke the object reference callback to report a reference - inline bool CallbackInvoker::invoke_advanced_object_reference_callback(jvmtiHeapReferenceKind ref_kind, - oop referrer, -@@ -2294,7 +2300,7 @@ - - // invoke the callback - int res = (*cb)(ref_kind, -- &reference_info, -+ (REF_INFO_MASK & (1 << ref_kind)) ? &reference_info : NULL, - wrapper.klass_tag(), - wrapper.referrer_klass_tag(), - wrapper.obj_size(), -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiTagMap.hpp openjdk/hotspot/src/share/vm/prims/jvmtiTagMap.hpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiTagMap.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiTagMap.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)jvmtiTagMap.hpp 1.25 07/05/05 17:06:40 JVM" --#endif - /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -136,4 +133,3 @@ - }; - - #endif /* _JAVA_JVMTI_TAG_MAP_H_ */ -- -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiThreadState.cpp openjdk/hotspot/src/share/vm/prims/jvmtiThreadState.cpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiThreadState.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiThreadState.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)jvmtiThreadState.cpp 1.44 07/05/05 17:06:36 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiThreadState.hpp openjdk/hotspot/src/share/vm/prims/jvmtiThreadState.hpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiThreadState.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiThreadState.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)jvmtiThreadState.hpp 1.35 07/05/05 17:06:40 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiThreadState.inline.hpp openjdk/hotspot/src/share/vm/prims/jvmtiThreadState.inline.hpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiThreadState.inline.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiThreadState.inline.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)jvmtiThreadState.inline.hpp 1.7 07/05/05 17:06:40 JVM" --#endif - /* - * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -63,4 +60,3 @@ - void JvmtiThreadState::set_head_env_thread_state(JvmtiEnvThreadState* ets) { - _head_env_thread_state = ets; - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiTrace.cpp openjdk/hotspot/src/share/vm/prims/jvmtiTrace.cpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiTrace.cpp 1970-01-01 01:00:00.000000000 +0100 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiTrace.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -0,0 +1,297 @@ -+/* -+ * Copyright 2003-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, -+ * CA 95054 USA or visit www.sun.com if you need additional information or -+ * have any questions. -+ * -+ */ -+ -+# include "incls/_precompiled.incl" -+# include "incls/_jvmtiTrace.cpp.incl" -+ -+// -+// class JvmtiTrace -+// -+// Support for JVMTI tracing code -+// -+// ------------ -+// Usage: -+// -XX:TraceJVMTI=DESC,DESC,DESC -+// -+// DESC is DOMAIN ACTION KIND -+// -+// DOMAIN is function name -+// event name -+// "all" (all functions and events) -+// "func" (all functions except boring) -+// "allfunc" (all functions) -+// "event" (all events) -+// "ec" (event controller) -+// -+// ACTION is "+" (add) -+// "-" (remove) -+// -+// KIND is -+// for func -+// "i" (input params) -+// "e" (error returns) -+// "o" (output) -+// for event -+// "t" (event triggered aka posted) -+// "s" (event sent) -+// -+// Example: -+// -XX:TraceJVMTI=ec+,GetCallerFrame+ie,Breakpoint+s -+ -+#ifdef JVMTI_TRACE -+ -+bool JvmtiTrace::_initialized = false; -+bool JvmtiTrace::_on = false; -+bool JvmtiTrace::_trace_event_controller = false; -+ -+void JvmtiTrace::initialize() { -+ if (_initialized) { -+ return; -+ } -+ SafeResourceMark rm; -+ -+ const char *very_end; -+ const char *curr; -+ if (strlen(TraceJVMTI)) { -+ curr = TraceJVMTI; -+ } else { -+ curr = ""; // hack in fixed tracing here -+ } -+ very_end = curr + strlen(curr); -+ while (curr < very_end) { -+ const char *curr_end = strchr(curr, ','); -+ if (curr_end == NULL) { -+ curr_end = very_end; -+ } -+ const char *op_pos = strchr(curr, '+'); -+ const char *minus_pos = strchr(curr, '-'); -+ if (minus_pos != NULL && (minus_pos < op_pos || op_pos == NULL)) { -+ op_pos = minus_pos; -+ } -+ char op; -+ const char *flags = op_pos + 1; -+ const char *flags_end = curr_end; -+ if (op_pos == NULL || op_pos > curr_end) { -+ flags = "ies"; -+ flags_end = flags + strlen(flags); -+ op_pos = curr_end; -+ op = '+'; -+ } else { -+ op = *op_pos; -+ } -+ jbyte bits = 0; -+ for (; flags < flags_end; ++flags) { -+ switch (*flags) { -+ case 'i': -+ bits |= SHOW_IN; -+ break; -+ case 'I': -+ bits |= SHOW_IN_DETAIL; -+ break; -+ case 'e': -+ bits |= SHOW_ERROR; -+ break; -+ case 'o': -+ bits |= SHOW_OUT; -+ break; -+ case 'O': -+ bits |= SHOW_OUT_DETAIL; -+ break; -+ case 't': -+ bits |= SHOW_EVENT_TRIGGER; -+ break; -+ case 's': -+ bits |= SHOW_EVENT_SENT; -+ break; -+ default: -+ tty->print_cr("Invalid trace flag '%c'", *flags); -+ break; -+ } -+ } -+ const int FUNC = 1; -+ const int EXCLUDE = 2; -+ const int ALL_FUNC = 4; -+ const int EVENT = 8; -+ const int ALL_EVENT = 16; -+ int domain = 0; -+ size_t len = op_pos - curr; -+ if (op_pos == curr) { -+ domain = ALL_FUNC | FUNC | ALL_EVENT | EVENT | EXCLUDE; -+ } else if (len==3 && strncmp(curr, "all", 3)==0) { -+ domain = ALL_FUNC | FUNC | ALL_EVENT | EVENT; -+ } else if (len==7 && strncmp(curr, "allfunc", 7)==0) { -+ domain = ALL_FUNC | FUNC; -+ } else if (len==4 && strncmp(curr, "func", 4)==0) { -+ domain = ALL_FUNC | FUNC | EXCLUDE; -+ } else if (len==8 && strncmp(curr, "allevent", 8)==0) { -+ domain = ALL_EVENT | EVENT; -+ } else if (len==5 && strncmp(curr, "event", 5)==0) { -+ domain = ALL_EVENT | EVENT; -+ } else if (len==2 && strncmp(curr, "ec", 2)==0) { -+ _trace_event_controller = true; -+ tty->print_cr("JVMTI Tracing the event controller"); -+ } else { -+ domain = FUNC | EVENT; // go searching -+ } -+ -+ int exclude_index = 0; -+ if (domain & FUNC) { -+ if (domain & ALL_FUNC) { -+ if (domain & EXCLUDE) { -+ tty->print("JVMTI Tracing all significant functions"); -+ } else { -+ tty->print_cr("JVMTI Tracing all functions"); -+ } -+ } -+ for (int i = 0; i <= _max_function_index; ++i) { -+ if (domain & EXCLUDE && i == _exclude_functions[exclude_index]) { -+ ++exclude_index; -+ } else { -+ bool do_op = false; -+ if (domain & ALL_FUNC) { -+ do_op = true; -+ } else { -+ const char *fname = function_name(i); -+ if (fname != NULL) { -+ size_t fnlen = strlen(fname); -+ if (len==fnlen && strncmp(curr, fname, fnlen)==0) { -+ tty->print_cr("JVMTI Tracing the function: %s", fname); -+ do_op = true; -+ } -+ } -+ } -+ if (do_op) { -+ if (op == '+') { -+ _trace_flags[i] |= bits; -+ } else { -+ _trace_flags[i] &= ~bits; -+ } -+ _on = true; -+ } -+ } -+ } -+ } -+ if (domain & EVENT) { -+ if (domain & ALL_EVENT) { -+ tty->print_cr("JVMTI Tracing all events"); -+ } -+ for (int i = 0; i <= _max_event_index; ++i) { -+ bool do_op = false; -+ if (domain & ALL_EVENT) { -+ do_op = true; -+ } else { -+ const char *ename = event_name(i); -+ if (ename != NULL) { -+ size_t evtlen = strlen(ename); -+ if (len==evtlen && strncmp(curr, ename, evtlen)==0) { -+ tty->print_cr("JVMTI Tracing the event: %s", ename); -+ do_op = true; -+ } -+ } -+ } -+ if (do_op) { -+ if (op == '+') { -+ _event_trace_flags[i] |= bits; -+ } else { -+ _event_trace_flags[i] &= ~bits; -+ } -+ _on = true; -+ } -+ } -+ } -+ if (!_on && (domain & (FUNC|EVENT))) { -+ tty->print_cr("JVMTI Trace domain not found"); -+ } -+ curr = curr_end + 1; -+ } -+ _initialized = true; -+} -+ -+ -+void JvmtiTrace::shutdown() { -+ int i; -+ _on = false; -+ _trace_event_controller = false; -+ for (i = 0; i <= _max_function_index; ++i) { -+ _trace_flags[i] = 0; -+ } -+ for (i = 0; i <= _max_event_index; ++i) { -+ _event_trace_flags[i] = 0; -+ } -+} -+ -+ -+const char* JvmtiTrace::enum_name(const char** names, const jint* values, jint value) { -+ for (int index = 0; names[index] != 0; ++index) { -+ if (values[index] == value) { -+ return names[index]; -+ } -+ } -+ return "*INVALID-ENUM-VALUE*"; -+} -+ -+ -+// return a valid string no matter what state the thread is in -+const char *JvmtiTrace::safe_get_thread_name(Thread *thread) { -+ if (thread == NULL) { -+ return "NULL"; -+ } -+ if (!thread->is_Java_thread()) { -+ return thread->name(); -+ } -+ JavaThread *java_thread = (JavaThread *)thread; -+ oop threadObj = java_thread->threadObj(); -+ if (threadObj == NULL) { -+ return "NULL"; -+ } -+ typeArrayOop name = java_lang_Thread::name(threadObj); -+ if (name == NULL) { -+ return ""; -+ } -+ return UNICODE::as_utf8((jchar*) name->base(T_CHAR), name->length()); -+} -+ -+ -+// return the name of the current thread -+const char *JvmtiTrace::safe_get_current_thread_name() { -+ if (JvmtiEnv::is_vm_live()) { -+ return JvmtiTrace::safe_get_thread_name(Thread::current()); -+ } else { -+ return "VM not live"; -+ } -+} -+ -+// return a valid string no matter what the state of k_mirror -+const char * JvmtiTrace::get_class_name(oop k_mirror) { -+ if (java_lang_Class::is_primitive(k_mirror)) { -+ return "primitive"; -+ } -+ klassOop k_oop = java_lang_Class::as_klassOop(k_mirror); -+ if (k_oop == NULL) { -+ return "INVALID"; -+ } -+ return Klass::cast(k_oop)->external_name(); -+} -+ -+#endif /*JVMTI_TRACE */ -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiTrace.hpp openjdk/hotspot/src/share/vm/prims/jvmtiTrace.hpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiTrace.hpp 1970-01-01 01:00:00.000000000 +0100 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiTrace.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -0,0 +1,98 @@ -+/* -+ * Copyright 1999-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, -+ * CA 95054 USA or visit www.sun.com if you need additional information or -+ * have any questions. -+ * -+ */ -+ -+/////////////////////////////////////////////////////////////// -+// -+// class JvmtiTrace -+// -+// Support for JVMTI tracing code -+// -+ -+// Support tracing except in product build on the client compiler -+#ifndef PRODUCT -+#define JVMTI_TRACE 1 -+#else -+#ifdef COMPILER2 -+#define JVMTI_TRACE 1 -+#endif -+#endif -+ -+#ifdef JVMTI_TRACE -+ -+class JvmtiTrace : AllStatic { -+ -+ static bool _initialized; -+ static bool _on; -+ static bool _trace_event_controller; -+ static jbyte _trace_flags[]; -+ static jbyte _event_trace_flags[]; -+ static const char* _event_names[]; -+ static jint _max_function_index; -+ static jint _max_event_index; -+ static short _exclude_functions[]; -+ static const char* _function_names[]; -+ -+public: -+ -+ enum { -+ SHOW_IN = 01, -+ SHOW_OUT = 02, -+ SHOW_ERROR = 04, -+ SHOW_IN_DETAIL = 010, -+ SHOW_OUT_DETAIL = 020, -+ SHOW_EVENT_TRIGGER = 040, -+ SHOW_EVENT_SENT = 0100 -+ }; -+ -+ static bool tracing() { return _on; } -+ static bool trace_event_controller() { return _trace_event_controller; } -+ static jbyte trace_flags(int num) { return _trace_flags[num]; } -+ static jbyte event_trace_flags(int num) { return _event_trace_flags[num]; } -+ static const char* function_name(int num) { return _function_names[num]; } // To Do: add range checking -+ -+ static const char* event_name(int num) { -+ static char* ext_event_name = (char*)"(extension event)"; -+ if (num >= JVMTI_MIN_EVENT_TYPE_VAL && num <= JVMTI_MAX_EVENT_TYPE_VAL) { -+ return _event_names[num]; -+ } else { -+ return ext_event_name; -+ } -+ } -+ -+ static const char* enum_name(const char** names, const jint* values, jint value); -+ -+ static void initialize(); -+ static void shutdown(); -+ -+ // return a valid string no matter what state the thread is in -+ static const char *safe_get_thread_name(Thread *thread); -+ -+ // return the name of the current thread -+ static const char *safe_get_current_thread_name(); -+ -+ // return a valid string no matter what the state of k_mirror -+ static const char *get_class_name(oop k_mirror); -+}; -+ -+#endif /*JVMTI_TRACE */ -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiUtil.cpp openjdk/hotspot/src/share/vm/prims/jvmtiUtil.cpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiUtil.cpp 1970-01-01 01:00:00.000000000 +0100 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiUtil.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -0,0 +1,40 @@ -+/* -+ * Copyright 2003-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, -+ * CA 95054 USA or visit www.sun.com if you need additional information or -+ * have any questions. -+ * -+ */ -+ -+# include "incls/_precompiled.incl" -+# include "incls/_jvmtiUtil.cpp.incl" -+// -+// class JvmtiUtil -+// -+ -+ResourceArea* JvmtiUtil::_single_threaded_resource_area = NULL; -+ -+ResourceArea* JvmtiUtil::single_threaded_resource_area() { -+ if (_single_threaded_resource_area == NULL) { -+ // lazily create the single threaded resource area -+ // pick a size which is not a standard since the pools don't exist yet -+ _single_threaded_resource_area = new ResourceArea(Chunk::non_pool_size); -+ } -+ return _single_threaded_resource_area; -+} -diff -ruNb openjdk6/hotspot/src/share/vm/prims/jvmtiUtil.hpp openjdk/hotspot/src/share/vm/prims/jvmtiUtil.hpp ---- openjdk6/hotspot/src/share/vm/prims/jvmtiUtil.hpp 1970-01-01 01:00:00.000000000 +0100 -+++ openjdk/hotspot/src/share/vm/prims/jvmtiUtil.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -0,0 +1,86 @@ -+/* -+ * Copyright 1999-2007 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, -+ * CA 95054 USA or visit www.sun.com if you need additional information or -+ * have any questions. -+ * -+ */ -+ -+/////////////////////////////////////////////////////////////// -+// -+// class JvmtiUtil -+// -+// class for miscellaneous jvmti utility static methods -+// -+ -+class JvmtiUtil : AllStatic { -+ -+ static ResourceArea* _single_threaded_resource_area; -+ -+ static const char* _error_names[]; -+ static const bool _event_threaded[]; -+ -+public: -+ -+ static ResourceArea* single_threaded_resource_area(); -+ -+ static const char* error_name(int num) { return _error_names[num]; } // To Do: add range checking -+ -+ static const bool has_event_capability(jvmtiEvent event_type, const jvmtiCapabilities* capabilities_ptr); -+ -+ static const bool event_threaded(int num) { -+ if (num >= JVMTI_MIN_EVENT_TYPE_VAL && num <= JVMTI_MAX_EVENT_TYPE_VAL) { -+ return _event_threaded[num]; -+ } -+ if (num >= EXT_MIN_EVENT_TYPE_VAL && num <= EXT_MAX_EVENT_TYPE_VAL) { -+ return false; -+ } -+ ShouldNotReachHere(); -+ return false; -+ } -+}; -+ -+ -+/////////////////////////////////////////////////////////////// -+// -+// class SafeResourceMark -+// -+// ResourceMarks that work before threads exist -+// -+ -+class SafeResourceMark : public ResourceMark { -+ -+ ResourceArea* safe_resource_area() { -+ Thread* thread; -+ -+ if (Threads::number_of_threads() == 0) { -+ return JvmtiUtil::single_threaded_resource_area(); -+ } -+ thread = ThreadLocalStorage::thread(); -+ if (thread == NULL) { -+ return JvmtiUtil::single_threaded_resource_area(); -+ } -+ return thread->resource_area(); -+ } -+ -+ public: -+ -+ SafeResourceMark() : ResourceMark(safe_resource_area()) {} -+ -+}; -diff -ruNb openjdk6/hotspot/src/share/vm/prims/methodComparator.cpp openjdk/hotspot/src/share/vm/prims/methodComparator.cpp ---- openjdk6/hotspot/src/share/vm/prims/methodComparator.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/methodComparator.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)methodComparator.cpp 1.15 07/05/05 17:06:41 JVM" --#endif - /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/prims/methodComparator.hpp openjdk/hotspot/src/share/vm/prims/methodComparator.hpp ---- openjdk6/hotspot/src/share/vm/prims/methodComparator.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/methodComparator.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)methodComparator.hpp 1.12 07/05/05 17:06:40 JVM" --#endif - /* - * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/prims/nativeLookup.cpp openjdk/hotspot/src/share/vm/prims/nativeLookup.cpp ---- openjdk6/hotspot/src/share/vm/prims/nativeLookup.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/nativeLookup.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)nativeLookup.cpp 1.82 07/05/05 17:06:42 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/prims/nativeLookup.hpp openjdk/hotspot/src/share/vm/prims/nativeLookup.hpp ---- openjdk6/hotspot/src/share/vm/prims/nativeLookup.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/nativeLookup.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)nativeLookup.hpp 1.27 07/05/05 17:06:41 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/prims/perf.cpp openjdk/hotspot/src/share/vm/prims/perf.cpp ---- openjdk6/hotspot/src/share/vm/prims/perf.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/perf.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)perf.cpp 1.15 07/05/05 17:06:34 JVM" --#endif - /* - * Copyright 2001-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -314,4 +311,3 @@ - guarantee(ok == 0, "register perf natives"); - } - JVM_END -- -diff -ruNb openjdk6/hotspot/src/share/vm/prims/privilegedStack.cpp openjdk/hotspot/src/share/vm/prims/privilegedStack.cpp ---- openjdk6/hotspot/src/share/vm/prims/privilegedStack.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/privilegedStack.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)privilegedStack.cpp 1.31 07/05/05 17:06:42 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -77,4 +74,3 @@ - } - - #endif -- -diff -ruNb openjdk6/hotspot/src/share/vm/prims/privilegedStack.hpp openjdk/hotspot/src/share/vm/prims/privilegedStack.hpp ---- openjdk6/hotspot/src/share/vm/prims/privilegedStack.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/privilegedStack.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)privilegedStack.hpp 1.25 07/05/05 17:06:41 JVM" --#endif - /* - * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -44,4 +41,3 @@ - void print_on(outputStream* st) const PRODUCT_RETURN; - bool contains(address addr) PRODUCT_RETURN0; - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/prims/unsafe.cpp openjdk/hotspot/src/share/vm/prims/unsafe.cpp ---- openjdk6/hotspot/src/share/vm/prims/unsafe.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/prims/unsafe.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)unsafe.cpp 1.64 07/05/17 16:05:09 JVM" --#endif - /* - * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/aprofiler.cpp openjdk/hotspot/src/share/vm/runtime/aprofiler.cpp ---- openjdk6/hotspot/src/share/vm/runtime/aprofiler.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/aprofiler.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)aprofiler.cpp 1.33 07/05/05 17:06:43 JVM" --#endif - /* - * Copyright 1997-2002 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/aprofiler.hpp openjdk/hotspot/src/share/vm/runtime/aprofiler.hpp ---- openjdk6/hotspot/src/share/vm/runtime/aprofiler.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/aprofiler.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)aprofiler.hpp 1.32 07/05/05 17:06:42 JVM" --#endif - /* - * Copyright 1997-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/arguments.cpp openjdk/hotspot/src/share/vm/runtime/arguments.cpp ---- openjdk6/hotspot/src/share/vm/runtime/arguments.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/arguments.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)arguments.cpp 1.333 07/09/25 22:04:01 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -545,7 +542,7 @@ - static bool append_to_string_flag(char* name, const char* new_value, FlagValueOrigin origin) { - const char* old_value = ""; - if (!CommandLineFlags::ccstrAt(name, &old_value)) return false; -- size_t old_len = strlen(old_value); -+ size_t old_len = old_value != NULL ? strlen(old_value) : 0; - size_t new_len = strlen(new_value); - const char* value; - char* free_this_too = NULL; -@@ -589,14 +586,25 @@ - char punct; - if (sscanf(arg, "%" XSTR(BUFLEN) NAME_RANGE "%c", name, &punct) == 2 && punct == '=') { - const char* value = strchr(arg, '=') + 1; -- // Note that normal -XX:Foo=WWW accumulates. -- bool success = append_to_string_flag(name, value, origin); -- if (success) return success; -+ Flag* flag = Flag::find_flag(name, strlen(name)); -+ if (flag != NULL && flag->is_ccstr()) { -+ if (flag->ccstr_accumulates()) { -+ return append_to_string_flag(name, value, origin); -+ } else { -+ if (value[0] == '\0') { -+ value = NULL; -+ } -+ return set_string_flag(name, value, origin); -+ } -+ } - } - - if (sscanf(arg, "%" XSTR(BUFLEN) NAME_RANGE ":%c", name, &punct) == 2 && punct == '=') { - const char* value = strchr(arg, '=') + 1; - // -XX:Foo:=xxx will reset the string flag to the given value. -+ if (value[0] == '\0') { -+ value = NULL; -+ } - return set_string_flag(name, value, origin); - } - -@@ -1253,12 +1261,6 @@ - FLAG_SET_DEFAULT(CacheTimeMillis, true); - } - ) --#ifdef COMPILER2 -- if (FLAG_IS_DEFAULT(UseSuperWord)) { -- // Generate SIMD instructions -- FLAG_SET_DEFAULT(UseSuperWord, true); -- } --#endif /* COMPILER2 */ - } - } - -@@ -1678,6 +1680,11 @@ - size_t len2 = strlen(pos+1) + 1; // options start after ':'. Final zero must be copied. - options = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len2), pos+1, len2); - } -+#ifdef JVMTI_KERNEL -+ if ((strcmp(name, "hprof") == 0) || (strcmp(name, "jdwp") == 0)) { -+ warning("profiling and debugging agents are not supported with Kernel VM"); -+ } else -+#endif // JVMTI_KERNEL - add_init_library(name, options); - } - // -agentlib and -agentpath -@@ -1693,7 +1700,13 @@ - if(pos != NULL) { - options = strcpy(NEW_C_HEAP_ARRAY(char, strlen(pos + 1) + 1), pos + 1); - } -+#ifdef JVMTI_KERNEL -+ if ((strcmp(name, "hprof") == 0) || (strcmp(name, "jdwp") == 0)) { -+ warning("profiling and debugging agents are not supported with Kernel VM"); -+ } else -+#endif // JVMTI_KERNEL - add_init_agent(name, options, is_absolute_path); -+ - } - // -javaagent - } else if (match_option(option, "-javaagent:", &tail)) { -@@ -1831,7 +1844,12 @@ - // EVM option, ignore silently for compatibility - // -Xprof - } else if (match_option(option, "-Xprof", &tail)) { -+#ifndef FPROF_KERNEL - _has_profile = true; -+#else // FPROF_KERNEL -+ // do we have to exit? -+ warning("Kernel VM does not support flat profiling."); -+#endif // FPROF_KERNEL - // -Xaprof - } else if (match_option(option, "-Xaprof", &tail)) { - _has_alloc_profile = true; -@@ -1882,6 +1900,9 @@ - #elif defined(COMPILER2) - vm_exit_during_initialization( - "Dumping a shared archive is not supported on the Server JVM.", NULL); -+#elif defined(KERNEL) -+ vm_exit_during_initialization( -+ "Dumping a shared archive is not supported on the Kernel JVM.", NULL); - #else - FLAG_SET_CMDLINE(bool, DumpSharedSpaces, true); - set_mode_flags(_int); // Prevent compilation, which creates objects -@@ -2210,6 +2231,9 @@ - // not specified. - set_mode_flags(_int); - } -+ if (CompileThreshold == 0) { -+ set_mode_flags(_int); -+ } - - #ifdef TIERED - // If we are using tiered compilation in the tiered vm then c1 will -@@ -2423,6 +2447,9 @@ - #ifdef SERIALGC - set_serial_gc_flags(); - #endif // SERIALGC -+#ifdef KERNEL -+ no_shared_spaces(); -+#endif // KERNEL - - // Set some flags for ParallelGC if needed. - set_parallel_gc_flags(); -@@ -2443,10 +2470,10 @@ - // Set flags if Aggressive optimization flags (-XX:+AggressiveOpts) enabled. - set_aggressive_opts_flags(); - --#ifdef IA64 -- // Biased locking is not implemented on IA64 -+#ifdef CC_INTERP -+ // Biased locking is not implemented with c++ interpreter - FLAG_SET_DEFAULT(UseBiasedLocking, false); --#endif /* IA64 */ -+#endif /* CC_INTERP */ - - if (PrintCommandLineFlags) { - CommandLineFlags::printSetFlags(); -@@ -2542,6 +2569,36 @@ - PropertyList_add(plist, k, v); - } - -+#ifdef KERNEL -+char *Arguments::get_kernel_properties() { -+ // Find properties starting with kernel and append them to string -+ // We need to find out how long they are first because the URL's that they -+ // might point to could get long. -+ int length = 0; -+ SystemProperty* prop; -+ for (prop = _system_properties; prop != NULL; prop = prop->next()) { -+ if (strncmp(prop->key(), "kernel.", 7 ) == 0) { -+ length += (strlen(prop->key()) + strlen(prop->value()) + 5); // "-D =" -+ } -+ } -+ // Add one for null terminator. -+ char *props = AllocateHeap(length + 1, "get_kernel_properties"); -+ if (length != 0) { -+ int pos = 0; -+ for (prop = _system_properties; prop != NULL; prop = prop->next()) { -+ if (strncmp(prop->key(), "kernel.", 7 ) == 0) { -+ jio_snprintf(&props[pos], length-pos, -+ "-D%s=%s ", prop->key(), prop->value()); -+ pos = strlen(props); -+ } -+ } -+ } -+ // null terminate props in case of null -+ props[length] = '\0'; -+ return props; -+} -+#endif // KERNEL -+ - // Copies src into buf, replacing "%%" with "%" and "%p" with pid - // Returns true if all of the source pointed by src has been copied over to - // the destination buffer pointed by buf. Otherwise, returns false. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/arguments.hpp openjdk/hotspot/src/share/vm/runtime/arguments.hpp ---- openjdk6/hotspot/src/share/vm/runtime/arguments.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/arguments.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)arguments.hpp 1.103 07/06/27 11:12:35 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -506,4 +503,9 @@ - - // Utility: copies src into buf, replacing "%%" with "%" and "%p" with pid. - static bool copy_expand_pid(const char* src, size_t srclen, char* buf, size_t buflen); -+ -+#ifdef KERNEL -+ // For java kernel vm, return property string for kernel properties. -+ static char *get_kernel_properties(); -+#endif // KERNEL - }; -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/atomic.cpp openjdk/hotspot/src/share/vm/runtime/atomic.cpp ---- openjdk6/hotspot/src/share/vm/runtime/atomic.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/atomic.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)atomic.cpp 1.14 07/05/05 17:06:42 JVM" --#endif - /* - * Copyright 2001-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/atomic.hpp openjdk/hotspot/src/share/vm/runtime/atomic.hpp ---- openjdk6/hotspot/src/share/vm/runtime/atomic.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/atomic.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)atomic.hpp 1.22 07/05/05 17:06:42 JVM" --#endif - /* - * Copyright 1999-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/biasedLocking.cpp openjdk/hotspot/src/share/vm/runtime/biasedLocking.cpp ---- openjdk6/hotspot/src/share/vm/runtime/biasedLocking.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/biasedLocking.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)biasedLocking.cpp 1.15 07/05/23 10:53:58 JVM" --#endif - - /* - * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/biasedLocking.hpp openjdk/hotspot/src/share/vm/runtime/biasedLocking.hpp ---- openjdk6/hotspot/src/share/vm/runtime/biasedLocking.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/biasedLocking.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)biasedLocking.hpp 1.11 07/05/17 16:05:21 JVM" --#endif - /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/compilationPolicy.cpp openjdk/hotspot/src/share/vm/runtime/compilationPolicy.cpp ---- openjdk6/hotspot/src/share/vm/runtime/compilationPolicy.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/compilationPolicy.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)compilationPolicy.cpp 1.45 07/05/05 17:06:45 JVM" --#endif - /* - * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -449,4 +446,3 @@ - - - #endif // COMPILER2 -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/compilationPolicy.hpp openjdk/hotspot/src/share/vm/runtime/compilationPolicy.hpp ---- openjdk6/hotspot/src/share/vm/runtime/compilationPolicy.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/compilationPolicy.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)compilationPolicy.hpp 1.15 07/05/05 17:06:44 JVM" --#endif - /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/deoptimization.cpp openjdk/hotspot/src/share/vm/runtime/deoptimization.cpp ---- openjdk6/hotspot/src/share/vm/runtime/deoptimization.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/deoptimization.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)deoptimization.cpp 1.282 07/05/17 16:05:24 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -89,12 +86,15 @@ - } - - --JRT_LEAF(Deoptimization::UnrollBlock*, Deoptimization::fetch_unroll_info(JavaThread* thread)) -+// In order to make fetch_unroll_info work properly with escape -+// analysis, The method was changed from JRT_LEAF to JRT_BLOCK_ENTRY and -+// ResetNoHandleMark and HandleMark were removed from it. The actual reallocation -+// of previously eliminated objects occurs in realloc_objects, which is -+// called from the method fetch_unroll_info_helper below. -+JRT_BLOCK_ENTRY(Deoptimization::UnrollBlock*, Deoptimization::fetch_unroll_info(JavaThread* thread)) - // It is actually ok to allocate handles in a leaf method. It causes no safepoints, - // but makes the entry a little slower. There is however a little dance we have to - // do in debug mode to get around the NoHandleMark code in the JRT_LEAF macro -- ResetNoHandleMark rnhm; // No-op in release/product versions -- HandleMark hm; - - // fetch_unroll_info() is called at the beginning of the deoptimization - // handler. Note this fact before we start generating temporary frames -@@ -125,13 +125,68 @@ - // Now get the deoptee with a valid map - frame deoptee = stub_frame.sender(&map); - -- // We are safepoint safe up to this call -- vframeArray* array = create_vframeArray(thread, deoptee, &map); -+ // Create a growable array of VFrames where each VFrame represents an inlined -+ // Java frame. This storage is allocated with the usual system arena. -+ assert(deoptee.is_compiled_frame(), "Wrong frame type"); -+ GrowableArray* chunk = new GrowableArray(10); -+ vframe* vf = vframe::new_vframe(&deoptee, &map, thread); -+ while (!vf->is_top()) { -+ assert(vf->is_compiled_frame(), "Wrong frame type"); -+ chunk->push(compiledVFrame::cast(vf)); -+ vf = vf->sender(); -+ } -+ assert(vf->is_compiled_frame(), "Wrong frame type"); -+ chunk->push(compiledVFrame::cast(vf)); - -- // We are no longer safepoint safe. If a safepoint occurs from here on -+#ifdef COMPILER2 -+ // Reallocate the non-escaping objects and restore their fields. Then -+ // relock objects if synchronization on them was eliminated. -+ if (DoEscapeAnalysis && EliminateAllocations) { -+ GrowableArray* objects = chunk->at(0)->scope()->objects(); -+ bool reallocated = false; -+ if (objects != NULL) { -+ JRT_BLOCK -+ reallocated = realloc_objects(thread, &deoptee, objects, THREAD); -+ JRT_END -+ } -+ if (reallocated) { -+ reassign_fields(&deoptee, &map, objects); -+#ifndef PRODUCT -+ if (TraceDeoptimization) { -+ ttyLocker ttyl; -+ tty->print_cr("REALLOC OBJECTS in thread " INTPTR_FORMAT, thread); -+ print_objects(objects); -+ } -+#endif -+ } -+ for (int i = 0; i < chunk->length(); i++) { -+ GrowableArray* monitors = chunk->at(i)->scope()->monitors(); -+ if (monitors != NULL) { -+ relock_objects(&deoptee, &map, monitors); -+#ifndef PRODUCT -+ if (TraceDeoptimization) { -+ ttyLocker ttyl; -+ tty->print_cr("RELOCK OBJECTS in thread " INTPTR_FORMAT, thread); -+ for (int j = 0; i < monitors->length(); i++) { -+ MonitorValue* mv = monitors->at(i); -+ if (mv->eliminated()) { -+ StackValue* owner = StackValue::create_stack_value(&deoptee, &map, mv->owner()); -+ tty->print_cr(" object <" INTPTR_FORMAT "> locked", owner->get_obj()()); -+ } -+ } -+ } -+#endif -+ } -+ } -+ } -+#endif // COMPILER2 -+ // Ensure that no safepoint is taken after pointers have been stored -+ // in fields of rematerialized objects. If a safepoint occurs from here on - // out the java state residing in the vframeArray will be missed. - No_Safepoint_Verifier no_safepoint; - -+ vframeArray* array = create_vframeArray(thread, deoptee, &map, chunk); -+ - assert(thread->vframe_array_head() == NULL, "Pending deopt!");; - thread->set_vframe_array_head(array); - -@@ -194,7 +249,7 @@ - int popframe_extra_args = 0; - // Create an interpreter return address for the stub to use as its return - // address so the skeletal frames are perfectly walkable -- frame_pcs[number_of_frames] = AbstractInterpreter::deopt_entry(vtos, 0); -+ frame_pcs[number_of_frames] = Interpreter::deopt_entry(vtos, 0); - - // PopFrame requires that the preserved incoming arguments from the recently-popped topmost - // activation be put back on the expression stack of the caller for reexecution -@@ -228,7 +283,7 @@ - // as interpreted so the skeleton frame will be walkable - // The correct pc will be set when the skeleton frame is completely filled out - // The final pc we store in the loop is wrong and will be overwritten below -- frame_pcs[number_of_frames - 1 - index ] = AbstractInterpreter::deopt_entry(vtos, 0) - frame::pc_return_offset; -+ frame_pcs[number_of_frames - 1 - index ] = Interpreter::deopt_entry(vtos, 0) - frame::pc_return_offset; - - callee_parameters = array->element(index)->method()->size_of_parameters(); - callee_locals = array->element(index)->method()->max_locals(); -@@ -543,21 +598,206 @@ - return 0; - } - --vframeArray* Deoptimization::create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map) { -- // Create a growable array of VFrames where each VFrame represents an inlined -- // Java frame. This storage is allocated with the usual system arena. --#ifdef ASSERT -- assert(fr.is_compiled_frame(), "Wrong frame type"); --#endif /* ASSERT */ -- GrowableArray* chunk = new GrowableArray(10); -- vframe* vf = vframe::new_vframe(&fr, reg_map, thread); -- while (!vf->is_top()) { -- assert(vf->is_compiled_frame(), "Wrong frame type"); -- chunk->push(compiledVFrame::cast(vf)); -- vf = vf->sender(); -+ -+#ifdef COMPILER2 -+bool Deoptimization::realloc_objects(JavaThread* thread, frame* fr, GrowableArray* objects, TRAPS) { -+ Handle pending_exception(thread->pending_exception()); -+ const char* exception_file = thread->exception_file(); -+ int exception_line = thread->exception_line(); -+ thread->clear_pending_exception(); -+ -+ for (int i = 0; i < objects->length(); i++) { -+ assert(objects->at(i)->is_object(), "invalid debug information"); -+ ObjectValue* sv = (ObjectValue*) objects->at(i); -+ -+ KlassHandle k(((ConstantOopReadValue*) sv->klass())->value()()); -+ oop obj = NULL; -+ -+ if (k->oop_is_instance()) { -+ instanceKlass* ik = instanceKlass::cast(k()); -+ obj = ik->allocate_instance(CHECK_(false)); -+ } else if (k->oop_is_typeArray()) { -+ typeArrayKlass* ak = typeArrayKlass::cast(k()); -+ assert(sv->field_size() % type2size[ak->element_type()] == 0, "non-integral array length"); -+ int len = sv->field_size() / type2size[ak->element_type()]; -+ obj = ak->allocate(len, CHECK_(false)); -+ } else if (k->oop_is_objArray()) { -+ objArrayKlass* ak = objArrayKlass::cast(k()); -+ obj = ak->allocate(sv->field_size(), CHECK_(false)); -+ } -+ -+ assert(obj != NULL, "allocation failed"); -+ assert(sv->value().is_null(), "redundant reallocation"); -+ sv->set_value(obj); -+ } -+ -+ if (pending_exception.not_null()) { -+ thread->set_pending_exception(pending_exception(), exception_file, exception_line); -+ } -+ -+ return true; -+} -+ -+// This assumes that the fields are stored in ObjectValue in the same order -+// they are yielded by do_nonstatic_fields. -+class FieldReassigner: public FieldClosure { -+ frame* _fr; -+ RegisterMap* _reg_map; -+ ObjectValue* _sv; -+ instanceKlass* _ik; -+ oop _obj; -+ -+ int _i; -+public: -+ FieldReassigner(frame* fr, RegisterMap* reg_map, ObjectValue* sv, oop obj) : -+ _fr(fr), _reg_map(reg_map), _sv(sv), _obj(obj), _i(0) {} -+ -+ int i() const { return _i; } -+ -+ -+ void do_field(fieldDescriptor* fd) { -+ StackValue* value = -+ StackValue::create_stack_value(_fr, _reg_map, _sv->field_at(i())); -+ int offset = fd->offset(); -+ switch (fd->field_type()) { -+ case T_OBJECT: case T_ARRAY: -+ assert(value->type() == T_OBJECT, "Agreement."); -+ _obj->obj_field_put(offset, value->get_obj()()); -+ break; -+ -+ case T_LONG: case T_DOUBLE: { -+ assert(value->type() == T_INT, "Agreement."); -+ StackValue* low = -+ StackValue::create_stack_value(_fr, _reg_map, _sv->field_at(++_i)); -+ jlong res = jlong_from((jint)value->get_int(), (jint)low->get_int()); -+ _obj->long_field_put(offset, res); -+ break; - } -- assert(vf->is_compiled_frame(), "Wrong frame type"); -- chunk->push(compiledVFrame::cast(vf)); -+ -+ case T_INT: case T_FLOAT: // 4 bytes. -+ assert(value->type() == T_INT, "Agreement."); -+ _obj->int_field_put(offset, (jint)value->get_int()); -+ break; -+ -+ case T_SHORT: case T_CHAR: // 2 bytes -+ assert(value->type() == T_INT, "Agreement."); -+ _obj->short_field_put(offset, (jshort)value->get_int()); -+ break; -+ -+ case T_BOOLEAN: // 1 byte -+ assert(value->type() == T_INT, "Agreement."); -+ _obj->bool_field_put(offset, (jboolean)value->get_int()); -+ break; -+ -+ default: -+ ShouldNotReachHere(); -+ } -+ _i++; -+ } -+}; -+ -+// restore elements of an eliminated type array -+void Deoptimization::reassign_type_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, typeArrayOop obj, BasicType type) { -+ StackValue* low; -+ jlong lval; -+ int index = 0; -+ -+ for (int i = 0; i < sv->field_size(); i++) { -+ StackValue* value = StackValue::create_stack_value(fr, reg_map, sv->field_at(i)); -+ switch(type) { -+ case T_BOOLEAN: obj->bool_at_put (index, (jboolean) value->get_int()); break; -+ case T_BYTE: obj->byte_at_put (index, (jbyte) value->get_int()); break; -+ case T_CHAR: obj->char_at_put (index, (jchar) value->get_int()); break; -+ case T_SHORT: obj->short_at_put(index, (jshort) value->get_int()); break; -+ case T_INT: obj->int_at_put (index, (jint) value->get_int()); break; -+ case T_FLOAT: obj->float_at_put(index, (jfloat) value->get_int()); break; -+ case T_LONG: -+ case T_DOUBLE: -+ low = StackValue::create_stack_value(fr, reg_map, sv->field_at(++i)); -+ lval = jlong_from((jint)value->get_int(), (jint)low->get_int()); -+ sv->value()->long_field_put(index, lval); -+ break; -+ default: -+ ShouldNotReachHere(); -+ } -+ index++; -+ } -+} -+ -+ -+// restore fields of an eliminated object array -+void Deoptimization::reassign_object_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, objArrayOop obj) { -+ for (int i = 0; i < sv->field_size(); i++) { -+ StackValue* value = StackValue::create_stack_value(fr, reg_map, sv->field_at(i)); -+ assert(value->type() == T_OBJECT, "object element expected"); -+ obj->obj_at_put(i, value->get_obj()()); -+ } -+} -+ -+ -+// restore fields of all eliminated objects and arrays -+void Deoptimization::reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray* objects) { -+ for (int i = 0; i < objects->length(); i++) { -+ ObjectValue* sv = (ObjectValue*) objects->at(i); -+ KlassHandle k(((ConstantOopReadValue*) sv->klass())->value()()); -+ Handle obj = sv->value(); -+ assert(obj.not_null(), "reallocation was missed"); -+ -+ if (k->oop_is_instance()) { -+ instanceKlass* ik = instanceKlass::cast(k()); -+ FieldReassigner reassign(fr, reg_map, sv, obj()); -+ ik->do_nonstatic_fields(&reassign); -+ } else if (k->oop_is_typeArray()) { -+ typeArrayKlass* ak = typeArrayKlass::cast(k()); -+ reassign_type_array_elements(fr, reg_map, sv, (typeArrayOop) obj(), ak->element_type()); -+ } else if (k->oop_is_objArray()) { -+ reassign_object_array_elements(fr, reg_map, sv, (objArrayOop) obj()); -+ } -+ } -+} -+ -+ -+// relock objects for which synchronization was eliminated -+void Deoptimization::relock_objects(frame* fr, RegisterMap* reg_map, GrowableArray* monitors) { -+ for (int i = 0; i < monitors->length(); i++) { -+ MonitorValue* mv = monitors->at(i); -+ StackValue* owner = StackValue::create_stack_value(fr, reg_map, mv->owner()); -+ if (mv->eliminated()) { -+ Handle obj = owner->get_obj(); -+ assert(obj.not_null(), "reallocation was missed"); -+ BasicLock* lock = StackValue::resolve_monitor_lock(fr, mv->basic_lock()); -+ lock->set_displaced_header(obj->mark()); -+ obj->set_mark((markOop) lock); -+ } -+ assert(owner->get_obj()->is_locked(), "object must be locked now"); -+ } -+} -+ -+ -+#ifndef PRODUCT -+// print information about reallocated objects -+void Deoptimization::print_objects(GrowableArray* objects) { -+ fieldDescriptor fd; -+ -+ for (int i = 0; i < objects->length(); i++) { -+ ObjectValue* sv = (ObjectValue*) objects->at(i); -+ KlassHandle k(((ConstantOopReadValue*) sv->klass())->value()()); -+ Handle obj = sv->value(); -+ -+ tty->print(" object <" INTPTR_FORMAT "> of type ", sv->value()()); -+ k->as_klassOop()->print_value(); -+ tty->print(" allocated (%d bytes)", obj->size() * HeapWordSize); -+ tty->cr(); -+ -+ if (Verbose) { -+ k->oop_print_on(obj(), tty); -+ } -+ } -+} -+#endif -+#endif // COMPILER2 -+ -+vframeArray* Deoptimization::create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray* chunk) { - - #ifndef PRODUCT - if (TraceDeoptimization) { -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/deoptimization.hpp openjdk/hotspot/src/share/vm/runtime/deoptimization.hpp ---- openjdk6/hotspot/src/share/vm/runtime/deoptimization.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/deoptimization.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)deoptimization.hpp 1.91 07/05/05 17:06:46 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -27,6 +24,8 @@ - - class ProfileData; - class vframeArray; -+class MonitorValue; -+class ObjectValue; - - class Deoptimization : AllStatic { - public: -@@ -100,8 +99,18 @@ - // executing in a particular CodeBlob if UseBiasedLocking is enabled - static void revoke_biases_of_monitors(CodeBlob* cb); - -+#ifdef COMPILER2 -+ // Support for restoring non-escaping objects -+ static bool realloc_objects(JavaThread* thread, frame* fr, GrowableArray* objects, TRAPS); -+ static void reassign_type_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, typeArrayOop obj, BasicType type); -+ static void reassign_object_array_elements(frame* fr, RegisterMap* reg_map, ObjectValue* sv, objArrayOop obj); -+ static void reassign_fields(frame* fr, RegisterMap* reg_map, GrowableArray* objects); -+ static void relock_objects(frame* fr, RegisterMap* reg_map, GrowableArray* monitors); -+ NOT_PRODUCT(static void print_objects(GrowableArray* objects);) -+#endif // COMPILER2 -+ - public: -- static vframeArray* create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map); -+ static vframeArray* create_vframeArray(JavaThread* thread, frame fr, RegisterMap *reg_map, GrowableArray* chunk); - - // Interface used for unpacking deoptimized frames - -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/extendedPC.hpp openjdk/hotspot/src/share/vm/runtime/extendedPC.hpp ---- openjdk6/hotspot/src/share/vm/runtime/extendedPC.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/extendedPC.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)extendedPC.hpp 1.17 07/05/05 17:06:46 JVM" --#endif - /* - * Copyright 1998-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/fieldDescriptor.cpp openjdk/hotspot/src/share/vm/runtime/fieldDescriptor.cpp ---- openjdk6/hotspot/src/share/vm/runtime/fieldDescriptor.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/fieldDescriptor.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)fieldDescriptor.cpp 1.56 07/05/05 17:06:46 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/fieldDescriptor.hpp openjdk/hotspot/src/share/vm/runtime/fieldDescriptor.hpp ---- openjdk6/hotspot/src/share/vm/runtime/fieldDescriptor.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/fieldDescriptor.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)fieldDescriptor.hpp 1.46 07/05/05 17:06:47 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/fieldType.cpp openjdk/hotspot/src/share/vm/runtime/fieldType.cpp ---- openjdk6/hotspot/src/share/vm/runtime/fieldType.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/fieldType.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)fieldType.cpp 1.27 07/05/05 17:06:47 JVM" --#endif - /* - * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -93,4 +90,3 @@ - *dimension = dim; - return element_type; - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/fieldType.hpp openjdk/hotspot/src/share/vm/runtime/fieldType.hpp ---- openjdk6/hotspot/src/share/vm/runtime/fieldType.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/fieldType.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)fieldType.hpp 1.28 07/05/05 17:06:47 JVM" --#endif - /* - * Copyright 1997-2002 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -53,4 +50,3 @@ - // Parse field and extract array information. Works for T_ARRAY only. - static BasicType get_array_info(symbolOop signature, jint* dimension, symbolOop *object_key, TRAPS); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/fprofiler.cpp openjdk/hotspot/src/share/vm/runtime/fprofiler.cpp ---- openjdk6/hotspot/src/share/vm/runtime/fprofiler.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/fprofiler.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)fprofiler.cpp 1.136 07/05/05 17:06:47 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -927,16 +924,6 @@ - FlatProfiler::record_thread_ticks(); - } - --inline bool is_valid_method(methodOop method) { -- if (method == NULL || -- !method->is_perm() || -- oop(method)->klass() != Universe::methodKlassObj() || -- !method->is_method()) { -- return false; // doesn't look good -- } -- return true; // hopefully this is a method indeed --} -- - void ThreadProfiler::record_interpreted_tick(frame fr, TickPosition where, int* ticks) { - FlatProfiler::all_int_ticks++; - if (!FlatProfiler::full_profile()) { -@@ -954,7 +941,7 @@ - if (fr.fp() != NULL) { - method = *fr.interpreter_frame_method_addr(); - } -- if (!is_valid_method(method)) { -+ if (!Universe::heap()->is_valid_method(method)) { - // tick came at a bad time, stack frame not initialized correctly - interpreter_ticks += 1; - FlatProfiler::interpreter_ticks += 1; -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/fprofiler.hpp openjdk/hotspot/src/share/vm/runtime/fprofiler.hpp ---- openjdk6/hotspot/src/share/vm/runtime/fprofiler.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/fprofiler.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)fprofiler.hpp 1.54 07/05/05 17:06:47 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -27,6 +24,7 @@ - - // a simple flat profiler for Java - -+ - // Forward declaration of classes defined in this header file - class ThreadProfiler; - class ThreadProfilerMark; -@@ -50,14 +48,16 @@ - // For now, the only thread-specific region is the class loader. - enum Region { noRegion, classLoaderRegion, extraRegion, maxRegion }; - -- ThreadProfilerMark(Region); -- ~ThreadProfilerMark(); -+ ThreadProfilerMark(Region) KERNEL_RETURN; -+ ~ThreadProfilerMark() KERNEL_RETURN; - - private: - ThreadProfiler* _pp; - Region _r; - }; - -+#ifndef FPROF_KERNEL -+ - class IntervalData VALUE_OBJ_CLASS_SPEC { - // Just to keep these things all together - private: -@@ -102,27 +102,29 @@ - static void print_header(outputStream* st); - void print_data(outputStream* st); - }; -+#endif // FPROF_KERNEL - - class ThreadProfiler: public CHeapObj { - public: -- ThreadProfiler(); -- ~ThreadProfiler(); -+ ThreadProfiler() KERNEL_RETURN; -+ ~ThreadProfiler() KERNEL_RETURN; - - // Resets the profiler -- void reset(); -+ void reset() KERNEL_RETURN; - - // Activates the profiler for a certain thread -- void engage(); -+ void engage() KERNEL_RETURN; - - // Deactivates the profiler -- void disengage(); -+ void disengage() KERNEL_RETURN; - - // Prints the collected profiling information -- void print(const char* thread_name); -+ void print(const char* thread_name) KERNEL_RETURN; - - // Garbage Collection Support -- void oops_do(OopClosure* f); -+ void oops_do(OopClosure* f) KERNEL_RETURN; - -+#ifndef FPROF_KERNEL - private: - // for recording ticks. - friend class ProfilerNode; -@@ -206,26 +208,45 @@ - IntervalData* interval_data_ref() { - return &_interval_data; - } -+#endif // FPROF_KERNEL - }; - - class FlatProfiler: AllStatic { - public: -- static void reset(); -- static void engage(JavaThread* mainThread, bool fullProfile); -- static void disengage(); -- static void print(int unused); -- static bool is_active(); -- static bool full_profile() { -- return full_profile_flag; -- } -+ static void reset() KERNEL_RETURN ; -+ static void engage(JavaThread* mainThread, bool fullProfile) KERNEL_RETURN ; -+ static void disengage() KERNEL_RETURN ; -+ static void print(int unused) KERNEL_RETURN ; -+ static bool is_active() KERNEL_RETURN_(return false;) ; - - // This is NULL if each thread has its own thread profiler, - // else this is the single thread profiler used by all threads. - // In particular it makes a difference during garbage collection, - // where you only want to traverse each thread profiler once. -- static ThreadProfiler* get_thread_profiler(); -+ static ThreadProfiler* get_thread_profiler() KERNEL_RETURN_(return NULL;); -+ -+ // Garbage Collection Support -+ static void oops_do(OopClosure* f) KERNEL_RETURN ; -+ -+ // Support for disassembler to inspect the PCRecorder -+ -+ // Returns the start address for a given pc -+ // NULL is returned if the PCRecorder is inactive -+ static address bucket_start_for(address pc) KERNEL_RETURN_(return NULL;); -+ -+ enum { MillisecsPerTick = 10 }; // ms per profiling ticks -+ -+ // Returns the number of ticks recorded for the bucket -+ // pc belongs to. -+ static int bucket_count_for(address pc) KERNEL_RETURN_(return 0;); -+ -+#ifndef FPROF_KERNEL - - private: -+ static bool full_profile() { -+ return full_profile_flag; -+ } -+ - friend class ThreadProfiler; - // the following group of ticks cover everything that's not attributed to individual Java methods - static int received_gc_ticks; // ticks during which gc was active -@@ -278,24 +299,6 @@ - static void record_vm_tick(); - static void record_thread_ticks(); - -- public: -- enum { MillisecsPerTick = 10 }; // ms per profiling ticks -- -- // Garbage Collection Support -- public: -- static void oops_do(OopClosure* f); -- -- public: -- // Support for disassembler to inspect the PCRecorder -- -- // Returns the start address for a given pc -- // NULL is returned if the PCRecorder is inactive -- static address bucket_start_for(address pc); -- -- // Returns the number of ticks recorded for the bucket -- // pc belongs to. -- static int bucket_count_for(address pc); -- - // For interval analysis - private: - static int interval_ticks_previous; // delivered_ticks from the last interval -@@ -304,6 +307,5 @@ - static void interval_reset(); // reset interval data. - enum {interval_print_size = 10}; - static IntervalData* interval_data; -+#endif // FPROF_KERNEL - }; -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/frame.cpp openjdk/hotspot/src/share/vm/runtime/frame.cpp ---- openjdk6/hotspot/src/share/vm/runtime/frame.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/frame.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)frame.cpp 1.233 07/05/05 17:06:44 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -524,7 +521,7 @@ - NOT_PRODUCT(address begin = pc()-40;) - NOT_PRODUCT(address end = NULL;) - -- st->print("%s frame (sp=" INTPTR_FORMAT, print_name(), sp()); -+ st->print("%s frame (sp=" INTPTR_FORMAT " unextended sp=" INTPTR_FORMAT, print_name(), sp(), unextended_sp()); - if (sp() != NULL) - st->print(", fp=" INTPTR_FORMAT ", pc=" INTPTR_FORMAT, fp(), pc()); - -@@ -676,7 +673,23 @@ - - void frame::print_on_error(outputStream* st, char* buf, int buflen, bool verbose) const { - if (_cb != NULL) { -- if (_cb->is_buffer_blob()) { -+ if (Interpreter::contains(pc())) { -+ methodOop m = this->interpreter_frame_method(); -+ if (m != NULL) { -+ m->name_and_sig_as_C_string(buf, buflen); -+ st->print("j %s", buf); -+ st->print("+%d", this->interpreter_frame_bci()); -+ } else { -+ st->print("j " PTR_FORMAT, pc()); -+ } -+ } else if (StubRoutines::contains(pc())) { -+ StubCodeDesc* desc = StubCodeDesc::desc_for(pc()); -+ if (desc != NULL) { -+ st->print("v ~StubRoutines::%s", desc->name()); -+ } else { -+ st->print("v ~StubRoutines::" PTR_FORMAT, pc()); -+ } -+ } else if (_cb->is_buffer_blob()) { - st->print("v ~BufferBlob::%s", ((BufferBlob *)_cb)->name()); - } else if (_cb->is_nmethod()) { - methodOop m = ((nmethod *)_cb)->method(); -@@ -697,24 +710,6 @@ - } else { - st->print("v blob " PTR_FORMAT, pc()); - } -- } else if (!is_init_completed()) { -- print_C_frame(st, buf, buflen, pc()); -- } else if (Interpreter::contains(pc())) { -- methodOop m = this->interpreter_frame_method(); -- if (m != NULL) { -- m->name_and_sig_as_C_string(buf, buflen); -- st->print("j %s", buf); -- st->print("+%d", this->interpreter_frame_bci()); -- } else { -- st->print("j " PTR_FORMAT, pc()); -- } -- } else if (StubRoutines::contains(pc())) { -- StubCodeDesc* desc = StubCodeDesc::desc_for(pc()); -- if (desc != NULL) { -- st->print("v ~StubRoutines::%s", desc->name()); -- } else { -- st->print("v ~StubRoutines::" PTR_FORMAT, pc()); -- } - } else { - print_C_frame(st, buf, buflen, pc()); - } -@@ -900,7 +895,7 @@ - // Interpreter frame in the midst of a call have a methodOop within the - // object. - interpreterState istate = get_interpreterState(); -- if (istate->msg() == cInterpreter::call_method) { -+ if (istate->msg() == BytecodeInterpreter::call_method) { - f->do_oop((oop*)&istate->_result._to_call._callee); - } - -@@ -1411,4 +1406,3 @@ - _fr = thread->last_frame(); - _is_done = false; - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/frame.hpp openjdk/hotspot/src/share/vm/runtime/frame.hpp ---- openjdk6/hotspot/src/share/vm/runtime/frame.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/frame.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)frame.hpp 1.163 07/05/05 17:06:42 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -25,9 +22,7 @@ - * - */ - --#ifdef CC_INTERP --typedef class cInterpreter* interpreterState; --#endif /* CC_INTERP */ -+typedef class BytecodeInterpreter* interpreterState; - - class CodeBlob; - -@@ -41,9 +36,7 @@ - class frame VALUE_OBJ_CLASS_SPEC { - private: - // Instance variables: --#ifndef CC_INTERP - intptr_t* _sp; // stack pointer (from Thread::last_Java_sp) --#endif // !CC_INTERP - address _pc; // program counter (the next instruction after the call) - - CodeBlob* _cb; // CodeBlob that "owns" pc -@@ -73,10 +66,9 @@ - address raw_pc() const; - - void set_pc( address newpc ); --#ifndef CC_INTERP -- void set_sp( intptr_t* newsp ) { _sp = newsp; } -+ - intptr_t* sp() const { return _sp; } --#endif // !CC_INTERP -+ void set_sp( intptr_t* newsp ) { _sp = newsp; } - - - CodeBlob* cb() const { return _cb; } -@@ -279,7 +271,12 @@ - jint interpreter_frame_expression_stack_size() const; - - intptr_t* interpreter_frame_sender_sp() const; -+ -+#ifndef CC_INTERP -+ // template based interpreter deoptimization support - void set_interpreter_frame_sender_sp(intptr_t* sender_sp); -+ void interpreter_frame_set_monitor_end(BasicObjectLock* value); -+#endif // CC_INTERP - - // BasicObjectLocks: - // -@@ -296,7 +293,6 @@ - BasicObjectLock* previous_monitor_in_interpreter_frame(BasicObjectLock* current) const; - static int interpreter_frame_monitor_size(); - -- void interpreter_frame_set_monitor_end(BasicObjectLock* value); - void interpreter_frame_verify_monitor(BasicObjectLock* value) const; - - // Tells whether the current interpreter_frame frame pointer -@@ -471,4 +467,3 @@ - frame *current() { return &_fr; } - RegisterMap* register_map() { return &_reg_map; } - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/frame.inline.hpp openjdk/hotspot/src/share/vm/runtime/frame.inline.hpp ---- openjdk6/hotspot/src/share/vm/runtime/frame.inline.hpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/frame.inline.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)frame.inline.hpp 1.23 07/05/05 17:06:47 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/globals.cpp openjdk/hotspot/src/share/vm/runtime/globals.cpp ---- openjdk6/hotspot/src/share/vm/runtime/globals.cpp 2008-07-10 22:04:35.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/globals.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)globals.cpp 1.49 07/05/17 16:05:26 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -337,7 +334,7 @@ - char* new_value = NEW_C_HEAP_ARRAY(char, strlen(*value)+1); - strcpy(new_value, *value); - result->set_ccstr(new_value); -- if (result->origin == DEFAULT) { -+ if (result->origin == DEFAULT && old_value != NULL) { - // Prior value is NOT heap allocated, but was a literal constant. - char* old_value_to_free = NEW_C_HEAP_ARRAY(char, strlen(old_value)+1); - strcpy(old_value_to_free, old_value); -@@ -356,7 +353,7 @@ - char* new_value = NEW_C_HEAP_ARRAY(char, strlen(value)+1); - strcpy(new_value, value); - faddr->set_ccstr(new_value); -- if (faddr->origin != DEFAULT) { -+ if (faddr->origin != DEFAULT && old_value != NULL) { - // Prior value is heap allocated so free it. - FREE_C_HEAP_ARRAY(char, old_value); - } -@@ -430,4 +427,3 @@ - } - - #endif -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/globals.hpp openjdk/hotspot/src/share/vm/runtime/globals.hpp ---- openjdk6/hotspot/src/share/vm/runtime/globals.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/globals.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)globals.hpp 1.967 07/07/13 14:51:27 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -61,6 +58,7 @@ - define_pd_global(uintx,PermSize, ScaleForWordSize(4*M)); - define_pd_global(uintx,MaxPermSize, ScaleForWordSize(64*M)); - define_pd_global(bool, NeverActAsServerClassMachine, true); -+define_pd_global(uintx, DefaultMaxRAM, 1*G); - #define CI_COMPILER_COUNT 0 - #else - -@@ -73,7 +71,9 @@ - #endif // no compilers - - --typedef const char* ccstr; // string type alias used only in this file -+// string type aliases used only in this file -+typedef const char* ccstr; -+typedef const char* ccstrlist; // represents string arguments which accumulate - - enum FlagValueOrigin { - DEFAULT = 0, -@@ -117,7 +117,8 @@ - double get_double() const { return *((double*) addr); } - void set_double(double value) { *((double*) addr) = value; } - -- bool is_ccstr() const { return strcmp(type, "ccstr") == 0; } -+ bool is_ccstr() const { return strcmp(type, "ccstr") == 0 || strcmp(type, "ccstrlist") == 0; } -+ bool ccstr_accumulates() const { return strcmp(type, "ccstrlist") == 0; } - ccstr get_ccstr() const { return *((ccstr*) addr); } - void set_ccstr(ccstr value) { *((ccstr*) addr) = value; } - -@@ -305,6 +306,9 @@ - product_pd(bool, UseLargePages, \ - "Use large page memory") \ - \ -+ develop(bool, TracePageSizes, false, \ -+ "Trace page size selection and usage.") \ -+ \ - product(bool, UseNUMA, false, \ - "Use NUMA if available") \ - \ -@@ -389,6 +393,9 @@ - develop(bool, VerifyStack, false, \ - "Verify stack of each thread when it is entering a runtime call") \ - \ -+ develop(bool, ForceUnreachable, false, \ -+ "(amd64) Make all non code cache addresses to be unreachable with rip-rel forcing use of 64bit literal fixups") \ -+ \ - notproduct(bool, StressDerivedPointers, false, \ - "Force scavenge when a derived pointers is detected on stack " \ - "after rtm call") \ -@@ -459,7 +466,7 @@ - develop(bool, DeoptimizeALot, false, \ - "deoptimize at every exit from the runtime system") \ - \ -- develop(ccstr, DeoptimizeOnlyAt, "", \ -+ develop(ccstrlist, DeoptimizeOnlyAt, "", \ - "a comma separated list of bcis to deoptimize at") \ - \ - product(bool, DeoptimizeRandom, false, \ -@@ -497,7 +504,7 @@ - develop(bool, ShowSafepointMsgs, false, \ - "Show msg. about safepoint synch.") \ - \ -- develop(bool, SafepointTimeout, false, \ -+ product(bool, SafepointTimeout, false, \ - "Time out and warn or fail after SafepointTimeoutDelay " \ - "milliseconds if failed to reach safepoint") \ - \ -@@ -609,17 +616,17 @@ - product(bool, SuppressFatalErrorMessage, false, \ - "Do NO Fatal Error report [Avoid deadlock]") \ - \ -- product(ccstr, OnError, "", \ -+ product(ccstrlist, OnError, "", \ - "Run user-defined commands on fatal error; see VMError.cpp " \ - "for examples") \ - \ -- product(ccstr, OnOutOfMemoryError, "", \ -+ product(ccstrlist, OnOutOfMemoryError, "", \ - "Run user-defined commands on first java.lang.OutOfMemoryError") \ - \ - manageable(bool, HeapDumpOnOutOfMemoryError, false, \ - "Dump heap to file when java.lang.OutOfMemoryError is thrown") \ - \ -- manageable(ccstr, HeapDumpPath, "", \ -+ manageable(ccstr, HeapDumpPath, NULL, \ - "When HeapDumpOnOutOfMemoryError is on, the path (filename or" \ - "directory) of the dump file (defaults to java_pid.hprof" \ - "in the working directory)") \ -@@ -823,8 +830,6 @@ - product(intx, FenceInstruction, 0, \ - "(Unsafe,Unstable) Experimental") \ - \ -- product(intx, AppendRatio, 11, "(Unstable) Monitor queue fairness" ) \ -- \ - product(intx, SyncFlags, 0, "(Unsafe,Unstable) Experimental Sync flags" ) \ - \ - product(intx, SyncVerbose, 0, "(Unstable)" ) \ -@@ -842,6 +847,10 @@ - "Prevent spurious or premature wakeups from object.wait" \ - "(Solaris only)") \ - \ -+ product(intx, NativeMonitorTimeout, -1, "(Unstable)" ) \ -+ product(intx, NativeMonitorFlags, 0, "(Unstable)" ) \ -+ product(intx, NativeMonitorSpinLimit, 20, "(Unstable)" ) \ -+ \ - develop(bool, UsePthreads, false, \ - "Use pthread-based instead of libthread-based synchronization " \ - "(SPARC only)") \ -@@ -1063,7 +1072,7 @@ - develop(bool, TraceHPI, false, \ - "Trace Host Porting Interface (HPI)") \ - \ -- product(ccstr, HPILibPath, "", \ -+ product(ccstr, HPILibPath, NULL, \ - "Specify alternate path to HPI library") \ - \ - develop(bool, TraceProtectionDomainVerification, false, \ -@@ -1570,7 +1579,7 @@ - product(bool, AlwaysActAsServerClassMachine, false, \ - "Always act like a server-class machine") \ - \ -- product(uintx, DefaultMaxRAM, G, \ -+ product_pd(uintx, DefaultMaxRAM, \ - "Maximum real memory size for setting server class heap size") \ - \ - product(uintx, DefaultMaxRAMFraction, 4, \ -@@ -2029,7 +2038,7 @@ - diagnostic(bool, PrintIntrinsics, false, \ - "prints attempted and successful inlining of intrinsics") \ - \ -- diagnostic(ccstr, DisableIntrinsic, "", \ -+ diagnostic(ccstrlist, DisableIntrinsic, "", \ - "do not expand intrinsics whose (internal) names appear here") \ - \ - develop(bool, StressReflectiveCode, false, \ -@@ -2075,10 +2084,10 @@ - diagnostic(bool, LogVMOutput, trueInDebug, \ - "Save VM output to hotspot.log, or to LogFile") \ - \ -- diagnostic(ccstr, LogFile, "", \ -+ diagnostic(ccstr, LogFile, NULL, \ - "If LogVMOutput is on, save VM output to this file [hotspot.log]") \ - \ -- product(ccstr, ErrorFile, "", \ -+ product(ccstr, ErrorFile, NULL, \ - "If an error occurs, save the error data to this file " \ - "[default: ./hs_err_pid%p.log] (%p replaced with pid)") \ - \ -@@ -2098,7 +2107,7 @@ - "standard exit from VM if bytecode verify error " \ - "(only in debug mode)") \ - \ -- notproduct(ccstr, AbortVMOnException, "", \ -+ notproduct(ccstr, AbortVMOnException, NULL, \ - "Call fatal if this exception is thrown. Example: " \ - "java -XX:AbortVMOnException=java.lang.NullPointerException Foo") \ - \ -@@ -2205,9 +2214,6 @@ - develop(bool, CountCompiledCalls, false, \ - "counts method invocations") \ - \ -- notproduct(bool, CountVMLocks, false, \ -- "counts VM internal lock attempts and contention") \ -- \ - notproduct(bool, CountRuntimeCalls, false, \ - "counts VM runtime calls") \ - \ -@@ -2425,7 +2431,7 @@ - "Guarantee a safepoint (at least) every so many milliseconds " \ - "(0 means none)") \ - \ -- develop(intx, SafepointTimeoutDelay, 10000, \ -+ product(intx, SafepointTimeoutDelay, 10000, \ - "Delay in milliseconds for option SafepointTimeout") \ - \ - product(intx, NmethodSweepFraction, 4, \ -@@ -2441,7 +2447,7 @@ - "number of times to evaluate expression in assert " \ - "(to estimate overhead); only works with -DUSE_REPEATED_ASSERTS") \ - \ -- notproduct(ccstr, SuppressErrorAt, "", \ -+ notproduct(ccstrlist, SuppressErrorAt, "", \ - "List of assertions (file:line) to muzzle") \ - \ - notproduct(uintx, HandleAllocationLimit, 1024, \ -@@ -2744,6 +2750,9 @@ - "true: the scavenge order will be depth-first, " \ - "false: the scavenge order will be breadth-first") \ - \ -+ product(bool, PSChunkLargeArrays, true, \ -+ "true: process large arrays in chunks") \ -+ \ - product(uintx, GCDrainStackTargetSize, 64, \ - "how many entries we'll try to leave on the stack during " \ - "parallel GC") \ -@@ -2834,13 +2843,13 @@ - develop(intx, CIBreakAt, -1, \ - "id of compilation to break at") \ - \ -- product(ccstr, CompileOnly, "", \ -+ product(ccstrlist, CompileOnly, "", \ - "List of methods (pkg/class.name) to restrict compilation to") \ - \ -- product(ccstr, CompileCommandFile, "", \ -+ product(ccstr, CompileCommandFile, NULL, \ - "Read compiler commands from this file [.hotspot_compiler]") \ - \ -- product(ccstr, CompileCommand, "", \ -+ product(ccstrlist, CompileCommand, "", \ - "Prepend to .hotspot_compiler; e.g. log,java/lang/String.") \ - \ - product(bool, CICompilerCountPerCPU, false, \ -@@ -3033,7 +3042,7 @@ - product(bool, PerfDataSaveToFile, false, \ - "Save PerfData memory to hsperfdata_ file on exit") \ - \ -- product(ccstr, PerfDataSaveFile, "", \ -+ product(ccstr, PerfDataSaveFile, NULL, \ - "Save PerfData memory to the specified absolute pathname," \ - "%p in the file name if present will be replaced by pid") \ - \ -@@ -3134,7 +3143,7 @@ - "Causes the VM to pause at startup time and wait for the pause " \ - "file to be removed (default: ./vm.paused.)") \ - \ -- diagnostic(ccstr, PauseAtStartupFile, "", \ -+ diagnostic(ccstr, PauseAtStartupFile, NULL, \ - "The file to create and for whose removal to await when pausing " \ - "at startup. (default: ./vm.paused.)") \ - \ -@@ -3197,5 +3206,3 @@ - RUNTIME_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_NOTPRODUCT_FLAG, DECLARE_MANAGEABLE_FLAG, DECLARE_PRODUCT_RW_FLAG) - - RUNTIME_OS_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_NOTPRODUCT_FLAG) -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/globals_extension.hpp openjdk/hotspot/src/share/vm/runtime/globals_extension.hpp ---- openjdk6/hotspot/src/share/vm/runtime/globals_extension.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/globals_extension.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)globals_extension.hpp 1.17 07/05/17 16:05:46 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/handles.cpp openjdk/hotspot/src/share/vm/runtime/handles.cpp ---- openjdk6/hotspot/src/share/vm/runtime/handles.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/handles.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)handles.cpp 1.110 07/05/05 17:06:42 JVM" --#endif - /* - * Copyright 1997-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/handles.hpp openjdk/hotspot/src/share/vm/runtime/handles.hpp ---- openjdk6/hotspot/src/share/vm/runtime/handles.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/handles.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)handles.hpp 1.120 07/05/05 17:06:47 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -349,4 +346,3 @@ - ~ResetNoHandleMark() {} - #endif - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/handles.inline.hpp openjdk/hotspot/src/share/vm/runtime/handles.inline.hpp ---- openjdk6/hotspot/src/share/vm/runtime/handles.inline.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/handles.inline.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)handles.inline.hpp 1.28 07/05/05 17:06:48 JVM" --#endif - /* - * Copyright 1998-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/hpi.cpp openjdk/hotspot/src/share/vm/runtime/hpi.cpp ---- openjdk6/hotspot/src/share/vm/runtime/hpi.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/hpi.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)hpi.cpp 1.18 07/05/17 16:05:48 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/hpi.hpp openjdk/hotspot/src/share/vm/runtime/hpi.hpp ---- openjdk6/hotspot/src/share/vm/runtime/hpi.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/hpi.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)hpi.hpp 1.22 07/05/05 17:06:48 JVM" --#endif - /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/icache.cpp openjdk/hotspot/src/share/vm/runtime/icache.cpp ---- openjdk6/hotspot/src/share/vm/runtime/icache.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/icache.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)icache.cpp 1.23 07/05/05 17:06:49 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/icache.hpp openjdk/hotspot/src/share/vm/runtime/icache.hpp ---- openjdk6/hotspot/src/share/vm/runtime/icache.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/icache.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)icache.hpp 1.18 07/05/05 17:06:44 JVM" --#endif - /* - * Copyright 1997-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/init.cpp openjdk/hotspot/src/share/vm/runtime/init.cpp ---- openjdk6/hotspot/src/share/vm/runtime/init.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/init.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)init.cpp 1.122 07/05/23 10:54:05 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -85,6 +82,7 @@ - - - jint init_globals() { -+ HandleMark hm; - management_init(); - vtune_init(); - bytecodes_init(); -@@ -107,7 +105,9 @@ - universe2_init(); // dependent on codeCache_init and stubRoutines_init - referenceProcessor_init(); - jni_handles_init(); -+#ifndef VM_STRUCTS_KERNEL - vmStructs_init(); -+#endif // VM_STRUCTS_KERNEL - - vtableStubs_init(); - InlineCacheBuffer_init(); -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/init.hpp openjdk/hotspot/src/share/vm/runtime/init.hpp ---- openjdk6/hotspot/src/share/vm/runtime/init.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/init.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)init.hpp 1.19 07/05/05 17:06:49 JVM" --#endif - /* - * Copyright 1997-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/interfaceSupport.cpp openjdk/hotspot/src/share/vm/runtime/interfaceSupport.cpp ---- openjdk6/hotspot/src/share/vm/runtime/interfaceSupport.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/interfaceSupport.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)interfaceSupport.cpp 1.91 07/05/05 17:06:50 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -270,4 +267,3 @@ - } - #endif - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/interfaceSupport.hpp openjdk/hotspot/src/share/vm/runtime/interfaceSupport.hpp ---- openjdk6/hotspot/src/share/vm/runtime/interfaceSupport.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/interfaceSupport.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)interfaceSupport.hpp 1.176 07/05/17 16:05:52 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/java.cpp openjdk/hotspot/src/share/vm/runtime/java.cpp ---- openjdk6/hotspot/src/share/vm/runtime/java.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/java.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)java.cpp 1.221 07/05/29 09:44:26 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -144,13 +141,6 @@ - RuntimeHistogram->print(); - } - -- if (CountVMLocks) { -- extern Histogram *MutexHistogram; -- extern Histogram *MutexContentionHistogram; -- MutexHistogram->print(); -- MutexContentionHistogram->print(); -- } -- - if (CountJNICalls) { - extern Histogram *JNIHistogram; - JNIHistogram->print(); -@@ -438,6 +428,7 @@ - // Always call even when there are not JVMTI environments yet, since environments - // may be attached late and JVMTI must track phases of VM execution - JvmtiExport::post_vm_death(); -+ Threads::shutdown_vm_agents(); - - // Terminate the signal thread - // Note: we don't wait until it actually dies. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/java.hpp openjdk/hotspot/src/share/vm/runtime/java.hpp ---- openjdk6/hotspot/src/share/vm/runtime/java.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/java.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)java.hpp 1.36 07/05/05 17:06:49 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -72,6 +69,7 @@ - static bool is_jdk14x_version() { assert(is_jdk_version_initialized(), "must have been initialized"); return _jdk_version == 4; } - static bool is_jdk15x_version() { assert(is_jdk_version_initialized(), "must have been initialized"); return _jdk_version == 5; } - static bool is_jdk16x_version() { assert(is_jdk_version_initialized(), "must have been initialized"); return _jdk_version == 6; } -+ static bool is_jdk17x_version() { assert(is_jdk_version_initialized(), "must have been initialized"); return _jdk_version == 7; } - - static bool supports_thread_park_blocker() { return _version_info.thread_park_blocker; } - -@@ -87,9 +85,16 @@ - } - static bool is_gte_jdk16x_version() { - // Keep the semantics of this that the version number is >= 1.6 -+ assert(is_jdk_version_initialized(), "Not initialized"); - return _jdk_version >= 6; - } - -+ static bool is_gte_jdk17x_version() { -+ // Keep the semantics of this that the version number is >= 1.7 -+ assert(is_jdk_version_initialized(), "Not initialized"); -+ return _jdk_version >= 7; -+ } -+ - static bool is_jdk_version_initialized() { - return _jdk_version > 0; - } -@@ -116,5 +121,3 @@ - _version_info.jdk_version = (1 << 24) | (5 << 16); - } - }; -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/javaCalls.cpp openjdk/hotspot/src/share/vm/runtime/javaCalls.cpp ---- openjdk6/hotspot/src/share/vm/runtime/javaCalls.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/javaCalls.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)javaCalls.cpp 1.220 07/05/05 17:06:51 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/javaCalls.hpp openjdk/hotspot/src/share/vm/runtime/javaCalls.hpp ---- openjdk6/hotspot/src/share/vm/runtime/javaCalls.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/javaCalls.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)javaCalls.hpp 1.81 07/05/05 17:06:47 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -196,4 +193,3 @@ - // Low-level interface - static void call(JavaValue* result, methodHandle method, JavaCallArguments* args, TRAPS); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/javaFrameAnchor.hpp openjdk/hotspot/src/share/vm/runtime/javaFrameAnchor.hpp ---- openjdk6/hotspot/src/share/vm/runtime/javaFrameAnchor.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/javaFrameAnchor.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)javaFrameAnchor.hpp 1.16 07/05/05 17:06:50 JVM" --#endif - /* - * Copyright 2002-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -44,7 +41,7 @@ - friend class JavaThread; - friend class frame; - friend class VMStructs; --friend class cInterpreter; -+friend class BytecodeInterpreter; - friend class JavaCallWrapper; - - private: -@@ -88,4 +85,3 @@ - static ByteSize last_Java_pc_offset() { return byte_offset_of(JavaFrameAnchor, _last_Java_pc); } - - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/jfieldIDWorkaround.hpp openjdk/hotspot/src/share/vm/runtime/jfieldIDWorkaround.hpp ---- openjdk6/hotspot/src/share/vm/runtime/jfieldIDWorkaround.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/jfieldIDWorkaround.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)jfieldIDWorkaround.hpp 1.11 07/05/05 17:06:51 JVM" --#endif - /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/jniHandles.cpp openjdk/hotspot/src/share/vm/runtime/jniHandles.cpp ---- openjdk6/hotspot/src/share/vm/runtime/jniHandles.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/jniHandles.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)jniHandles.cpp 1.64 07/05/17 16:06:13 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/jniHandles.hpp openjdk/hotspot/src/share/vm/runtime/jniHandles.hpp ---- openjdk6/hotspot/src/share/vm/runtime/jniHandles.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/jniHandles.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)jniHandles.hpp 1.54 07/05/17 16:06:14 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -213,5 +210,3 @@ - *((oop*)handle) = deleted_handle(); // Mark the handle as deleted, allocate will reuse it - } - } -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/jniPeriodicChecker.cpp openjdk/hotspot/src/share/vm/runtime/jniPeriodicChecker.cpp ---- openjdk6/hotspot/src/share/vm/runtime/jniPeriodicChecker.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/jniPeriodicChecker.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)jniPeriodicChecker.cpp 1.4 07/05/05 17:06:51 JVM" --#endif - /* - * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/jniPeriodicChecker.hpp openjdk/hotspot/src/share/vm/runtime/jniPeriodicChecker.hpp ---- openjdk6/hotspot/src/share/vm/runtime/jniPeriodicChecker.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/jniPeriodicChecker.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)jniPeriodicChecker.hpp 1.4 07/05/05 17:06:51 JVM" --#endif - /* - * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/memprofiler.cpp openjdk/hotspot/src/share/vm/runtime/memprofiler.cpp ---- openjdk6/hotspot/src/share/vm/runtime/memprofiler.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/memprofiler.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)memprofiler.cpp 1.24 07/05/05 17:06:52 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/memprofiler.hpp openjdk/hotspot/src/share/vm/runtime/memprofiler.hpp ---- openjdk6/hotspot/src/share/vm/runtime/memprofiler.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/memprofiler.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)memprofiler.hpp 1.17 07/05/05 17:06:52 JVM" --#endif - /* - * Copyright 1998 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/monitorChunk.cpp openjdk/hotspot/src/share/vm/runtime/monitorChunk.cpp ---- openjdk6/hotspot/src/share/vm/runtime/monitorChunk.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/monitorChunk.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)monitorChunk.cpp 1.19 07/05/05 17:06:52 JVM" --#endif - /* - * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -45,4 +42,3 @@ - at(index)->oops_do(f); - } - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/monitorChunk.hpp openjdk/hotspot/src/share/vm/runtime/monitorChunk.hpp ---- openjdk6/hotspot/src/share/vm/runtime/monitorChunk.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/monitorChunk.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)monitorChunk.hpp 1.19 07/05/05 17:06:52 JVM" --#endif - /* - * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/mutex.cpp openjdk/hotspot/src/share/vm/runtime/mutex.cpp ---- openjdk6/hotspot/src/share/vm/runtime/mutex.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/mutex.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,4 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)mutex.cpp 1.60 07/05/05 17:06:43 JVM" --#endif -+ - /* - * Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -28,63 +26,808 @@ - # include "incls/_precompiled.incl" - # include "incls/_mutex.cpp.incl" - --#ifdef ASSERT --Histogram* MutexHistogram; --static volatile jint MutexHistogram_lock = 0; --Histogram* MutexContentionHistogram; --static volatile jint MutexContentionHistogram_lock = 0; -+// o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o -+// -+// Native Monitor-Mutex locking - theory of operations -+// -+// * Native Monitors are completely unrelated to Java-level monitors, -+// although the "back-end" slow-path implementations share a common lineage. -+// See objectMonitor:: in synchronizer.cpp. -+// Native Monitors do *not* support nesting or recursion but otherwise -+// they're basically Hoare-flavor monitors. -+// -+// * A thread acquires ownership of a Monitor/Mutex by CASing the LockByte -+// in the _LockWord from zero to non-zero. Note that the _Owner field -+// is advisory and is used only to verify that the thread calling unlock() -+// is indeed the last thread to have acquired the lock. -+// -+// * Contending threads "push" themselves onto the front of the contention -+// queue -- called the cxq -- with CAS and then spin/park. -+// The _LockWord contains the LockByte as well as the pointer to the head -+// of the cxq. Colocating the LockByte with the cxq precludes certain races. -+// -+// * Using a separately addressable LockByte allows for CAS:MEMBAR or CAS:0 -+// idioms. We currently use MEMBAR in the uncontended unlock() path, as -+// MEMBAR often has less latency than CAS. If warranted, we could switch to -+// a CAS:0 mode, using timers to close the resultant race, as is done -+// with Java Monitors in synchronizer.cpp. -+// -+// See the following for a discussion of the relative cost of atomics (CAS) -+// MEMBAR, and ways to eliminate such instructions from the common-case paths: -+// -- http://blogs.sun.com/dave/entry/biased_locking_in_hotspot -+// -- http://blogs.sun.com/dave/resource/MustangSync.pdf -+// -- http://blogs.sun.com/dave/resource/synchronization-public2.pdf -+// -- synchronizer.cpp -+// -+// * Overall goals - desiderata -+// 1. Minimize context switching -+// 2. Minimize lock migration -+// 3. Minimize CPI -- affinity and locality -+// 4. Minimize the execution of high-latency instructions such as CAS or MEMBAR -+// 5. Minimize outer lock hold times -+// 6. Behave gracefully on a loaded system -+// -+// * Thread flow and list residency: -+// -+// Contention queue --> EntryList --> OnDeck --> Owner --> !Owner -+// [..resident on monitor list..] -+// [...........contending..................] -+// -+// -- The contention queue (cxq) contains recently-arrived threads (RATs). -+// Threads on the cxq eventually drain into the EntryList. -+// -- Invariant: a thread appears on at most one list -- cxq, EntryList -+// or WaitSet -- at any one time. -+// -- For a given monitor there can be at most one "OnDeck" thread at any -+// given time but if needbe this particular invariant could be relaxed. -+// -+// * The WaitSet and EntryList linked lists are composed of ParkEvents. -+// I use ParkEvent instead of threads as ParkEvents are immortal and -+// type-stable, meaning we can safely unpark() a possibly stale -+// list element in the unlock()-path. (That's benign). -+// -+// * Succession policy - providing for progress: -+// -+// As necessary, the unlock()ing thread identifies, unlinks, and unparks -+// an "heir presumptive" tentative successor thread from the EntryList. -+// This becomes the so-called "OnDeck" thread, of which there can be only -+// one at any given time for a given monitor. The wakee will recontend -+// for ownership of monitor. -+// -+// Succession is provided for by a policy of competitive handoff. -+// The exiting thread does _not_ grant or pass ownership to the -+// successor thread. (This is also referred to as "handoff" succession"). -+// Instead the exiting thread releases ownership and possibly wakes -+// a successor, so the successor can (re)compete for ownership of the lock. -+// -+// Competitive handoff provides excellent overall throughput at the expense -+// of short-term fairness. If fairness is a concern then one remedy might -+// be to add an AcquireCounter field to the monitor. After a thread acquires -+// the lock it will decrement the AcquireCounter field. When the count -+// reaches 0 the thread would reset the AcquireCounter variable, abdicate -+// the lock directly to some thread on the EntryList, and then move itself to the -+// tail of the EntryList. -+// -+// But in practice most threads engage or otherwise participate in resource -+// bounded producer-consumer relationships, so lock domination is not usually -+// a practical concern. Recall too, that in general it's easier to construct -+// a fair lock from a fast lock, but not vice-versa. -+// -+// * The cxq can have multiple concurrent "pushers" but only one concurrent -+// detaching thread. This mechanism is immune from the ABA corruption. -+// More precisely, the CAS-based "push" onto cxq is ABA-oblivious. -+// We use OnDeck as a pseudo-lock to enforce the at-most-one detaching -+// thread constraint. -+// -+// * Taken together, the cxq and the EntryList constitute or form a -+// single logical queue of threads stalled trying to acquire the lock. -+// We use two distinct lists to reduce heat on the list ends. -+// Threads in lock() enqueue onto cxq while threads in unlock() will -+// dequeue from the EntryList. (c.f. Michael Scott's "2Q" algorithm). -+// A key desideratum is to minimize queue & monitor metadata manipulation -+// that occurs while holding the "outer" monitor lock -- that is, we want to -+// minimize monitor lock holds times. -+// -+// The EntryList is ordered by the prevailing queue discipline and -+// can be organized in any convenient fashion, such as a doubly-linked list or -+// a circular doubly-linked list. If we need a priority queue then something akin -+// to Solaris' sleepq would work nicely. Viz., -+// -- http://agg.eng/ws/on10_nightly/source/usr/src/uts/common/os/sleepq.c. -+// -- http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/os/sleepq.c -+// Queue discipline is enforced at ::unlock() time, when the unlocking thread -+// drains the cxq into the EntryList, and orders or reorders the threads on the -+// EntryList accordingly. -+// -+// Barring "lock barging", this mechanism provides fair cyclic ordering, -+// somewhat similar to an elevator-scan. -+// -+// * OnDeck -+// -- For a given monitor there can be at most one OnDeck thread at any given -+// instant. The OnDeck thread is contending for the lock, but has been -+// unlinked from the EntryList and cxq by some previous unlock() operations. -+// Once a thread has been designated the OnDeck thread it will remain so -+// until it manages to acquire the lock -- being OnDeck is a stable property. -+// -- Threads on the EntryList or cxq are _not allowed to attempt lock acquisition. -+// -- OnDeck also serves as an "inner lock" as follows. Threads in unlock() will, after -+// having cleared the LockByte and dropped the outer lock, attempt to "trylock" -+// OnDeck by CASing the field from null to non-null. If successful, that thread -+// is then responsible for progress and succession and can use CAS to detach and -+// drain the cxq into the EntryList. By convention, only this thread, the holder of -+// the OnDeck inner lock, can manipulate the EntryList or detach and drain the -+// RATs on the cxq into the EntryList. This avoids ABA corruption on the cxq as -+// we allow multiple concurrent "push" operations but restrict detach concurrency -+// to at most one thread. Having selected and detached a successor, the thread then -+// changes the OnDeck to refer to that successor, and then unparks the successor. -+// That successor will eventually acquire the lock and clear OnDeck. Beware -+// that the OnDeck usage as a lock is asymmetric. A thread in unlock() transiently -+// "acquires" OnDeck, performs queue manipulations, passes OnDeck to some successor, -+// and then the successor eventually "drops" OnDeck. Note that there's never -+// any sense of contention on the inner lock, however. Threads never contend -+// or wait for the inner lock. -+// -- OnDeck provides for futile wakeup throttling a described in section 3.3 of -+// See http://www.usenix.org/events/jvm01/full_papers/dice/dice.pdf -+// In a sense, OnDeck subsumes the ObjectMonitor _Succ and ObjectWaiter -+// TState fields found in Java-level objectMonitors. (See synchronizer.cpp). -+// -+// * Waiting threads reside on the WaitSet list -- wait() puts -+// the caller onto the WaitSet. Notify() or notifyAll() simply -+// transfers threads from the WaitSet to either the EntryList or cxq. -+// Subsequent unlock() operations will eventually unpark the notifyee. -+// Unparking a notifee in notify() proper is inefficient - if we were to do so -+// it's likely the notifyee would simply impale itself on the lock held -+// by the notifier. -+// -+// * The mechanism is obstruction-free in that if the holder of the transient -+// OnDeck lock in unlock() is preempted or otherwise stalls, other threads -+// can still acquire and release the outer lock and continue to make progress. -+// At worst, waking of already blocked contending threads may be delayed, -+// but nothing worse. (We only use "trylock" operations on the inner OnDeck -+// lock). -+// -+// * Note that thread-local storage must be initialized before a thread -+// uses Native monitors or mutexes. The native monitor-mutex subsystem -+// depends on Thread::current(). -+// -+// * The monitor synchronization subsystem avoids the use of native -+// synchronization primitives except for the narrow platform-specific -+// park-unpark abstraction. See the comments in os_solaris.cpp regarding -+// the semantics of park-unpark. Put another way, this monitor implementation -+// depends only on atomic operations and park-unpark. The monitor subsystem -+// manages all RUNNING->BLOCKED and BLOCKED->READY transitions while the -+// underlying OS manages the READY<->RUN transitions. -+// -+// * The memory consistency model provide by lock()-unlock() is at least as -+// strong or stronger than the Java Memory model defined by JSR-133. -+// That is, we guarantee at least entry consistency, if not stronger. -+// See http://g.oswego.edu/dl/jmm/cookbook.html. -+// -+// * Thread:: currently contains a set of purpose-specific ParkEvents: -+// _MutexEvent, _ParkEvent, etc. A better approach might be to do away with -+// the purpose-specific ParkEvents and instead implement a general per-thread -+// stack of available ParkEvents which we could provision on-demand. The -+// stack acts as a local cache to avoid excessive calls to ParkEvent::Allocate() -+// and ::Release(). A thread would simply pop an element from the local stack before it -+// enqueued or park()ed. When the contention was over the thread would -+// push the no-longer-needed ParkEvent back onto its stack. -+// -+// * A slightly reduced form of ILock() and IUnlock() have been partially -+// model-checked (Murphi) for safety and progress at T=1,2,3 and 4. -+// It'd be interesting to see if TLA/TLC could be useful as well. -+// -+// * Mutex-Monitor is a low-level "leaf" subsystem. That is, the monitor -+// code should never call other code in the JVM that might itself need to -+// acquire monitors or mutexes. That's true *except* in the case of the -+// ThreadBlockInVM state transition wrappers. The ThreadBlockInVM DTOR handles -+// mutator reentry (ingress) by checking for a pending safepoint in which case it will -+// call SafepointSynchronize::block(), which in turn may call Safepoint_lock->lock(), etc. -+// In that particular case a call to lock() for a given Monitor can end up recursively -+// calling lock() on another monitor. While distasteful, this is largely benign -+// as the calls come from jacket that wraps lock(), and not from deep within lock() itself. -+// -+// It's unfortunate that native mutexes and thread state transitions were convolved. -+// They're really separate concerns and should have remained that way. Melding -+// them together was facile -- a bit too facile. The current implementation badly -+// conflates the two concerns. -+// -+// * TODO-FIXME: -+// -+// -- Add DTRACE probes for contended acquire, contended acquired, contended unlock -+// We should also add DTRACE probes in the ParkEvent subsystem for -+// Park-entry, Park-exit, and Unpark. -+// -+// -- We have an excess of mutex-like constructs in the JVM, namely: -+// 1. objectMonitors for Java-level synchronization (synchronizer.cpp) -+// 2. low-level muxAcquire and muxRelease -+// 3. low-level spinAcquire and spinRelease -+// 4. native Mutex:: and Monitor:: -+// 5. jvm_raw_lock() and _unlock() -+// 6. JVMTI raw monitors -- distinct from (5) despite having a confusingly -+// similar name. -+// -+// o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o-o -+ -+ -+// CASPTR() uses the canonical argument order that dominates in the literature. -+// Our internal cmpxchg_ptr() uses a bastardized ordering to accommodate Sun .il templates. -+ -+#define CASPTR(a,c,s) intptr_t(Atomic::cmpxchg_ptr ((void *)(s),(void *)(a),(void *)(c))) -+#define UNS(x) (uintptr_t(x)) -+#define TRACE(m) { static volatile int ctr = 0 ; int x = ++ctr ; if ((x & (x-1))==0) { ::printf ("%d:%s\n", x, #m); ::fflush(stdout); }} -+ -+// Simplistic low-quality Marsaglia SHIFT-XOR RNG. -+// Bijective except for the trailing mask operation. -+// Useful for spin loops as the compiler can't optimize it away. -+ -+static inline jint MarsagliaXORV (jint x) { -+ if (x == 0) x = 1|os::random() ; -+ x ^= x << 6; -+ x ^= ((unsigned)x) >> 21; -+ x ^= x << 7 ; -+ return x & 0x7FFFFFFF ; -+} - --MutexHistogramElement::MutexHistogramElement(const char* elementName) { -- _name = elementName; -- uintx count = 0; -+static inline jint MarsagliaXOR (jint * const a) { -+ jint x = *a ; -+ if (x == 0) x = UNS(a)|1 ; -+ x ^= x << 6; -+ x ^= ((unsigned)x) >> 21; -+ x ^= x << 7 ; -+ *a = x ; -+ return x & 0x7FFFFFFF ; -+} - -- while (Atomic::cmpxchg(1, &MutexHistogram_lock, 0) != 0) { -- while (OrderAccess::load_acquire(&MutexHistogram_lock) != 0) { -- count +=1; -- if ( (WarnOnStalledSpinLock > 0) -- && (count % WarnOnStalledSpinLock == 0)) { -- warning("MutexHistogram_lock seems to be stalled"); -- } -- } -+static int Stall (int its) { -+ static volatile jint rv = 1 ; -+ volatile int OnFrame = 0 ; -+ jint v = rv ^ UNS(OnFrame) ; -+ while (--its >= 0) { -+ v = MarsagliaXORV (v) ; -+ } -+ // Make this impossible for the compiler to optimize away, -+ // but (mostly) avoid W coherency sharing on MP systems. -+ if (v == 0x12345) rv = v ; -+ return v ; -+} -+ -+int Monitor::TryLock () { -+ intptr_t v = _LockWord.FullWord ; -+ for (;;) { -+ if ((v & _LBIT) != 0) return 0 ; -+ const intptr_t u = CASPTR (&_LockWord, v, v|_LBIT) ; -+ if (v == u) return 1 ; -+ v = u ; - } -+} - -- if (MutexHistogram == NULL) { -- MutexHistogram = new Histogram("VM Mutex Lock Attempt Counts",200); -+int Monitor::TryFast () { -+ // Optimistic fast-path form ... -+ // Fast-path attempt for the common uncontended case. -+ // Avoid RTS->RTO $ coherence upgrade on typical SMP systems. -+ intptr_t v = CASPTR (&_LockWord, 0, _LBIT) ; // agro ... -+ if (v == 0) return 1 ; -+ -+ for (;;) { -+ if ((v & _LBIT) != 0) return 0 ; -+ const intptr_t u = CASPTR (&_LockWord, v, v|_LBIT) ; -+ if (v == u) return 1 ; -+ v = u ; - } -+} - -- MutexHistogram->add_element(this); -- Atomic::dec(&MutexHistogram_lock); -+int Monitor::ILocked () { -+ const intptr_t w = _LockWord.FullWord & 0xFF ; -+ assert (w == 0 || w == _LBIT, "invariant") ; -+ return w == _LBIT ; - } - -+// Polite TATAS spinlock with exponential backoff - bounded spin. -+// Ideally we'd use processor cycles, time or vtime to control -+// the loop, but we currently use iterations. -+// All the constants within were derived empirically but work over -+// over the spectrum of J2SE reference platforms. -+// On Niagara-class systems the back-off is unnecessary but -+// is relatively harmless. (At worst it'll slightly retard -+// acquisition times). The back-off is critical for older SMP systems -+// where constant fetching of the LockWord would otherwise impair -+// scalability. -+// -+// Clamp spinning at approximately 1/2 of a context-switch round-trip. -+// See synchronizer.cpp for details and rationale. -+ -+int Monitor::TrySpin (Thread * const Self) { -+ if (TryLock()) return 1 ; -+ if (!os::is_MP()) return 0 ; -+ -+ int Probes = 0 ; -+ int Delay = 0 ; -+ int Steps = 0 ; -+ int SpinMax = NativeMonitorSpinLimit ; -+ int flgs = NativeMonitorFlags ; -+ for (;;) { -+ intptr_t v = _LockWord.FullWord; -+ if ((v & _LBIT) == 0) { -+ if (CASPTR (&_LockWord, v, v|_LBIT) == v) { -+ return 1 ; -+ } -+ continue ; -+ } -+ -+ if ((flgs & 8) == 0) { -+ SpinPause () ; -+ } -+ -+ // Periodically increase Delay -- variable Delay form -+ // conceptually: delay *= 1 + 1/Exponent -+ ++ Probes; -+ if (Probes > SpinMax) return 0 ; -+ -+ if ((Probes & 0x7) == 0) { -+ Delay = ((Delay << 1)|1) & 0x7FF ; -+ // CONSIDER: Delay += 1 + (Delay/4); Delay &= 0x7FF ; -+ } -+ -+ if (flgs & 2) continue ; -+ -+ // Consider checking _owner's schedctl state, if OFFPROC abort spin. -+ // If the owner is OFFPROC then it's unlike that the lock will be dropped -+ // in a timely fashion, which suggests that spinning would not be fruitful -+ // or profitable. -+ -+ // Stall for "Delay" time units - iterations in the current implementation. -+ // Avoid generating coherency traffic while stalled. -+ // Possible ways to delay: -+ // PAUSE, SLEEP, MEMBAR #sync, MEMBAR #halt, -+ // wr %g0,%asi, gethrtime, rdstick, rdtick, rdtsc, etc. ... -+ // Note that on Niagara-class systems we want to minimize STs in the -+ // spin loop. N1 and brethren write-around the L1$ over the xbar into the L2$. -+ // Furthermore, they don't have a W$ like traditional SPARC processors. -+ // We currently use a Marsaglia Shift-Xor RNG loop. -+ Steps += Delay ; -+ if (Self != NULL) { -+ jint rv = Self->rng[0] ; -+ for (int k = Delay ; --k >= 0; ) { -+ rv = MarsagliaXORV (rv) ; -+ if ((flgs & 4) == 0 && SafepointSynchronize::do_call_back()) return 0 ; -+ } -+ Self->rng[0] = rv ; -+ } else { -+ Stall (Delay) ; -+ } -+ } -+} - --MutexContentionHistogramElement::MutexContentionHistogramElement(const char* elementName) { -- _name = elementName; -- uintx count = 0; -+static int ParkCommon (ParkEvent * ev, jlong timo) { -+ // Diagnostic support - periodically unwedge blocked threads -+ intx nmt = NativeMonitorTimeout ; -+ if (nmt > 0 && (nmt < timo || timo <= 0)) { -+ timo = nmt ; -+ } -+ int err = OS_OK ; -+ if (0 == timo) { -+ ev->park() ; -+ } else { -+ err = ev->park(timo) ; -+ } -+ return err ; -+} - -- while (Atomic::cmpxchg(1, &MutexContentionHistogram_lock, 0) != 0) { -- while (OrderAccess::load_acquire(&MutexContentionHistogram_lock) != 0) { -- count +=1; -- if ( (WarnOnStalledSpinLock > 0) -- && (count % WarnOnStalledSpinLock == 0)) { -- warning("MutexContentionHistogram_lock seems to be stalled"); -+inline int Monitor::AcquireOrPush (ParkEvent * ESelf) { -+ intptr_t v = _LockWord.FullWord ; -+ for (;;) { -+ if ((v & _LBIT) == 0) { -+ const intptr_t u = CASPTR (&_LockWord, v, v|_LBIT) ; -+ if (u == v) return 1 ; // indicate acquired -+ v = u ; -+ } else { -+ // Anticipate success ... -+ ESelf->ListNext = (ParkEvent *) (v & ~_LBIT) ; -+ const intptr_t u = CASPTR (&_LockWord, v, intptr_t(ESelf)|_LBIT) ; -+ if (u == v) return 0 ; // indicate pushed onto cxq -+ v = u ; - } -+ // Interference - LockWord change - just retry - } -+} -+ -+// ILock and IWait are the lowest level primitive internal blocking -+// synchronization functions. The callers of IWait and ILock must have -+// performed any needed state transitions beforehand. -+// IWait and ILock may directly call park() without any concern for thread state. -+// Note that ILock and IWait do *not* access _owner. -+// _owner is a higher-level logical concept. -+ -+void Monitor::ILock (Thread * Self) { -+ assert (_OnDeck != Self->_MutexEvent, "invariant") ; -+ -+ if (TryFast()) { -+ Exeunt: -+ assert (ILocked(), "invariant") ; -+ return ; -+ } -+ -+ ParkEvent * const ESelf = Self->_MutexEvent ; -+ assert (_OnDeck != ESelf, "invariant") ; -+ -+ // As an optimization, spinners could conditionally try to set ONDECK to _LBIT -+ // Synchronizer.cpp uses a similar optimization. -+ if (TrySpin (Self)) goto Exeunt ; -+ -+ // Slow-path - the lock is contended. -+ // Either Enqueue Self on cxq or acquire the outer lock. -+ // LockWord encoding = (cxq,LOCKBYTE) -+ ESelf->reset() ; -+ OrderAccess::fence() ; -+ -+ // Optional optimization ... try barging on the inner lock -+ if ((NativeMonitorFlags & 32) && CASPTR (&_OnDeck, NULL, UNS(Self)) == 0) { -+ goto OnDeck_LOOP ; -+ } -+ -+ if (AcquireOrPush (ESelf)) goto Exeunt ; -+ -+ // At any given time there is at most one ondeck thread. -+ // ondeck implies not resident on cxq and not resident on EntryList -+ // Only the OnDeck thread can try to acquire -- contended for -- the lock. -+ // CONSIDER: use Self->OnDeck instead of m->OnDeck. -+ // Deschedule Self so that others may run. -+ while (_OnDeck != ESelf) { -+ ParkCommon (ESelf, 0) ; -+ } -+ -+ // Self is now in the ONDECK position and will remain so until it -+ // manages to acquire the lock. -+ OnDeck_LOOP: -+ for (;;) { -+ assert (_OnDeck == ESelf, "invariant") ; -+ if (TrySpin (Self)) break ; -+ // CONSIDER: if ESelf->TryPark() && TryLock() break ... -+ // It's probably wise to spin only if we *actually* blocked -+ // CONSIDER: check the lockbyte, if it remains set then -+ // preemptively drain the cxq into the EntryList. -+ // The best place and time to perform queue operations -- lock metadata -- -+ // is _before having acquired the outer lock, while waiting for the lock to drop. -+ ParkCommon (ESelf, 0) ; -+ } -+ -+ assert (_OnDeck == ESelf, "invariant") ; -+ _OnDeck = NULL ; -+ -+ // Note that we current drop the inner lock (clear OnDeck) in the slow-path -+ // epilog immediately after having acquired the outer lock. -+ // But instead we could consider the following optimizations: -+ // A. Shift or defer dropping the inner lock until the subsequent IUnlock() operation. -+ // This might avoid potential reacquisition of the inner lock in IUlock(). -+ // B. While still holding the inner lock, attempt to opportunistically select -+ // and unlink the next ONDECK thread from the EntryList. -+ // If successful, set ONDECK to refer to that thread, otherwise clear ONDECK. -+ // It's critical that the select-and-unlink operation run in constant-time as -+ // it executes when holding the outer lock and may artificially increase the -+ // effective length of the critical section. -+ // Note that (A) and (B) are tantamount to succession by direct handoff for -+ // the inner lock. -+ goto Exeunt ; -+} -+ -+void Monitor::IUnlock (bool RelaxAssert) { -+ assert (ILocked(), "invariant") ; -+ _LockWord.Bytes[_LSBINDEX] = 0 ; // drop outer lock -+ OrderAccess::storeload (); -+ ParkEvent * const w = _OnDeck ; -+ assert (RelaxAssert || w != Thread::current()->_MutexEvent, "invariant") ; -+ if (w != NULL) { -+ // Either we have a valid ondeck thread or ondeck is transiently "locked" -+ // by some exiting thread as it arranges for succession. The LSBit of -+ // OnDeck allows us to discriminate two cases. If the latter, the -+ // responsibility for progress and succession lies with that other thread. -+ // For good performance, we also depend on the fact that redundant unpark() -+ // operations are cheap. That is, repeated Unpark()ing of the ONDECK thread -+ // is inexpensive. This approach provides implicit futile wakeup throttling. -+ // Note that the referent "w" might be stale with respect to the lock. -+ // In that case the following unpark() is harmless and the worst that'll happen -+ // is a spurious return from a park() operation. Critically, if "w" _is stale, -+ // then progress is known to have occurred as that means the thread associated -+ // with "w" acquired the lock. In that case this thread need take no further -+ // action to guarantee progress. -+ if ((UNS(w) & _LBIT) == 0) w->unpark() ; -+ return ; -+ } -+ -+ intptr_t cxq = _LockWord.FullWord ; -+ if (((cxq & ~_LBIT)|UNS(_EntryList)) == 0) { -+ return ; // normal fast-path exit - cxq and EntryList both empty -+ } -+ if (cxq & _LBIT) { -+ // Optional optimization ... -+ // Some other thread acquired the lock in the window since this -+ // thread released it. Succession is now that thread's responsibility. -+ return ; -+ } -+ -+ Succession: -+ // Slow-path exit - this thread must ensure succession and progress. -+ // OnDeck serves as lock to protect cxq and EntryList. -+ // Only the holder of OnDeck can manipulate EntryList or detach the RATs from cxq. -+ // Avoid ABA - allow multiple concurrent producers (enqueue via push-CAS) -+ // but only one concurrent consumer (detacher of RATs). -+ // Consider protecting this critical section with schedctl on Solaris. -+ // Unlike a normal lock, however, the exiting thread "locks" OnDeck, -+ // picks a successor and marks that thread as OnDeck. That successor -+ // thread will then clear OnDeck once it eventually acquires the outer lock. -+ if (CASPTR (&_OnDeck, NULL, _LBIT) != UNS(NULL)) { -+ return ; -+ } -+ -+ ParkEvent * List = _EntryList ; -+ if (List != NULL) { -+ // Transfer the head of the EntryList to the OnDeck position. -+ // Once OnDeck, a thread stays OnDeck until it acquires the lock. -+ // For a given lock there is at most OnDeck thread at any one instant. -+ WakeOne: -+ assert (List == _EntryList, "invariant") ; -+ ParkEvent * const w = List ; -+ assert (RelaxAssert || w != Thread::current()->_MutexEvent, "invariant") ; -+ _EntryList = w->ListNext ; -+ // as a diagnostic measure consider setting w->_ListNext = BAD -+ assert (UNS(_OnDeck) == _LBIT, "invariant") ; -+ _OnDeck = w ; // pass OnDeck to w. -+ // w will clear OnDeck once it acquires the outer lock -+ -+ // Another optional optimization ... -+ // For heavily contended locks it's not uncommon that some other -+ // thread acquired the lock while this thread was arranging succession. -+ // Try to defer the unpark() operation - Delegate the responsibility -+ // for unpark()ing the OnDeck thread to the current or subsequent owners -+ // That is, the new owner is responsible for unparking the OnDeck thread. -+ OrderAccess::storeload() ; -+ cxq = _LockWord.FullWord ; -+ if (cxq & _LBIT) return ; -+ -+ w->unpark() ; -+ return ; -+ } -+ -+ cxq = _LockWord.FullWord ; -+ if ((cxq & ~_LBIT) != 0) { -+ // The EntryList is empty but the cxq is populated. -+ // drain RATs from cxq into EntryList -+ // Detach RATs segment with CAS and then merge into EntryList -+ for (;;) { -+ // optional optimization - if locked, the owner is responsible for succession -+ if (cxq & _LBIT) goto Punt ; -+ const intptr_t vfy = CASPTR (&_LockWord, cxq, cxq & _LBIT) ; -+ if (vfy == cxq) break ; -+ cxq = vfy ; -+ // Interference - LockWord changed - Just retry -+ // We can see concurrent interference from contending threads -+ // pushing themselves onto the cxq or from lock-unlock operations. -+ // From the perspective of this thread, EntryList is stable and -+ // the cxq is prepend-only -- the head is volatile but the interior -+ // of the cxq is stable. In theory if we encounter interference from threads -+ // pushing onto cxq we could simply break off the original cxq suffix and -+ // move that segment to the EntryList, avoiding a 2nd or multiple CAS attempts -+ // on the high-traffic LockWord variable. For instance lets say the cxq is "ABCD" -+ // when we first fetch cxq above. Between the fetch -- where we observed "A" -+ // -- and CAS -- where we attempt to CAS null over A -- "PQR" arrive, -+ // yielding cxq = "PQRABCD". In this case we could simply set A.ListNext -+ // null, leaving cxq = "PQRA" and transfer the "BCD" segment to the EntryList. -+ // Note too, that it's safe for this thread to traverse the cxq -+ // without taking any special concurrency precautions. -+ } -+ -+ // We don't currently reorder the cxq segment as we move it onto -+ // the EntryList, but it might make sense to reverse the order -+ // or perhaps sort by thread priority. See the comments in -+ // synchronizer.cpp objectMonitor::exit(). -+ assert (_EntryList == NULL, "invariant") ; -+ _EntryList = List = (ParkEvent *)(cxq & ~_LBIT) ; -+ assert (List != NULL, "invariant") ; -+ goto WakeOne ; -+ } -+ -+ // cxq|EntryList is empty. -+ // w == NULL implies that cxq|EntryList == NULL in the past. -+ // Possible race - rare inopportune interleaving. -+ // A thread could have added itself to cxq since this thread previously checked. -+ // Detect and recover by refetching cxq. -+ Punt: -+ assert (UNS(_OnDeck) == _LBIT, "invariant") ; -+ _OnDeck = NULL ; // Release inner lock. -+ OrderAccess::storeload(); // Dekker duality - pivot point -+ -+ // Resample LockWord/cxq to recover from possible race. -+ // For instance, while this thread T1 held OnDeck, some other thread T2 might -+ // acquire the outer lock. Another thread T3 might try to acquire the outer -+ // lock, but encounter contention and enqueue itself on cxq. T2 then drops the -+ // outer lock, but skips succession as this thread T1 still holds OnDeck. -+ // T1 is and remains responsible for ensuring succession of T3. -+ // -+ // Note that we don't need to recheck EntryList, just cxq. -+ // If threads moved onto EntryList since we dropped OnDeck -+ // that implies some other thread forced succession. -+ cxq = _LockWord.FullWord ; -+ if ((cxq & ~_LBIT) != 0 && (cxq & _LBIT) == 0) { -+ goto Succession ; // potential race -- re-run succession - } -+ return ; -+} - -- if (MutexContentionHistogram == NULL) { -- MutexContentionHistogram = new Histogram("VM Mutex Lock Contention Count",200); -+bool Monitor::notify() { -+ assert (_owner == Thread::current(), "invariant") ; -+ assert (ILocked(), "invariant") ; -+ if (_WaitSet == NULL) return true ; -+ NotifyCount ++ ; -+ -+ // Transfer one thread from the WaitSet to the EntryList or cxq. -+ // Currently we just unlink the head of the WaitSet and prepend to the cxq. -+ // And of course we could just unlink it and unpark it, too, but -+ // in that case it'd likely impale itself on the reentry. -+ Thread::muxAcquire (_WaitLock, "notify:WaitLock") ; -+ ParkEvent * nfy = _WaitSet ; -+ if (nfy != NULL) { // DCL idiom -+ _WaitSet = nfy->ListNext ; -+ assert (nfy->Notified == 0, "invariant") ; -+ // push nfy onto the cxq -+ for (;;) { -+ const intptr_t v = _LockWord.FullWord ; -+ assert ((v & 0xFF) == _LBIT, "invariant") ; -+ nfy->ListNext = (ParkEvent *)(v & ~_LBIT); -+ if (CASPTR (&_LockWord, v, UNS(nfy)|_LBIT) == v) break; -+ // interference - _LockWord changed -- just retry -+ } -+ // Note that setting Notified before pushing nfy onto the cxq is -+ // also legal and safe, but the safety properties are much more -+ // subtle, so for the sake of code stewardship ... -+ OrderAccess::fence() ; -+ nfy->Notified = 1; -+ } -+ Thread::muxRelease (_WaitLock) ; -+ if (nfy != NULL && (NativeMonitorFlags & 16)) { -+ // Experimental code ... light up the wakee in the hope that this thread (the owner) -+ // will drop the lock just about the time the wakee comes ONPROC. -+ nfy->unpark() ; - } -+ assert (ILocked(), "invariant") ; -+ return true ; -+} - -- MutexContentionHistogram->add_element(this); -- Atomic::dec(&MutexContentionHistogram_lock); -+// Currently notifyAll() transfers the waiters one-at-a-time from the waitset -+// to the cxq. This could be done more efficiently with a single bulk en-mass transfer, -+// but in practice notifyAll() for large #s of threads is rare and not time-critical. -+// Beware too, that we invert the order of the waiters. Lets say that the -+// waitset is "ABCD" and the cxq is "XYZ". After a notifyAll() the waitset -+// will be empty and the cxq will be "DCBAXYZ". This is benign, of course. -+ -+bool Monitor::notify_all() { -+ assert (_owner == Thread::current(), "invariant") ; -+ assert (ILocked(), "invariant") ; -+ while (_WaitSet != NULL) notify() ; -+ return true ; - } - --#endif -+int Monitor::IWait (Thread * Self, jlong timo) { -+ assert (ILocked(), "invariant") ; - -+ // Phases: -+ // 1. Enqueue Self on WaitSet - currently prepend -+ // 2. unlock - drop the outer lock -+ // 3. wait for either notification or timeout -+ // 4. lock - reentry - reacquire the outer lock -+ -+ ParkEvent * const ESelf = Self->_MutexEvent ; -+ ESelf->Notified = 0 ; -+ ESelf->reset() ; -+ OrderAccess::fence() ; -+ -+ // Add Self to WaitSet -+ // Ideally only the holder of the outer lock would manipulate the WaitSet - -+ // That is, the outer lock would implicitly protect the WaitSet. -+ // But if a thread in wait() encounters a timeout it will need to dequeue itself -+ // from the WaitSet _before it becomes the owner of the lock. We need to dequeue -+ // as the ParkEvent -- which serves as a proxy for the thread -- can't reside -+ // on both the WaitSet and the EntryList|cxq at the same time.. That is, a thread -+ // on the WaitSet can't be allowed to compete for the lock until it has managed to -+ // unlink its ParkEvent from WaitSet. Thus the need for WaitLock. -+ // Contention on the WaitLock is minimal. -+ // -+ // Another viable approach would be add another ParkEvent, "WaitEvent" to the -+ // thread class. The WaitSet would be composed of WaitEvents. Only the -+ // owner of the outer lock would manipulate the WaitSet. A thread in wait() -+ // could then compete for the outer lock, and then, if necessary, unlink itself -+ // from the WaitSet only after having acquired the outer lock. More precisely, -+ // there would be no WaitLock. A thread in in wait() would enqueue its WaitEvent -+ // on the WaitSet; release the outer lock; wait for either notification or timeout; -+ // reacquire the inner lock; and then, if needed, unlink itself from the WaitSet. -+ // -+ // Alternatively, a 2nd set of list link fields in the ParkEvent might suffice. -+ // One set would be for the WaitSet and one for the EntryList. -+ // We could also deconstruct the ParkEvent into a "pure" event and add a -+ // new immortal/TSM "ListElement" class that referred to ParkEvents. -+ // In that case we could have one ListElement on the WaitSet and another -+ // on the EntryList, with both referring to the same pure Event. -+ -+ Thread::muxAcquire (_WaitLock, "wait:WaitLock:Add") ; -+ ESelf->ListNext = _WaitSet ; -+ _WaitSet = ESelf ; -+ Thread::muxRelease (_WaitLock) ; -+ -+ // Release the outer lock -+ // We call IUnlock (RelaxAssert=true) as a thread T1 might -+ // enqueue itself on the WaitSet, call IUnlock(), drop the lock, -+ // and then stall before it can attempt to wake a successor. -+ // Some other thread T2 acquires the lock, and calls notify(), moving -+ // T1 from the WaitSet to the cxq. T2 then drops the lock. T1 resumes, -+ // and then finds *itself* on the cxq. During the course of a normal -+ // IUnlock() call a thread should _never find itself on the EntryList -+ // or cxq, but in the case of wait() it's possible. -+ // See synchronizer.cpp objectMonitor::wait(). -+ IUnlock (true) ; -+ -+ // Wait for either notification or timeout -+ // Beware that in some circumstances we might propagate -+ // spurious wakeups back to the caller. -+ -+ for (;;) { -+ if (ESelf->Notified) break ; -+ int err = ParkCommon (ESelf, timo) ; -+ if (err == OS_TIMEOUT || (NativeMonitorFlags & 1)) break ; -+ } -+ -+ // Prepare for reentry - if necessary, remove ESelf from WaitSet -+ // ESelf can be: -+ // 1. Still on the WaitSet. This can happen if we exited the loop by timeout. -+ // 2. On the cxq or EntryList -+ // 3. Not resident on cxq, EntryList or WaitSet, but in the OnDeck position. -+ -+ OrderAccess::fence() ; -+ int WasOnWaitSet = 0 ; -+ if (ESelf->Notified == 0) { -+ Thread::muxAcquire (_WaitLock, "wait:WaitLock:remove") ; -+ if (ESelf->Notified == 0) { // DCL idiom -+ assert (_OnDeck != ESelf, "invariant") ; // can't be both OnDeck and on WaitSet -+ // ESelf is resident on the WaitSet -- unlink it. -+ // A doubly-linked list would be better here so we can unlink in constant-time. -+ // We have to unlink before we potentially recontend as ESelf might otherwise -+ // end up on the cxq|EntryList -- it can't be on two lists at once. -+ ParkEvent * p = _WaitSet ; -+ ParkEvent * q = NULL ; // classic q chases p -+ while (p != NULL && p != ESelf) { -+ q = p ; -+ p = p->ListNext ; -+ } -+ assert (p == ESelf, "invariant") ; -+ if (p == _WaitSet) { // found at head -+ assert (q == NULL, "invariant") ; -+ _WaitSet = p->ListNext ; -+ } else { // found in interior -+ assert (q->ListNext == p, "invariant") ; -+ q->ListNext = p->ListNext ; -+ } -+ WasOnWaitSet = 1 ; // We were *not* notified but instead encountered timeout -+ } -+ Thread::muxRelease (_WaitLock) ; -+ } -+ -+ // Reentry phase - reacquire the lock -+ if (WasOnWaitSet) { -+ // ESelf was previously on the WaitSet but we just unlinked it above -+ // because of a timeout. ESelf is not resident on any list and is not OnDeck -+ assert (_OnDeck != ESelf, "invariant") ; -+ ILock (Self) ; -+ } else { -+ // A prior notify() operation moved ESelf from the WaitSet to the cxq. -+ // ESelf is now on the cxq, EntryList or at the OnDeck position. -+ // The following fragment is extracted from Monitor::ILock() -+ for (;;) { -+ if (_OnDeck == ESelf && TrySpin(Self)) break ; -+ ParkCommon (ESelf, 0) ; -+ } -+ assert (_OnDeck == ESelf, "invariant") ; -+ _OnDeck = NULL ; -+ } -+ -+ assert (ILocked(), "invariant") ; -+ return WasOnWaitSet != 0 ; // return true IFF timeout -+} - --// This needs to be an invalid return from Thread::current; NULL is checked --// for as invalid in its implementation. _owner == INVALID_THREAD, means that --// the lock is unlocked. - - // ON THE VMTHREAD SNEAKING PAST HELD LOCKS: - // In particular, there are certain types of global lock that may be held -@@ -92,181 +835,351 @@ - // written the _owner field. These locks may be sneakily acquired by the - // VM thread during a safepoint to avoid deadlocks. Alternatively, one should - // identify all such locks, and ensure that Java threads never block at --// safepoints while holding them (_no_safepopint_check_flag). While it -+// safepoints while holding them (_no_safepoint_check_flag). While it - // seems as though this could increase the time to reach a safepoint - // (or at least increase the mean, if not the variance), the latter - // approach might make for a cleaner, more maintainable JVM design. -+// -+// Sneaking is vile and reprehensible and should be excised at the 1st -+// opportunity. It's possible that the need for sneaking could be obviated -+// as follows. Currently, a thread might (a) while TBIVM, call pthread_mutex_lock -+// or ILock() thus acquiring the "physical" lock underlying Monitor/Mutex. -+// (b) stall at the TBIVM exit point as a safepoint is in effect. Critically, -+// it'll stall at the TBIVM reentry state transition after having acquired the -+// underlying lock, but before having set _owner and having entered the actual -+// critical section. The lock-sneaking facility leverages that fact and allowed the -+// VM thread to logically acquire locks that had already be physically locked by mutators -+// but where mutators were known blocked by the reentry thread state transition. -+// -+// If we were to modify the Monitor-Mutex so that TBIVM state transitions tightly -+// wrapped calls to park(), then we could likely do away with sneaking. We'd -+// decouple lock acquisition and parking. The critical invariant to eliminating -+// sneaking is to ensure that we never "physically" acquire the lock while TBIVM. -+// An easy way to accomplish this is to wrap the park calls in a narrow TBIVM jacket. -+// One difficulty with this approach is that the TBIVM wrapper could recurse and -+// call lock() deep from within a lock() call, while the MutexEvent was already enqueued. -+// Using a stack (N=2 at minimum) of ParkEvents would take care of that problem. -+// -+// But of course the proper ultimate approach is to avoid schemes that require explicit -+// sneaking or dependence on any any clever invariants or subtle implementation properties -+// of Mutex-Monitor and instead directly address the underlying design flaw. - --Thread* Mutex::INVALID_THREAD = (Thread*)NULL; -- --void Mutex::lock(Thread *thread) { -- -+void Monitor::lock (Thread * Self) { - #ifdef CHECK_UNHANDLED_OOPS - // Clear unhandled oops so we get a crash right away. Only clear for non-vm - // or GC threads. -- if (thread->is_Java_thread()) { -- thread->clear_unhandled_oops(); -+ if (Self->is_Java_thread()) { -+ Self->clear_unhandled_oops(); - } - #endif // CHECK_UNHANDLED_OOPS - -- debug_only(check_prelock_state(thread)); -- // assert(!thread->is_inside_signal_handler(), "don't lock inside signal handler"); -+ debug_only(check_prelock_state(Self)); -+ assert (_owner != Self , "invariant") ; -+ assert (_OnDeck != Self->_MutexEvent, "invariant") ; -+ -+ if (TryFast()) { -+ Exeunt: -+ assert (ILocked(), "invariant") ; -+ assert (owner() == NULL, "invariant"); -+ set_owner (Self); -+ return ; -+ } - --#ifdef ASSERT -- // Keep track of how many time access lock -- if (CountVMLocks) _histogram->increment_count(); --#endif -+ // The lock is contended ... - -- // lock_implementation is a os-specific method -- if (lock_implementation()) { -- // Success, we now own the lock -- } else { --#ifdef ASSERT -- // Keep track of how many times we fail -- if (CountVMLocks) _contend_histogram->increment_count(); --#endif -- bool can_sneak = thread->is_VM_thread() && -- SafepointSynchronize::is_at_safepoint(); -- if (can_sneak && _owner == INVALID_THREAD) { -+ bool can_sneak = Self->is_VM_thread() && SafepointSynchronize::is_at_safepoint(); -+ if (can_sneak && _owner == NULL) { - // a java thread has locked the lock but has not entered the - // critical region -- let's just pretend we've locked the lock -- // and go on. we note this with _suppress_signal so we can also -+ // and go on. we note this with _snuck so we can also - // pretend to unlock when the time comes. -- _suppress_signal = true; -- } else { -- check_block_state(thread); -- if (!thread->is_Java_thread()) { -- wait_for_lock_implementation(); -- } else { -- debug_only(assert(rank() > Mutex::special, -- "Potential deadlock with special or lesser rank mutex")); -- wait_for_lock_blocking_implementation((JavaThread*)thread); -- } -+ _snuck = true; -+ goto Exeunt ; - } -+ -+ // Try a brief spin to avoid passing thru thread state transition ... -+ if (TrySpin (Self)) goto Exeunt ; -+ -+ check_block_state(Self); -+ if (Self->is_Java_thread()) { -+ // Horribile dictu - we suffer through a state transition -+ assert(rank() > Mutex::special, "Potential deadlock with special or lesser rank mutex"); -+ ThreadBlockInVM tbivm ((JavaThread *) Self) ; -+ ILock (Self) ; -+ } else { -+ // Mirabile dictu -+ ILock (Self) ; - } -+ goto Exeunt ; -+} -+ -+void Monitor::lock() { -+ this->lock(Thread::current()); -+} -+ -+// Lock without safepoint check - a degenerate variant of lock(). -+// Should ONLY be used by safepoint code and other code -+// that is guaranteed not to block while running inside the VM. If this is called with -+// thread state set to be in VM, the safepoint synchronization code will deadlock! - -- assert(owner() == Mutex::INVALID_THREAD, "Mutex lock count and owner are inconsistent"); -- set_owner(thread); -- trace("locks"); -+void Monitor::lock_without_safepoint_check (Thread * Self) { -+ assert (_owner != Self, "invariant") ; -+ ILock (Self) ; -+ assert (_owner == NULL, "invariant"); -+ set_owner (Self); - } - --void Mutex::lock() { -- Thread* thread = Thread::current(); -- this->lock(thread); -+void Monitor::lock_without_safepoint_check () { -+ lock_without_safepoint_check (Thread::current()) ; - } - --// Returns true if thread succeceed in grabbing the lock, otherwise false. --bool Mutex::try_lock() { -- Thread* thread = Thread::current(); -- debug_only(check_prelock_state(thread)); -+ -+// Returns true if thread succeceed [sic] in grabbing the lock, otherwise false. -+ -+bool Monitor::try_lock() { -+ Thread * const Self = Thread::current(); -+ debug_only(check_prelock_state(Self)); - // assert(!thread->is_inside_signal_handler(), "don't lock inside signal handler"); - --#ifdef ASSERT -- // Keep track of how many time access lock -- if (CountVMLocks) _histogram->increment_count(); --#endif -- // Special case, where all Java threads are stopped. The count is not -1, but the owner -- // is not yet set. In that case the VM thread can safely grab the lock. -- bool can_sneak = thread->is_VM_thread() && -- SafepointSynchronize::is_at_safepoint(); -- if (can_sneak && _owner == INVALID_THREAD) { -- set_owner(thread); // Do not need to be atomic, since we are at a safepoint -- _suppress_signal = true; -+ // Special case, where all Java threads are stopped. -+ // The lock may have been acquired but _owner is not yet set. -+ // In that case the VM thread can safely grab the lock. -+ // It strikes me this should appear _after the TryLock() fails, below. -+ bool can_sneak = Self->is_VM_thread() && SafepointSynchronize::is_at_safepoint(); -+ if (can_sneak && _owner == NULL) { -+ set_owner(Self); // Do not need to be atomic, since we are at a safepoint -+ _snuck = true; - return true; - } - -- // The try_lock_implementation is platform-specific -- if (try_lock_implementation()) { -+ if (TryLock()) { - // We got the lock -- assert(owner() == Mutex::INVALID_THREAD, "Mutex lock count and owner are inconsistent"); -- set_owner(thread); -- trace("try_locks"); -+ assert (_owner == NULL, "invariant"); -+ set_owner (Self); - return true; -- } else { --#ifdef ASSERT -- // Keep track of how many times we fail -- if (CountVMLocks) _contend_histogram->increment_count(); --#endif -+ } - return false; -+} -+ -+void Monitor::unlock() { -+ assert (_owner == Thread::current(), "invariant") ; -+ assert (_OnDeck != Thread::current()->_MutexEvent , "invariant") ; -+ set_owner (NULL) ; -+ if (_snuck) { -+ assert(SafepointSynchronize::is_at_safepoint() && Thread::current()->is_VM_thread(), "sneak"); -+ _snuck = false; -+ return ; - } -+ IUnlock (false) ; - } - --// Lock without safepoint check. Should ONLY be used by safepoint code and other code --// that is guaranteed not to block while running inside the VM. If this is called with --// thread state set to be in VM, the safepoint synchronization code will deadlock! -+// Yet another degenerate version of Monitor::lock() or lock_without_safepoint_check() -+// jvm_raw_lock() and _unlock() can be called by non-Java threads via JVM_RawMonitorEnter. -+// -+// There's no expectation that JVM_RawMonitors will interoperate properly with the native -+// Mutex-Monitor constructs. We happen to implement JVM_RawMonitors in terms of -+// native Mutex-Monitors simply as a matter of convenience. A simple abstraction layer -+// over a pthread_mutex_t would work equally as well, but require more platform-specific -+// code -- a "PlatformMutex". Alternatively, a simply layer over muxAcquire-muxRelease -+// would work too. -+// -+// Since the caller might be a foreign thread, we don't necessarily have a Thread.MutexEvent -+// instance available. Instead, we transiently allocate a ParkEvent on-demand if -+// we encounter contention. That ParkEvent remains associated with the thread -+// until it manages to acquire the lock, at which time we return the ParkEvent -+// to the global ParkEvent free list. This is correct and suffices for our purposes. -+// -+// Beware that the original jvm_raw_unlock() had a "_snuck" test but that -+// jvm_raw_lock() didn't have the corresponding test. I suspect that's an -+// oversight, but I've replicated the original suspect logic in the new code ... -+ -+void Monitor::jvm_raw_lock() { -+ assert(rank() == native, "invariant"); -+ -+ if (TryLock()) { -+ Exeunt: -+ assert (ILocked(), "invariant") ; -+ assert (_owner == NULL, "invariant"); -+ // This can potentially be called by non-java Threads. Thus, the ThreadLocalStorage -+ // might return NULL. Don't call set_owner since it will break on an NULL owner -+ // Consider installing a non-null "ANON" distinguished value instead of just NULL. -+ _owner = ThreadLocalStorage::thread(); -+ return ; -+ } - --void Mutex::lock_without_safepoint_check() { --#ifdef ASSERT -- // Keep track of how many time access lock -- if (CountVMLocks) _histogram->increment_count(); --#endif -- Thread* thread = Thread::current(); --// #ifdef ASSERT --// if (thread) { --// assert(!thread->is_inside_signal_handler(), "don't lock inside signal handler"); --// } --// #endif -- -- // lock_implementation is platform specific -- if (lock_implementation()) { -- // Success, we now own the lock -+ if (TrySpin(NULL)) goto Exeunt ; -+ -+ // slow-path - apparent contention -+ // Allocate a ParkEvent for transient use. -+ // The ParkEvent remains associated with this thread until -+ // the time the thread manages to acquire the lock. -+ ParkEvent * const ESelf = ParkEvent::Allocate(NULL) ; -+ ESelf->reset() ; -+ OrderAccess::storeload() ; -+ -+ // Either Enqueue Self on cxq or acquire the outer lock. -+ if (AcquireOrPush (ESelf)) { -+ ParkEvent::Release (ESelf) ; // surrender the ParkEvent -+ goto Exeunt ; -+ } -+ -+ // At any given time there is at most one ondeck thread. -+ // ondeck implies not resident on cxq and not resident on EntryList -+ // Only the OnDeck thread can try to acquire -- contended for -- the lock. -+ // CONSIDER: use Self->OnDeck instead of m->OnDeck. -+ for (;;) { -+ if (_OnDeck == ESelf && TrySpin(NULL)) break ; -+ ParkCommon (ESelf, 0) ; -+ } -+ -+ assert (_OnDeck == ESelf, "invariant") ; -+ _OnDeck = NULL ; -+ ParkEvent::Release (ESelf) ; // surrender the ParkEvent -+ goto Exeunt ; -+} -+ -+void Monitor::jvm_raw_unlock() { -+ // Nearly the same as Monitor::unlock() ... -+ // directly set _owner instead of using set_owner(null) -+ _owner = NULL ; -+ if (_snuck) { // ??? -+ assert(SafepointSynchronize::is_at_safepoint() && Thread::current()->is_VM_thread(), "sneak"); -+ _snuck = false; -+ return ; -+ } -+ IUnlock(false) ; -+} -+ -+bool Monitor::wait(bool no_safepoint_check, long timeout, bool as_suspend_equivalent) { -+ Thread * const Self = Thread::current() ; -+ assert (_owner == Self, "invariant") ; -+ assert (ILocked(), "invariant") ; -+ -+ // as_suspend_equivalent logically implies !no_safepoint_check -+ guarantee (!as_suspend_equivalent || !no_safepoint_check, "invariant") ; -+ // !no_safepoint_check logically implies java_thread -+ guarantee (no_safepoint_check || Self->is_Java_thread(), "invariant") ; -+ -+ #ifdef ASSERT -+ Monitor * least = get_least_ranked_lock_besides_this(Self->owned_locks()); -+ assert(least != this, "Specification of get_least_... call above"); -+ if (least != NULL && least->rank() <= special) { -+ tty->print("Attempting to wait on monitor %s/%d while holding" -+ " lock %s/%d -- possible deadlock", -+ name(), rank(), least->name(), least->rank()); -+ assert(false, "Shouldn't block(wait) while holding a lock of rank special"); -+ } -+ #endif // ASSERT -+ -+ int wait_status ; -+ // conceptually set the owner to NULL in anticipation of -+ // abdicating the lock in wait -+ set_owner(NULL); -+ if (no_safepoint_check) { -+ wait_status = IWait (Self, timeout) ; - } else { --#ifdef ASSERT -- // Keep track of how many times we fail -- if (CountVMLocks) _contend_histogram->increment_count(); --#endif -- wait_for_lock_implementation(); -+ assert (Self->is_Java_thread(), "invariant") ; -+ JavaThread *jt = (JavaThread *)Self; -+ -+ // Enter safepoint region - ornate and Rococo ... -+ ThreadBlockInVM tbivm(jt); -+ OSThreadWaitState osts(Self->osthread(), false /* not Object.wait() */); -+ -+ if (as_suspend_equivalent) { -+ jt->set_suspend_equivalent(); -+ // cleared by handle_special_suspend_equivalent_condition() or -+ // java_suspend_self() -+ } -+ -+ wait_status = IWait (Self, timeout) ; -+ -+ // were we externally suspended while we were waiting? -+ if (as_suspend_equivalent && jt->handle_special_suspend_equivalent_condition()) { -+ // Our event wait has finished and we own the lock, but -+ // while we were waiting another thread suspended us. We don't -+ // want to hold the lock while suspended because that -+ // would surprise the thread that suspended us. -+ assert (ILocked(), "invariant") ; -+ IUnlock (true) ; -+ jt->java_suspend_self(); -+ ILock (Self) ; -+ assert (ILocked(), "invariant") ; -+ } - } - -- assert(_owner == INVALID_THREAD, "Mutex lock count and owner are inconsistent"); -- set_owner(thread); -+ // Conceptually reestablish ownership of the lock. -+ // The "real" lock -- the LockByte -- was reacquired by IWait(). -+ assert (ILocked(), "invariant") ; -+ assert (_owner == NULL, "invariant") ; -+ set_owner (Self) ; -+ return wait_status != 0 ; // return true IFF timeout - } - -+Monitor::~Monitor() { -+ assert ((UNS(_owner)|UNS(_LockWord.FullWord)|UNS(_EntryList)|UNS(_WaitSet)|UNS(_OnDeck)) == 0, "") ; -+} -+ -+void Monitor::ClearMonitor (Monitor * m) { -+ m->_owner = NULL ; -+ m->_snuck = false ; -+ m->_name = "UNKNOWN" ; -+ m->_LockWord.FullWord = 0 ; -+ m->_EntryList = NULL ; -+ m->_OnDeck = NULL ; -+ m->_WaitSet = NULL ; -+ m->_WaitLock[0] = 0 ; -+} - --// Can be called by non-Java threads (JVM_RawMonitorEnter) --void Mutex::jvm_raw_lock() { -+Monitor::Monitor() { ClearMonitor(this); } -+ -+Monitor::Monitor (int Rank, const char * name, bool allow_vm_block) { -+ ClearMonitor (this) ; - #ifdef ASSERT -- // Keep track of how many time access lock -- if (CountVMLocks) _histogram->increment_count(); -+ _allow_vm_block = allow_vm_block; -+ _rank = Rank ; - #endif -- assert(rank() == native, "must be called by non-VM locks"); -- if (lock_implementation()) { -- // Success, we now own the lock -- } else { -+} -+ -+Mutex::~Mutex() { -+ assert ((UNS(_owner)|UNS(_LockWord.FullWord)|UNS(_EntryList)|UNS(_WaitSet)|UNS(_OnDeck)) == 0, "") ; -+} -+ -+Mutex::Mutex (int Rank, const char * name, bool allow_vm_block) { -+ ClearMonitor ((Monitor *) this) ; - #ifdef ASSERT -- // Keep track of how many times we fail -- if (CountVMLocks) _contend_histogram->increment_count(); -+ _allow_vm_block = allow_vm_block; -+ _rank = Rank ; - #endif -- wait_for_lock_implementation(); -- } -- assert(_owner == INVALID_THREAD, "Mutex lock count and owner are inconsistent"); -- // This can potentially be called by non-java Threads. Thus, the ThreadLocalStorage -- // might return NULL. Don't call set_owner since it will break on an NULL -- // owner -- _owner = ThreadLocalStorage::thread(); - } - --bool Mutex::owned_by_self() const { -+bool Monitor::owned_by_self() const { - bool ret = _owner == Thread::current(); -- assert(_lock_count>=0 || !ret, "lock count must by >=0 for a locked mutex"); -+ assert (!ret || _LockWord.Bytes[_LSBINDEX] != 0, "invariant") ; - return ret; - } - --void Mutex::print_on_error(outputStream* st) const { -+void Monitor::print_on_error(outputStream* st) const { - st->print("[" PTR_FORMAT, this); -- st->print("/" PTR_FORMAT, _lock_event); - st->print("] %s", _name); - st->print(" - owner thread: " PTR_FORMAT, _owner); - } - -+ -+ -+ - // ---------------------------------------------------------------------------------- - // Non-product code - -+#ifndef PRODUCT -+void Monitor::print_on(outputStream* st) const { -+ st->print_cr("Mutex: [0x%lx/0x%lx] %s - owner: 0x%lx", this, _LockWord.FullWord, _name, _owner); -+} -+#endif - - #ifndef PRODUCT - #ifdef ASSERT --Mutex* Mutex::get_least_ranked_lock(Mutex* locks) { -- Mutex *res, *tmp; -+Monitor * Monitor::get_least_ranked_lock(Monitor * locks) { -+ Monitor *res, *tmp; - for (res = tmp = locks; tmp != NULL; tmp = tmp->next()) { - if (tmp->rank() < res->rank()) { - res = tmp; -@@ -285,8 +1198,8 @@ - return res; - } - --Mutex* Mutex::get_least_ranked_lock_besides_this(Mutex* locks) { -- Mutex *res, *tmp; -+Monitor* Monitor::get_least_ranked_lock_besides_this(Monitor* locks) { -+ Monitor *res, *tmp; - for (res = NULL, tmp = locks; tmp != NULL; tmp = tmp->next()) { - if (tmp != this && (res == NULL || tmp->rank() < res->rank())) { - res = tmp; -@@ -306,7 +1219,7 @@ - } - - --bool Mutex::contains(Mutex* locks, Mutex* lock) { -+bool Monitor::contains(Monitor* locks, Monitor * lock) { - for (; locks != NULL; locks = locks->next()) { - if (locks == lock) - return true; -@@ -315,7 +1228,12 @@ - } - #endif - --void Mutex::set_owner_implementation(Thread *new_owner) { -+// Called immediately after lock acquisition or release as a diagnostic -+// to track the lock-set of the thread and test for rank violations that -+// might indicate exposure to deadlock. -+// Rather like an EventListener for _owner (:>). -+ -+void Monitor::set_owner_implementation(Thread *new_owner) { - // This function is solely responsible for maintaining - // and checking the invariant that threads and locks - // are in a 1/N relation, with some some locks unowned. -@@ -326,17 +1244,17 @@ - // owner to another--it must be owned by NULL as an - // intermediate state. - -- if (new_owner != INVALID_THREAD) { -+ if (new_owner != NULL) { - // the thread is acquiring this lock - - assert(new_owner == Thread::current(), "Should I be doing this?"); -- assert(_owner == INVALID_THREAD, "setting the owner thread of an already owned mutex"); -+ assert(_owner == NULL, "setting the owner thread of an already owned mutex"); - _owner = new_owner; // set the owner - - // link "this" into the owned locks list - - #ifdef ASSERT // Thread::_owned_locks is under the same ifdef -- Mutex* locks = get_least_ranked_lock(new_owner->owned_locks()); -+ Monitor* locks = get_least_ranked_lock(new_owner->owned_locks()); - // Mutex::set_owner_implementation is a friend of Thread - - assert(this->rank() >= 0, "bad lock rank"); -@@ -379,13 +1297,13 @@ - Thread* old_owner = _owner; - debug_only(_last_owner = old_owner); - -- assert(old_owner != INVALID_THREAD, "removing the owner thread of an unowned mutex"); -+ assert(old_owner != NULL, "removing the owner thread of an unowned mutex"); - assert(old_owner == Thread::current(), "removing the owner thread of an unowned mutex"); - -- _owner = INVALID_THREAD; // set the owner -+ _owner = NULL; // set the owner - - #ifdef ASSERT -- Mutex *locks = old_owner->owned_locks(); -+ Monitor *locks = old_owner->owned_locks(); - - if (LogMultipleMutexLocking && locks != this) { - Events::log("thread " INTPTR_FORMAT " unlocks %s, still owns %s", old_owner, this->name(), locks->name()); -@@ -393,7 +1311,7 @@ - - // remove "this" from the owned locks list - -- Mutex *prev = NULL; -+ Monitor *prev = NULL; - bool found = false; - for (; locks != NULL; prev = locks, locks = locks->next()) { - if (locks == this) { -@@ -414,8 +1332,7 @@ - - - // Factored out common sanity checks for locking mutex'es. Used by lock() and try_lock() --void Mutex::check_prelock_state(Thread *thread) { -- assert(_lock_count >= -1, "sanity check"); -+void Monitor::check_prelock_state(Thread *thread) { - assert((!thread->is_Java_thread() || ((JavaThread *)thread)->thread_state() == _thread_in_vm) - || rank() == Mutex::special, "wrong thread state for using locks"); - if (StrictSafepointChecks) { -@@ -427,7 +1344,7 @@ - } - } - --void Mutex::check_block_state(Thread *thread) { -+void Monitor::check_block_state(Thread *thread) { - if (!_allow_vm_block && thread->is_VM_thread()) { - warning("VM thread blocked on lock"); - print(); -@@ -436,8 +1353,4 @@ - assert(_owner != thread, "deadlock: blocking on monitor owned by current thread"); - } - -- --void Mutex::trace(const char* operation) { --} -- - #endif // PRODUCT -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/mutex.hpp openjdk/hotspot/src/share/vm/runtime/mutex.hpp ---- openjdk6/hotspot/src/share/vm/runtime/mutex.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/mutex.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)mutex.hpp 1.68 07/05/05 17:06:50 JVM" --#endif - /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -25,49 +22,71 @@ - * - */ - --#ifdef ASSERT --class MutexHistogramElement : public HistogramElement { -- public: -- MutexHistogramElement(const char* elementname); --}; -- --class MutexContentionHistogramElement : public HistogramElement { -- public: -- MutexContentionHistogramElement(const char* elementname); --}; -- -- --#endif -- --// A simple Mutex for VM locking using OS primitives. Note that --// Mutex locking is NOT guaranteed to interoperate with the fast --// object locking, which is intentional: it reduces reliance on the --// fast locking mechanism as it is developed and tuned, and gives us --// a way out of all the recursive locking rat-holes that appear when --// we try to use a single locking mechanism. --// --// Implementation adapted from WIN32 Q&A by Jeffery Richter --// (implementation should be moved into platform specific file) -+// The SplitWord construct allows us to colocate the contention queue -+// (cxq) with the lock-byte. The queue elements are ParkEvents, which are -+// always aligned on 256-byte addresses - the least significant byte of -+// a ParkEvent is always 0. Colocating the lock-byte with the queue -+// allows us to easily avoid what would otherwise be a race in lock() -+// if we were to use two completely separate fields for the contention queue -+// and the lock indicator. Specifically, colocation renders us immune -+// from the race where a thread might enqueue itself in the lock() slow-path -+// immediately after the lock holder drops the outer lock in the unlock() -+// fast-path. - // -+// Colocation allows us to use a fast-path unlock() form that uses -+// A MEMBAR instead of a CAS. MEMBAR has lower local latency than CAS -+// on many platforms. - // --// NOTE WELL!! -+// See: -+// + http://blogs.sun.com/dave/entry/biased_locking_in_hotspot -+// + http://blogs.sun.com/dave/resource/synchronization-public2.pdf - // -+// Note that we're *not* using word-tearing the classic sense. -+// The lock() fast-path will CAS the lockword and the unlock() -+// fast-path will store into the lock-byte colocated within the lockword. -+// We depend on the fact that all our reference platforms have -+// coherent and atomic byte accesses. More precisely, byte stores -+// interoperate in a safe, sane, and expected manner with respect to -+// CAS, ST and LDs to the full-word containing the byte. -+// If you're porting HotSpot to a platform where that isn't the case -+// then you'll want change the unlock() fast path from: -+// STB;MEMBAR #storeload; LDN -+// to a full-word CAS of the lockword. -+ -+ -+union SplitWord { // full-word with separately addressable LSB -+ volatile intptr_t FullWord ; -+ volatile void * Address ; -+ volatile jbyte Bytes [sizeof(intptr_t)] ; -+} ; -+ -+// Endian-ness ... index of least-significant byte in SplitWord.Bytes[] -+#ifdef AMD64 // little -+ #define _LSBINDEX 0 -+#else -+#if IA32 // little -+ #define _LSBINDEX 0 -+#else -+#ifdef SPARC // big -+ #define _LSBINDEX (sizeof(intptr_t)-1) -+#else -+ #error "unknown architecture" -+#endif -+#endif -+#endif -+ -+class ParkEvent ; -+ - // See orderAccess.hpp. We assume throughout the VM that mutex lock and - // try_lock do fence-lock-acquire, and that unlock does a release-unlock, - // *in that order*. If their implementations change such that these - // assumptions are violated, a whole lot of code will break. - --class Mutex : public CHeapObj { -- private: -- // The following methods are machine-specific, and defined in mutex_.inline.hpp or mutex_.cpp -- bool lock_implementation(); -- bool try_lock_implementation(); -- void wait_for_lock_implementation(); -- void wait_for_lock_blocking_implementation(JavaThread *thread); -+class Monitor : public CHeapObj { - - public: -- // A special lock: Is a lock where you are guarantteed not to block while you are holding it, i.e., no -- // vm operation can happen, taking other locks, etc. -+ // A special lock: Is a lock where you are guaranteed not to block while you are -+ // holding it, i.e., no vm operation can happen, taking other locks, etc. - // NOTE: It is critical that the rank 'special' be the lowest (earliest) - // (except for "event"?) for the deadlock dection to work correctly. - // The rank native is only for use in Mutex's created by JVM_RawMonitorCreate, -@@ -91,37 +110,42 @@ - native = max_nonleaf + 1 - }; - -- protected: -- // Fields -- jint _lock_count; -- void* _lock_event; -- volatile bool _suppress_signal; // Used for sneaky locking -- Thread* volatile _owner; // The owner of the lock -- const char* _name; // Name of mutex --#ifdef ASSERT -- MutexHistogramElement *_histogram; -- MutexContentionHistogramElement *_contend_histogram; --#endif -+ // The WaitSet and EntryList linked lists are composed of ParkEvents. -+ // I use ParkEvent instead of threads as ParkEvents are immortal and -+ // type-stable, meaning we can safely unpark() a possibly stale -+ // list element in the unlock()-path. -+ -+ protected: // Monitor-Mutex metadata -+ SplitWord _LockWord ; // Contention queue (cxq) colocated with Lock-byte -+ enum LockWordBits { _LBIT=1 } ; -+ Thread * volatile _owner; // The owner of the lock -+ // Consider sequestering _owner on its own $line -+ // to aid future synchronization mechanisms. -+ ParkEvent * volatile _EntryList ; // List of threads waiting for entry -+ ParkEvent * volatile _OnDeck ; // heir-presumptive -+ volatile intptr_t _WaitLock [1] ; // Protects _WaitSet -+ ParkEvent * volatile _WaitSet ; // LL of ParkEvents -+ volatile bool _snuck; // Used for sneaky locking (evil). -+ const char * _name; // Name of mutex -+ int NotifyCount ; // diagnostic assist -+ double pad [8] ; // avoid false sharing - - // Debugging fields for naming, deadlock detection, etc. (some only used in debug mode) - #ifndef PRODUCT - bool _allow_vm_block; - debug_only(int _rank;) // rank (to avoid/detect potential deadlocks) -- debug_only(Mutex* _next;) // Used by a Thread to link up owned locks -+ debug_only(Monitor * _next;) // Used by a Thread to link up owned locks - debug_only(Thread* _last_owner;) // the last thread to own the lock -- debug_only(static bool contains(Mutex* locks, Mutex* lock);) -- debug_only(static Mutex* get_least_ranked_lock(Mutex* locks);) -- debug_only(Mutex* get_least_ranked_lock_besides_this(Mutex* locks);) -+ debug_only(static bool contains(Monitor * locks, Monitor * lock);) -+ debug_only(static Monitor * get_least_ranked_lock(Monitor * locks);) -+ debug_only(Monitor * get_least_ranked_lock_besides_this(Monitor * locks);) - #endif - - void set_owner_implementation(Thread* owner) PRODUCT_RETURN; -- void trace (const char* operation) PRODUCT_RETURN; - void check_prelock_state (Thread* thread) PRODUCT_RETURN; - void check_block_state (Thread* thread) PRODUCT_RETURN; - - // platform-dependent support code can go here (in os_.cpp) -- friend class MutexImplementation; -- friend class RawMonitor; - public: - enum { - _no_safepoint_check_flag = true, -@@ -129,19 +153,52 @@ - _as_suspend_equivalent_flag = true - }; - -- Mutex(int rank, const char *name, bool allow_vm_block = !_allow_vm_block_flag); -- ~Mutex(); -+ enum WaitResults { -+ CONDVAR_EVENT, // Wait returned because of condition variable notification -+ INTERRUPT_EVENT, // Wait returned because waiting thread was interrupted -+ NUMBER_WAIT_RESULTS -+ }; -+ -+ private: -+ int TrySpin (Thread * Self) ; -+ int TryLock () ; -+ int TryFast () ; -+ int AcquireOrPush (ParkEvent * ev) ; -+ void IUnlock (bool RelaxAssert) ; -+ void ILock (Thread * Self) ; -+ int IWait (Thread * Self, jlong timo); -+ int ILocked () ; -+ -+ protected: -+ static void ClearMonitor (Monitor * m) ; -+ Monitor() ; -+ -+ public: -+ Monitor(int rank, const char *name, bool allow_vm_block=false); -+ ~Monitor(); -+ -+ // Wait until monitor is notified (or times out). -+ // Defaults are to make safepoint checks, wait time is forever (i.e., -+ // zero), and not a suspend-equivalent condition. Returns true if wait -+ // times out; otherwise returns false. -+ bool wait(bool no_safepoint_check = !_no_safepoint_check_flag, -+ long timeout = 0, -+ bool as_suspend_equivalent = !_as_suspend_equivalent_flag); -+ bool notify(); -+ bool notify_all(); -+ - - void lock(); // prints out warning if VM thread blocks - void lock(Thread *thread); // overloaded with current thread - void unlock(); -- bool is_locked() const { return _owner != INVALID_THREAD; } -+ bool is_locked() const { return _owner != NULL; } - - bool try_lock(); // Like lock(), but unblocking. It returns false instead - - // Lock without safepoint check. Should ONLY be used by safepoint code and other code - // that is guaranteed not to block while running inside the VM. - void lock_without_safepoint_check(); -+ void lock_without_safepoint_check (Thread * Self) ; - - // Current owner - not not MT-safe. Can only be used to guarantee that - // the current running thread owns the lock -@@ -162,52 +219,56 @@ - debug_only(int rank() const { return _rank; }) - bool allow_vm_block() { return _allow_vm_block; } - -- debug_only(Mutex *next() const { return _next; }) -- debug_only(void set_next(Mutex *next) { _next = next; }) -+ debug_only(Monitor *next() const { return _next; }) -+ debug_only(void set_next(Monitor *next) { _next = next; }) - #endif - - void set_owner(Thread* owner) { - #ifndef PRODUCT - set_owner_implementation(owner); -- debug_only(void verify_mutex_rank(Thread* thr)); -+ debug_only(void verify_Monitor(Thread* thr)); - #else - _owner = owner; - #endif - } - -- static Thread* INVALID_THREAD; // Value of _owner when unowned. (i.e., lock is unlocked) - }; - -+// Normally we'd expect Monitor to extend Mutex in the sense that a monitor -+// constructed from pthreads primitives might extend a mutex by adding -+// a condvar and some extra metadata. In fact this was the case until J2SE7. -+// -+// Currently, however, the base object is a monitor. Monitor contains all the -+// logic for wait(), notify(), etc. Mutex extends monitor and restricts the -+// visiblity of wait(), notify(), and notify_all(). -+// -+// Another viable alternative would have been to have Monitor extend Mutex and -+// implement all the normal mutex and wait()-notify() logic in Mutex base class. -+// The wait()-notify() facility would be exposed via special protected member functions -+// (e.g., _Wait() and _Notify()) in Mutex. Monitor would extend Mutex and expose wait() -+// as a call to _Wait(). That is, the public wait() would be a wrapper for the protected -+// _Wait(). -+// -+// An even better alternative is to simply eliminate Mutex:: and use Monitor:: instead. -+// After all, monitors are sufficient for Java-level synchronization. At one point in time -+// there may have been some benefit to having distinct mutexes and monitors, but that time -+// has past. -+// -+// The Mutex/Monitor design parallels that of Java-monitors, being based on -+// thread-specific park-unpark platform-specific primitives. - --// A Monitor is a Mutex with a built in condition variable. It allows a thread, to --// temporarily to give up the lock and wait on the lock, until it is notified. --class Monitor : public Mutex { -- protected: -- void* _event; // Manual-reset event for notifications -- long _counter; // Current number of notifications -- long _waiters; // Number of threads waiting for notification -- long _tickets; // Number of waiters to be notified -- -- enum WaitResults { -- CONDVAR_EVENT, // Wait returned because of condition variable notification -- INTERRUPT_EVENT, // Wait returned because waiting thread was interrupted -- NUMBER_WAIT_RESULTS -- }; - -- friend class RawMonitor; -+class Mutex : public Monitor { // degenerate Monitor - public: -- Monitor(int rank, const char *name, bool allow_vm_block=false); -- ~Monitor(); -- -- // Wait until monitor is notified (or times out). -- // Defaults are to make safepoint checks, wait time is forever (i.e., -- // zero), and not a suspend-equivalent condition. Returns true if wait -- // times out; otherwise returns false. -- bool wait(bool no_safepoint_check = !_no_safepoint_check_flag, -- long timeout = 0, -- bool as_suspend_equivalent = !_as_suspend_equivalent_flag); -- bool notify(); -- bool notify_all(); -+ Mutex (int rank, const char *name, bool allow_vm_block=false); -+ ~Mutex () ; -+ private: -+ bool notify () { ShouldNotReachHere(); return false; } -+ bool notify_all() { ShouldNotReachHere(); return false; } -+ bool wait (bool no_safepoint_check, long timeout, bool as_suspend_equivalent) { -+ ShouldNotReachHere() ; -+ return false ; -+ } - }; - - /* -@@ -218,12 +279,12 @@ - * 6271289 -- - * To avoid errors where an os thread expires but the JavaThread still - * exists, Parkers are immortal (type-stable) and are recycled across -- * new threads. This parallels the Event and ParkEvent implementation. -- * Because park-unpark alow spurious wakeups it is harmless if an -+ * new threads. This parallels the ParkEvent implementation. -+ * Because park-unpark allow spurious wakeups it is harmless if an - * unpark call unparks a new thread using the old Parker reference. - * - * In the future we'll want to think about eliminating Parker and using -- * ParkEvent instead. There's consider duplication between the two -+ * ParkEvent instead. There's considerable duplication between the two - * services. - * - */ -@@ -255,4 +316,3 @@ - static Parker * volatile FreeList ; - static volatile int ListLock ; - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/mutexLocker.cpp openjdk/hotspot/src/share/vm/runtime/mutexLocker.cpp ---- openjdk6/hotspot/src/share/vm/runtime/mutexLocker.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/mutexLocker.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)mutexLocker.cpp 1.178 07/06/19 03:54:19 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -28,7 +25,13 @@ - #include "incls/_precompiled.incl" - #include "incls/_mutexLocker.cpp.incl" - --// Mutexes used in the VM (see comment in mutexLocker.hpp) -+// Mutexes used in the VM (see comment in mutexLocker.hpp): -+// -+// Note that the following pointers are effectively final -- after having been -+// set at JVM startup-time, they should never be subsequently mutated. -+// Instead of using pointers to malloc()ed monitors and mutexes we should consider -+// eliminating the indirection and using instances instead. -+// Consider using GCC's __read_mostly. - - Mutex* Patching_lock = NULL; - Monitor* SystemDictionary_lock = NULL; -@@ -105,11 +108,11 @@ - Monitor* LowMemory_lock = NULL; - - #define MAX_NUM_MUTEX 128 --static Mutex* _mutex_array[MAX_NUM_MUTEX]; -+static Monitor * _mutex_array[MAX_NUM_MUTEX]; - static int _num_mutex; - - #ifdef ASSERT --void assert_locked_or_safepoint(const Mutex* lock) { -+void assert_locked_or_safepoint(const Monitor * lock) { - // check if this thread owns the lock (common case) - if (IgnoreLockingAssertions) return; - assert(lock != NULL, "Need non-NULL lock"); -@@ -123,7 +126,7 @@ - } - - // a stronger assertion than the above --void assert_lock_strong(const Mutex* lock) { -+void assert_lock_strong(const Monitor * lock) { - if (IgnoreLockingAssertions) return; - assert(lock != NULL, "Need non-NULL lock"); - if (lock->owned_by_self()) return; -@@ -232,7 +235,7 @@ - - } - --GCMutexLocker::GCMutexLocker(Mutex* mutex) { -+GCMutexLocker::GCMutexLocker(Monitor * mutex) { - if (SafepointSynchronize::is_at_safepoint()) { - _locked = false; - } else { -@@ -249,7 +252,7 @@ - bool none = true; - for (int i = 0; i < _num_mutex; i++) { - // see if it has an owner -- if (_mutex_array[i]->owner() != Mutex::INVALID_THREAD) { -+ if (_mutex_array[i]->owner() != NULL) { - if (none) { - // print format used by Mutex::print_on_error() - st->print_cr(" ([mutex/lock_event])"); -@@ -261,4 +264,3 @@ - } - if (none) st->print_cr("None"); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/mutexLocker.hpp openjdk/hotspot/src/share/vm/runtime/mutexLocker.hpp ---- openjdk6/hotspot/src/share/vm/runtime/mutexLocker.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/mutexLocker.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)mutexLocker.hpp 1.150 07/06/19 03:54:12 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -122,9 +119,9 @@ - - class MutexLocker: StackObj { - private: -- Mutex* _mutex; -+ Monitor * _mutex; - public: -- MutexLocker(Mutex* mutex) { -+ MutexLocker(Monitor * mutex) { - assert(mutex->rank() != Mutex::special, - "Special ranked mutex should only use MutexLockerEx"); - _mutex = mutex; -@@ -132,7 +129,7 @@ - } - - // Overloaded constructor passing current thread -- MutexLocker(Mutex* mutex, Thread *thread) { -+ MutexLocker(Monitor * mutex, Thread *thread) { - assert(mutex->rank() != Mutex::special, - "Special ranked mutex should only use MutexLockerEx"); - _mutex = mutex; -@@ -147,8 +144,8 @@ - - // for debugging: check that we're already owning this lock (or are at a safepoint) - #ifdef ASSERT --void assert_locked_or_safepoint(const Mutex* lock); --void assert_lock_strong(const Mutex* lock); -+void assert_locked_or_safepoint(const Monitor * lock); -+void assert_lock_strong(const Monitor * lock); - #else - #define assert_locked_or_safepoint(lock) - #define assert_lock_strong(lock) -@@ -163,9 +160,9 @@ - - class MutexLockerEx: public StackObj { - private: -- Mutex* _mutex; -+ Monitor * _mutex; - public: -- MutexLockerEx(Mutex* mutex, bool no_safepoint_check = !Mutex::_no_safepoint_check_flag) { -+ MutexLockerEx(Monitor * mutex, bool no_safepoint_check = !Mutex::_no_safepoint_check_flag) { - _mutex = mutex; - if (_mutex != NULL) { - assert(mutex->rank() > Mutex::special || no_safepoint_check, -@@ -190,7 +187,7 @@ - - class MonitorLockerEx: public MutexLockerEx { - private: -- Monitor* _monitor; -+ Monitor * _monitor; - public: - MonitorLockerEx(Monitor* monitor, - bool no_safepoint_check = !Mutex::_no_safepoint_check_flag): -@@ -242,10 +239,10 @@ - - class GCMutexLocker: public StackObj { - private: -- Mutex* _mutex; -+ Monitor * _mutex; - bool _locked; - public: -- GCMutexLocker(Mutex* mutex); -+ GCMutexLocker(Monitor * mutex); - ~GCMutexLocker() { if (_locked) _mutex->unlock(); } - }; - -@@ -256,10 +253,10 @@ - - class MutexUnlocker: StackObj { - private: -- Mutex* _mutex; -+ Monitor * _mutex; - - public: -- MutexUnlocker(Mutex* mutex) { -+ MutexUnlocker(Monitor * mutex) { - _mutex = mutex; - _mutex->unlock(); - } -@@ -274,11 +271,11 @@ - - class MutexUnlockerEx: StackObj { - private: -- Mutex* _mutex; -+ Monitor * _mutex; - bool _no_safepoint_check; - - public: -- MutexUnlockerEx(Mutex* mutex, bool no_safepoint_check = !Mutex::_no_safepoint_check_flag) { -+ MutexUnlockerEx(Monitor * mutex, bool no_safepoint_check = !Mutex::_no_safepoint_check_flag) { - _mutex = mutex; - _no_safepoint_check = no_safepoint_check; - _mutex->unlock(); -@@ -305,10 +302,10 @@ - // - class VerifyMutexLocker: StackObj { - private: -- Mutex* _mutex; -+ Monitor * _mutex; - bool _reentrant; - public: -- VerifyMutexLocker(Mutex* mutex) { -+ VerifyMutexLocker(Monitor * mutex) { - _mutex = mutex; - _reentrant = mutex->owned_by_self(); - if (!_reentrant) { -@@ -326,4 +323,3 @@ - }; - - #endif -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/objectMonitor.hpp openjdk/hotspot/src/share/vm/runtime/objectMonitor.hpp ---- openjdk6/hotspot/src/share/vm/runtime/objectMonitor.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/objectMonitor.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)objectMonitor.hpp 1.41 07/05/17 16:06:18 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -159,7 +156,6 @@ - private: - friend class ObjectSynchronizer; - friend class ObjectWaiter; -- friend class RawMonitor; - friend class VMStructs; - - // WARNING: this must be the very first word of ObjectMonitor -@@ -210,7 +206,3 @@ - intptr_t StatA, StatsB ; - - }; -- -- -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/objectMonitor.inline.hpp openjdk/hotspot/src/share/vm/runtime/objectMonitor.inline.hpp ---- openjdk6/hotspot/src/share/vm/runtime/objectMonitor.inline.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/objectMonitor.inline.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)objectMonitor.inline.hpp 1.24 07/05/05 17:06:52 JVM" --#endif - /* - * Copyright 1998-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/orderAccess.cpp openjdk/hotspot/src/share/vm/runtime/orderAccess.cpp ---- openjdk6/hotspot/src/share/vm/runtime/orderAccess.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/orderAccess.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)orderAccess.cpp 1.9 07/05/05 17:06:53 JVM" --#endif - /* - * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/orderAccess.hpp openjdk/hotspot/src/share/vm/runtime/orderAccess.hpp ---- openjdk6/hotspot/src/share/vm/runtime/orderAccess.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/orderAccess.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)orderAccess.hpp 1.11 07/05/05 17:06:52 JVM" --#endif - /* - * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/os.cpp openjdk/hotspot/src/share/vm/runtime/os.cpp ---- openjdk6/hotspot/src/share/vm/runtime/os.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/os.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)os.cpp 1.183 07/06/19 03:53:14 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -39,6 +36,8 @@ - volatile jlong os::_global_time = 0; - volatile int os::_global_time_lock = 0; - bool os::_use_global_time = false; -+size_t os::_page_sizes[os::page_sizes_max]; -+ - #ifndef PRODUCT - int os::num_mallocs = 0; // # of calls to malloc/realloc - size_t os::alloc_bytes = 0; // # of bytes allocated -@@ -1013,7 +1012,7 @@ - // handler or a println uses at least 8k stack of VM and native code - // respectively. - const int framesize_in_bytes = -- AbstractInterpreter::size_top_interpreter_activation(method()) * wordSize; -+ Interpreter::size_top_interpreter_activation(method()) * wordSize; - int reserved_area = ((StackShadowPages + StackRedPages + StackYellowPages) - * vm_page_size()) + framesize_in_bytes; - // The very lower end of the stack -@@ -1021,6 +1020,46 @@ - return (sp > (stack_limit + reserved_area)); - } - -+size_t os::page_size_for_region(size_t region_min_size, size_t region_max_size, -+ uint min_pages) -+{ -+ assert(min_pages > 0, "sanity"); -+ if (UseLargePages) { -+ const size_t max_page_size = region_max_size / min_pages; -+ -+ for (unsigned int i = 0; _page_sizes[i] != 0; ++i) { -+ const size_t sz = _page_sizes[i]; -+ const size_t mask = sz - 1; -+ if ((region_min_size & mask) == 0 && (region_max_size & mask) == 0) { -+ // The largest page size with no fragmentation. -+ return sz; -+ } -+ -+ if (sz <= max_page_size) { -+ // The largest page size that satisfies the min_pages requirement. -+ return sz; -+ } -+ } -+ } -+ -+ return vm_page_size(); -+} -+ -+#ifndef PRODUCT -+void os::trace_page_sizes(const char* str, const size_t region_min_size, -+ const size_t region_max_size, const size_t page_size, -+ const char* base, const size_t size) -+{ -+ if (TracePageSizes) { -+ tty->print_cr("%s: min=" SIZE_FORMAT " max=" SIZE_FORMAT -+ " pg_sz=" SIZE_FORMAT " base=" PTR_FORMAT -+ " size=" SIZE_FORMAT, -+ str, region_min_size, region_max_size, -+ page_size, base, size); -+ } -+} -+#endif // #ifndef PRODUCT -+ - // This is the working definition of a server class machine: - // >= 2 physical CPU's and >=2GB of memory, with some fuzz - // because the graphics memory (?) sometimes masks physical memory. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/os.hpp openjdk/hotspot/src/share/vm/runtime/os.hpp ---- openjdk6/hotspot/src/share/vm/runtime/os.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/os.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)os.hpp 1.220 07/06/19 03:53:08 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -63,6 +60,8 @@ - - class os: AllStatic { - private: -+ enum { page_sizes_max = 9 }; // Size of _page_sizes array (8 plus a sentinel) -+ - static OSThread* _starting_thread; - static address _polling_page; - static volatile int32_t * _mem_serialize_page; -@@ -70,6 +69,13 @@ - static volatile jlong _global_time; - static volatile int _global_time_lock; - static bool _use_global_time; -+ static size_t _page_sizes[page_sizes_max]; -+ -+ static void init_page_sizes(size_t default_page_size) { -+ _page_sizes[0] = default_page_size; -+ _page_sizes[1] = 0; // sentinel -+ } -+ - public: - - static void init(void); // Called before command line parsing -@@ -155,9 +161,38 @@ - static bool stack_shadow_pages_available(Thread *thread, methodHandle method); - - // OS interface to Virtual Memory -+ -+ // Return the default page size. - static int vm_page_size(); -+ -+ // Return the page size to use for a region of memory. The min_pages argument -+ // is a hint intended to limit fragmentation; it says the returned page size -+ // should be <= region_max_size / min_pages. Because min_pages is a hint, -+ // this routine may return a size larger than region_max_size / min_pages. -+ // -+ // The current implementation ignores min_pages if a larger page size is an -+ // exact multiple of both region_min_size and region_max_size. This allows -+ // larger pages to be used when doing so would not cause fragmentation; in -+ // particular, a single page can be used when region_min_size == -+ // region_max_size == a supported page size. -+ static size_t page_size_for_region(size_t region_min_size, -+ size_t region_max_size, -+ uint min_pages); -+ -+ // Method for tracing page sizes returned by the above method; enabled by -+ // TracePageSizes. The region_{min,max}_size parameters should be the values -+ // passed to page_size_for_region() and page_size should be the result of that -+ // call. The (optional) base and size parameters should come from the -+ // ReservedSpace base() and size() methods. -+ static void trace_page_sizes(const char* str, const size_t region_min_size, -+ const size_t region_max_size, -+ const size_t page_size, -+ const char* base = NULL, -+ const size_t size = 0) PRODUCT_RETURN; -+ - static int vm_allocation_granularity(); -- static char* reserve_memory(size_t bytes, char* addr = 0); -+ static char* reserve_memory(size_t bytes, char* addr = 0, -+ size_t alignment_hint = 0); - static char* attempt_reserve_memory_at(size_t bytes, char* addr); - static void split_reserved_memory(char *base, size_t size, - size_t split, bool realloc); -@@ -292,7 +327,15 @@ - static int naked_sleep(); - static void infinite_sleep(); // never returns, use with CAUTION - static void yield(); // Yields to all threads with same priority -- static void NakedYield () ; -+ enum YieldResult { -+ YIELD_SWITCHED = 1, // caller descheduled, other ready threads exist & ran -+ YIELD_NONEREADY = 0, // No other runnable/ready threads. -+ // platform-specific yield return immediately -+ YIELD_UNKNOWN = -1 // Unknown: platform doesn't support _SWITCHED or _NONEREADY -+ // YIELD_SWITCHED and YIELD_NONREADY imply the platform supports a "strong" -+ // yield that can be used in lieu of blocking. -+ } ; -+ static YieldResult NakedYield () ; - static void yield_all(int attempts = 0); // Yields to all other threads including lower priority - static void loop_breaker(int attempts); // called from within tight loops to possibly influence time-sharing - static OSReturn set_priority(Thread* thread, ThreadPriority priority); -@@ -316,6 +359,9 @@ - static int message_box(const char* title, const char* message); - static char* do_you_want_to_debug(const char* message); - -+ // run cmd in a separate process and return its exit code; or -1 on failures -+ static int fork_and_exec(char *cmd); -+ - // Set file to send error reports. - static void set_error_file(const char *logfile); - -@@ -548,5 +594,3 @@ - extern "C" int SpinPause () ; - extern "C" int SafeFetch32 (int * adr, int errValue) ; - extern "C" intptr_t SafeFetchN (intptr_t * adr, intptr_t errValue) ; -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/osThread.cpp openjdk/hotspot/src/share/vm/runtime/osThread.cpp ---- openjdk6/hotspot/src/share/vm/runtime/osThread.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/osThread.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)osThread.cpp 1.29 07/05/05 17:06:53 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -56,4 +53,3 @@ - default: st->print("unknown state %d", _state); break; - } - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/osThread.hpp openjdk/hotspot/src/share/vm/runtime/osThread.hpp ---- openjdk6/hotspot/src/share/vm/runtime/osThread.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/osThread.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)osThread.hpp 1.40 07/05/05 17:06:53 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/perfData.cpp openjdk/hotspot/src/share/vm/runtime/perfData.cpp ---- openjdk6/hotspot/src/share/vm/runtime/perfData.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/perfData.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)perfData.cpp 1.22 07/05/05 17:06:52 JVM" --#endif - /* - * Copyright 2001-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/perfData.hpp openjdk/hotspot/src/share/vm/runtime/perfData.hpp ---- openjdk6/hotspot/src/share/vm/runtime/perfData.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/perfData.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)perfData.hpp 1.24 07/05/05 17:06:54 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/perfMemory.cpp openjdk/hotspot/src/share/vm/runtime/perfMemory.cpp ---- openjdk6/hotspot/src/share/vm/runtime/perfMemory.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/perfMemory.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)perfMemory.cpp 1.27 07/05/05 17:06:53 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -227,7 +224,7 @@ - char* PerfMemory::get_perfdata_file_path() { - char* dest_file = NULL; - -- if (PerfDataSaveFile[0] != '\0') { -+ if (PerfDataSaveFile != NULL) { - // dest_file_name stores the validated file name if file_name - // contains %p which will be replaced by pid. - dest_file = NEW_C_HEAP_ARRAY(char, JVM_MAXPATHLEN); -@@ -249,4 +246,3 @@ - - return dest_file; - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/perfMemory.hpp openjdk/hotspot/src/share/vm/runtime/perfMemory.hpp ---- openjdk6/hotspot/src/share/vm/runtime/perfMemory.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/perfMemory.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)perfMemory.hpp 1.23 07/05/05 17:06:54 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/prefetch.hpp openjdk/hotspot/src/share/vm/runtime/prefetch.hpp ---- openjdk6/hotspot/src/share/vm/runtime/prefetch.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/prefetch.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)prefetch.hpp 1.9 07/05/05 17:06:53 JVM" --#endif - /* - * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/reflection.cpp openjdk/hotspot/src/share/vm/runtime/reflection.cpp ---- openjdk6/hotspot/src/share/vm/runtime/reflection.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/reflection.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)reflection.cpp 1.178 07/05/23 10:54:08 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -298,7 +295,7 @@ - - oop Reflection:: basic_type_arrayklass_to_mirror(klassOop basic_type_arrayklass, TRAPS) { - BasicType type = typeArrayKlass::cast(basic_type_arrayklass)->element_type(); -- return SystemDictionary::java_mirror(type); -+ return Universe::java_mirror(type); - } - - -@@ -625,7 +622,7 @@ - // Basic types - BasicType type = vmSymbols::signature_type(signature()); - if (type != T_OBJECT) { -- return Handle(THREAD, SystemDictionary::java_mirror(type)); -+ return Handle(THREAD, Universe::java_mirror(type)); - } - - oop loader = instanceKlass::cast(k())->class_loader(); -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/reflection.hpp openjdk/hotspot/src/share/vm/runtime/reflection.hpp ---- openjdk6/hotspot/src/share/vm/runtime/reflection.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/reflection.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)reflection.hpp 1.46 07/05/05 17:06:54 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -163,4 +160,3 @@ - #endif /* SUPPORT_OLD_REFLECTION */ - - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/reflectionCompat.hpp openjdk/hotspot/src/share/vm/runtime/reflectionCompat.hpp ---- openjdk6/hotspot/src/share/vm/runtime/reflectionCompat.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/reflectionCompat.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)reflectionCompat.hpp 1.14 07/05/05 17:06:54 JVM" --#endif - /* - * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/reflectionUtils.cpp openjdk/hotspot/src/share/vm/runtime/reflectionUtils.cpp ---- openjdk6/hotspot/src/share/vm/runtime/reflectionUtils.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/reflectionUtils.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)reflectionUtils.cpp 1.15 07/05/05 17:06:54 JVM" --#endif - /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/reflectionUtils.hpp openjdk/hotspot/src/share/vm/runtime/reflectionUtils.hpp ---- openjdk6/hotspot/src/share/vm/runtime/reflectionUtils.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/reflectionUtils.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)reflectionUtils.hpp 1.16 07/05/05 17:06:54 JVM" --#endif - /* - * Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/registerMap.hpp openjdk/hotspot/src/share/vm/runtime/registerMap.hpp ---- openjdk6/hotspot/src/share/vm/runtime/registerMap.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/registerMap.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)registerMap.hpp 1.16 07/05/05 17:06:54 JVM" --#endif - /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/relocator.cpp openjdk/hotspot/src/share/vm/runtime/relocator.cpp ---- openjdk6/hotspot/src/share/vm/runtime/relocator.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/relocator.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)relocator.cpp 1.40 07/05/05 17:06:54 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/relocator.hpp openjdk/hotspot/src/share/vm/runtime/relocator.hpp ---- openjdk6/hotspot/src/share/vm/runtime/relocator.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/relocator.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)relocator.hpp 1.27 07/05/05 17:06:54 JVM" --#endif - /* - * Copyright 1997-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -119,4 +116,3 @@ - _listener->relocated(bci, delta, new_code_length); - } - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/rframe.cpp openjdk/hotspot/src/share/vm/runtime/rframe.cpp ---- openjdk6/hotspot/src/share/vm/runtime/rframe.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/rframe.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)rframe.cpp 1.41 07/05/05 17:06:52 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -171,4 +168,3 @@ - void DeoptimizedRFrame::print() { - RFrame::print("deopt."); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/rframe.hpp openjdk/hotspot/src/share/vm/runtime/rframe.hpp ---- openjdk6/hotspot/src/share/vm/runtime/rframe.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/rframe.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)rframe.hpp 1.23 07/05/05 17:06:49 JVM" --#endif - /* - * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -118,5 +115,3 @@ - public: - void print(); - }; -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/safepoint.cpp openjdk/hotspot/src/share/vm/runtime/safepoint.cpp ---- openjdk6/hotspot/src/share/vm/runtime/safepoint.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/safepoint.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)safepoint.cpp 1.305 07/05/29 09:44:27 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -37,6 +34,7 @@ - volatile int SafepointSynchronize::_safepoint_counter = 0; - static volatile int PageArmed = 0 ; // safepoint polling page is RO|RW vs PROT_NONE - static volatile int TryingToBlock = 0 ; // proximate value -- for advisory use only -+static bool timeout_error_printed = false; - - // Roll all threads forward to a safepoint and suspend them all - void SafepointSynchronize::begin() { -@@ -81,8 +79,7 @@ - // Save the starting time, so that it can be compared to see if this has taken - // too long to complete. - jlong safepoint_limit_time; -- static bool timeout_error_printed = false; -- -+ timeout_error_printed = false; - - // Begin the process of bringing the system to a safepoint. - // Java threads can be in several different states and are -@@ -129,7 +126,7 @@ - } - - // Make interpreter safepoint aware -- AbstractInterpreter::notice_safepoints(); -+ Interpreter::notice_safepoints(); - - if (UseCompilerSafepoints && DeferPollingPageLoopCount < 0) { - // Make polling safepoint aware -@@ -148,7 +145,7 @@ - #endif // ASSERT - - if (SafepointTimeout) -- safepoint_limit_time = os::javaTimeMillis() + (jlong)SafepointTimeoutDelay; -+ safepoint_limit_time = os::javaTimeNanos() + (jlong)SafepointTimeoutDelay * MICROUNITS; - - // Iterate through all threads until it have been determined how to stop them all at a safepoint - unsigned int iterations = 0; -@@ -172,36 +169,15 @@ - } - } - -- if (PrintSafepointStatistics && iterations == 0) { -+ if ( (PrintSafepointStatistics || (PrintSafepointStatisticsTimeout > 0)) -+ && iterations == 0) { - begin_statistics(nof_threads, still_running); - } - - if (still_running > 0) { - // Check for if it takes to long -- if (SafepointTimeout && safepoint_limit_time < os::javaTimeMillis()) { -- if (!timeout_error_printed) { -- timeout_error_printed = true; -- // Print out the thread IDs which didn't reach the safepoint -- // for debugging purposes (useful when there are lots of -- // threads in the debugger) -- tty->print_cr("# SafepointSynchronize::begin: Fatal error:"); -- tty->print_cr("# SafepointSynchronize::begin: Timed out while attempting to reach a safepoint."); -- tty->print_cr("# SafepointSynchronize::begin: Threads which did not reach the safepoint:"); -- for(JavaThread *cur = Threads::first(); cur; cur = cur->next()) { -- ThreadSafepointState *cur_state = cur->safepoint_state(); -- if (cur_state->is_running()) { -- tty->print("# "); -- cur_state->print(); -- cur->osthread()->print(); -- tty->print_cr(""); -- } -- } -- tty->print_cr("# SafepointSynchronize::begin: (End of list)"); -- } -- -- if (DieOnSafepointTimeout) { -- fatal("Safepoint Timeout"); -- } -+ if (SafepointTimeout && safepoint_limit_time < os::javaTimeNanos()) { -+ print_safepoint_timeout(_spinning_timeout); - } - - // Spin to avoid context switching. -@@ -294,35 +270,11 @@ - Safepoint_lock->wait(true); // true, means with no safepoint checks - } else { - // Compute remaining time -- jlong remaining_time = safepoint_limit_time - os::javaTimeMillis(); -+ jlong remaining_time = safepoint_limit_time - os::javaTimeNanos(); - - // If there is no remaining time, then there is an error -- if (remaining_time < 0 || Safepoint_lock->wait(true, remaining_time)) { -- if (!timeout_error_printed) { -- timeout_error_printed = true; -- // Print out the thread IDs which didn't reach the safepoint -- // for debugging purposes (useful when there are lots of -- // threads in the debugger) -- tty->print_cr("# SafepointSynchronize::begin: Fatal error:"); -- tty->print_cr("# SafepointSynchronize::begin: Timed out while waiting for all threads to stop."); -- tty->print_cr("# SafepointSynchronize::begin: Threads which did not reach the safepoint:"); -- for(JavaThread *cur = Threads::first(); cur; cur = cur->next()) { -- ThreadSafepointState *cur_state = cur->safepoint_state(); -- if (cur_state->type() == ThreadSafepointState::_call_back) { -- if (!cur_state->has_called_back()) { -- tty->print("# "); -- cur_state->print(); -- cur->osthread()->print(); -- tty->print_cr(""); -- } -- } -- } -- tty->print_cr("# SafepointSynchronize::begin: (End of list)"); -- } -- -- if (DieOnSafepointTimeout) { -- fatal("Safepoint Timeout"); -- } -+ if (remaining_time < 0 || Safepoint_lock->wait(true, remaining_time / MICROUNITS)) { -+ print_safepoint_timeout(_blocking_timeout); - } - } - } -@@ -330,10 +282,12 @@ - - #ifndef PRODUCT - if (SafepointTimeout) { -- jlong current_time = os::javaTimeMillis(); -+ jlong current_time = os::javaTimeNanos(); - if (safepoint_limit_time < current_time) { -- tty->print_cr("# SafepointSynchronize: Finished after %.4f seconds", -- 0.001 * ((double)current_time - (double)safepoint_limit_time + (double)SafepointTimeoutDelay) ); -+ tty->print_cr("# SafepointSynchronize: Finished after " -+ INT64_FORMAT_W(6) " ms", -+ ((current_time - safepoint_limit_time) / MICROUNITS + -+ SafepointTimeoutDelay)); - } - } - #endif -@@ -397,7 +351,7 @@ - } - - // Remove safepoint check from interpreter -- AbstractInterpreter::ignore_safepoints(); -+ Interpreter::ignore_safepoints(); - - { - MutexLocker mu(Safepoint_lock); -@@ -739,6 +693,51 @@ - // print_me(sp,stack_copy,was_oops); - } - -+ -+void SafepointSynchronize::print_safepoint_timeout(SafepointTimeoutReason reason) { -+ if (!timeout_error_printed) { -+ timeout_error_printed = true; -+ // Print out the thread infor which didn't reach the safepoint for debugging -+ // purposes (useful when there are lots of threads in the debugger). -+ tty->print_cr(""); -+ tty->print_cr("# SafepointSynchronize::begin: Timeout detected:"); -+ if (reason == _spinning_timeout) { -+ tty->print_cr("# SafepointSynchronize::begin: Timed out while spinning to reach a safepoint."); -+ } else if (reason == _blocking_timeout) { -+ tty->print_cr("# SafepointSynchronize::begin: Timed out while waiting for threads to stop."); -+ } -+ -+ tty->print_cr("# SafepointSynchronize::begin: Threads which did not reach the safepoint:"); -+ ThreadSafepointState *cur_state; -+ ResourceMark rm; -+ for(JavaThread *cur_thread = Threads::first(); cur_thread; -+ cur_thread = cur_thread->next()) { -+ cur_state = cur_thread->safepoint_state(); -+ -+ if (cur_thread->thread_state() != _thread_blocked && -+ ((reason == _spinning_timeout && cur_state->is_running()) || -+ (reason == _blocking_timeout && !cur_state->has_called_back()))) { -+ tty->print("# "); -+ cur_thread->print(); -+ tty->print_cr(""); -+ } -+ } -+ tty->print_cr("# SafepointSynchronize::begin: (End of list)"); -+ } -+ -+ // To debug the long safepoint, specify both DieOnSafepointTimeout & -+ // ShowMessageBoxOnError. -+ if (DieOnSafepointTimeout) { -+ char msg[1024]; -+ VM_Operation *op = VMThread::vm_operation(); -+ sprintf(msg, "Safepoint sync time longer than %d ms detected when executing %s.", -+ SafepointTimeoutDelay, -+ op != NULL ? op->name() : "no vm operation"); -+ fatal(msg); -+ } -+} -+ -+ - // ------------------------------------------------------------------------------------------------------- - // Implementation of ThreadSafepointState - -@@ -968,8 +967,11 @@ - static jlong last_safepoint_start_time = 0; - static jlong sync_end_time = 0; - static bool need_to_track_page_armed_status = false; -+static bool init_done = false; -+ -+void SafepointSynchronize::deferred_initialize_stat() { -+ if (init_done) return; - --void SafepointSynchronize::initialize_stat() { - if (PrintSafepointStatisticsCount <= 0) { - fatal("Wrong PrintSafepointStatisticsCount"); - } -@@ -1005,9 +1007,12 @@ - } - - tty->print_cr("page_trap_count"); -+ -+ init_done = true; - } - - void SafepointSynchronize::begin_statistics(int nof_threads, int nof_running) { -+ deferred_initialize_stat(); - - SafepointStats *spstat = &_safepoint_stats[_cur_stat_index]; - -@@ -1140,8 +1145,7 @@ - // print_statistics to print out the rest of the sampling. Then - // it tries to summarize the sampling. - void SafepointSynchronize::print_stat_on_exit() { -- assert(Thread::current()->is_VM_thread(), -- "print_stat_on_exit not called on VMThread"); -+ if (_safepoint_stats == NULL) return; - - SafepointStats *spstat = &_safepoint_stats[_cur_stat_index]; - -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/safepoint.hpp openjdk/hotspot/src/share/vm/runtime/safepoint.hpp ---- openjdk6/hotspot/src/share/vm/runtime/safepoint.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/safepoint.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)safepoint.hpp 1.103 07/05/26 16:02:40 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -62,6 +59,11 @@ - _other_thread = 2 - }; - -+ enum SafepointTimeoutReason { -+ _spinning_timeout = 0, -+ _blocking_timeout = 1 -+ }; -+ - typedef struct { - int _vmop_type; // type of VM operation triggers the safepoint - int _nof_total_threads; // total number of Java threads -@@ -107,6 +109,10 @@ - inline static void inc_page_trap_count() { - Atomic::inc(&_safepoint_stats[_cur_stat_index]._nof_threads_hit_page_trap); - } -+ -+ // For debug long safepoint -+ static void print_safepoint_timeout(SafepointTimeoutReason timeout_reason); -+ - public: - - // Main entry points -@@ -142,7 +148,7 @@ - static void print_state() PRODUCT_RETURN; - static void safepoint_msg(const char* format, ...) PRODUCT_RETURN; - -- static void initialize_stat(); -+ static void deferred_initialize_stat(); - static void print_stat_on_exit(); - inline static void inc_vmop_coalesced_count() { _coalesced_vmop_count++; } - -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/sharedRuntime.cpp openjdk/hotspot/src/share/vm/runtime/sharedRuntime.cpp ---- openjdk6/hotspot/src/share/vm/runtime/sharedRuntime.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/sharedRuntime.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)sharedRuntime.cpp 1.382 07/07/19 12:19:08 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -470,11 +467,6 @@ - throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_AbstractMethodError()); - JRT_END - --JRT_ENTRY(void, SharedRuntime::throw_IncompatibleClassChangeError(JavaThread* thread)) -- // These errors occur only at call sites -- throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_IncompatibleClassChangeError(), "vtable stub"); --JRT_END -- - JRT_ENTRY(void, SharedRuntime::throw_ArithmeticException(JavaThread* thread)) - throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_ArithmeticException(), "/ by zero"); - JRT_END -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/sharedRuntime.hpp openjdk/hotspot/src/share/vm/runtime/sharedRuntime.hpp ---- openjdk6/hotspot/src/share/vm/runtime/sharedRuntime.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/sharedRuntime.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)sharedRuntime.hpp 1.157 07/07/19 12:19:08 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -107,7 +104,6 @@ - STACK_OVERFLOW - }; - static void throw_AbstractMethodError(JavaThread* thread); -- static void throw_IncompatibleClassChangeError(JavaThread* thread); - static void throw_ArithmeticException(JavaThread* thread); - static void throw_NullPointerException(JavaThread* thread); - static void throw_NullPointerException_at_call(JavaThread* thread); -@@ -130,6 +126,7 @@ - } - - #ifdef COMPILER2 -+ static void generate_uncommon_trap_blob(void); - static UncommonTrapBlob* uncommon_trap_blob() { return _uncommon_trap_blob; } - #endif // COMPILER2 - -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/sharedRuntimeTrans.cpp openjdk/hotspot/src/share/vm/runtime/sharedRuntimeTrans.cpp ---- openjdk6/hotspot/src/share/vm/runtime/sharedRuntimeTrans.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/sharedRuntimeTrans.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)sharedRuntimeTrans.cpp 1.8 07/05/05 17:06:54 JVM" --#endif - /* - * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/sharedRuntimeTrig.cpp openjdk/hotspot/src/share/vm/runtime/sharedRuntimeTrig.cpp ---- openjdk6/hotspot/src/share/vm/runtime/sharedRuntimeTrig.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/sharedRuntimeTrig.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)sharedRuntimeTrig.cpp 1.16 07/05/05 17:06:55 JVM" --#endif - /* - * Copyright 2001-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/signature.cpp openjdk/hotspot/src/share/vm/runtime/signature.cpp ---- openjdk6/hotspot/src/share/vm/runtime/signature.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/signature.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)signature.cpp 1.43 07/05/05 17:06:56 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/signature.hpp openjdk/hotspot/src/share/vm/runtime/signature.hpp ---- openjdk6/hotspot/src/share/vm/runtime/signature.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/signature.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)signature.hpp 1.50 07/05/05 17:06:56 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/stackValue.cpp openjdk/hotspot/src/share/vm/runtime/stackValue.cpp ---- openjdk6/hotspot/src/share/vm/runtime/stackValue.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/stackValue.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)stackValue.cpp 1.27 07/05/05 17:06:58 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -28,6 +25,136 @@ - # include "incls/_precompiled.incl" - # include "incls/_stackValue.cpp.incl" - -+StackValue* StackValue::create_stack_value(const frame* fr, const RegisterMap* reg_map, ScopeValue* sv) { -+ if (sv->is_location()) { -+ // Stack or register value -+ Location loc = ((LocationValue *)sv)->location(); -+ -+#ifdef SPARC -+ // %%%%% Callee-save floats will NOT be working on a Sparc until we -+ // handle the case of a 2 floats in a single double register. -+ assert( !(loc.is_register() && loc.type() == Location::float_in_dbl), "Sparc does not handle callee-save floats yet" ); -+#endif // SPARC -+ -+ // First find address of value -+ -+ address value_addr = loc.is_register() -+ // Value was in a callee-save register -+ ? reg_map->location(VMRegImpl::as_VMReg(loc.register_number())) -+ // Else value was directly saved on the stack. The frame's original stack pointer, -+ // before any extension by its callee (due to Compiler1 linkage on SPARC), must be used. -+ : ((address)fr->unextended_sp()) + loc.stack_offset(); -+ -+ // Then package it right depending on type -+ // Note: the transfer of the data is thru a union that contains -+ // an intptr_t. This is because an interpreter stack slot is -+ // really an intptr_t. The use of a union containing an intptr_t -+ // ensures that on a 64 bit platform we have proper alignment -+ // and that we store the value where the interpreter will expect -+ // to find it (i.e. proper endian). Similarly on a 32bit platform -+ // using the intptr_t ensures that when a value is larger than -+ // a stack slot (jlong/jdouble) that we capture the proper part -+ // of the value for the stack slot in question. -+ // -+ switch( loc.type() ) { -+ case Location::float_in_dbl: { // Holds a float in a double register? -+ // The callee has no clue whether the register holds a float, -+ // double or is unused. He always saves a double. Here we know -+ // a double was saved, but we only want a float back. Narrow the -+ // saved double to the float that the JVM wants. -+ assert( loc.is_register(), "floats always saved to stack in 1 word" ); -+ union { intptr_t p; jfloat jf; } value; -+ value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF); -+ value.jf = (jfloat) *(jdouble*) value_addr; -+ return new StackValue(value.p); // 64-bit high half is stack junk -+ } -+ case Location::int_in_long: { // Holds an int in a long register? -+ // The callee has no clue whether the register holds an int, -+ // long or is unused. He always saves a long. Here we know -+ // a long was saved, but we only want an int back. Narrow the -+ // saved long to the int that the JVM wants. -+ assert( loc.is_register(), "ints always saved to stack in 1 word" ); -+ union { intptr_t p; jint ji;} value; -+ value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF); -+ value.ji = (jint) *(jlong*) value_addr; -+ return new StackValue(value.p); // 64-bit high half is stack junk -+ } -+#ifdef _LP64 -+ case Location::dbl: -+ // Double value in an aligned adjacent pair -+ return new StackValue(*(intptr_t*)value_addr); -+ case Location::lng: -+ // Long value in an aligned adjacent pair -+ return new StackValue(*(intptr_t*)value_addr); -+#endif -+ case Location::oop: { -+ Handle h(*(oop *)value_addr); // Wrap a handle around the oop -+ return new StackValue(h); -+ } -+ case Location::addr: { -+ ShouldNotReachHere(); // both C1 and C2 now inline jsrs -+ } -+ case Location::normal: { -+ // Just copy all other bits straight through -+ union { intptr_t p; jint ji;} value; -+ value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF); -+ value.ji = *(jint*)value_addr; -+ return new StackValue(value.p); -+ } -+ case Location::invalid: -+ return new StackValue(); -+ default: -+ ShouldNotReachHere(); -+ } -+ -+ } else if (sv->is_constant_int()) { -+ // Constant int: treat same as register int. -+ union { intptr_t p; jint ji;} value; -+ value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF); -+ value.ji = (jint)((ConstantIntValue*)sv)->value(); -+ return new StackValue(value.p); -+ } else if (sv->is_constant_oop()) { -+ // constant oop -+ return new StackValue(((ConstantOopReadValue *)sv)->value()); -+#ifdef _LP64 -+ } else if (sv->is_constant_double()) { -+ // Constant double in a single stack slot -+ union { intptr_t p; double d; } value; -+ value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF); -+ value.d = ((ConstantDoubleValue *)sv)->value(); -+ return new StackValue(value.p); -+ } else if (sv->is_constant_long()) { -+ // Constant long in a single stack slot -+ union { intptr_t p; jlong jl; } value; -+ value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF); -+ value.jl = ((ConstantLongValue *)sv)->value(); -+ return new StackValue(value.p); -+#endif -+ } else if (sv->is_object()) { -+ return new StackValue(((ObjectValue *)sv)->value()); -+ } -+ -+ // Unknown ScopeValue type -+ ShouldNotReachHere(); -+ return new StackValue((intptr_t) 0); // dummy -+} -+ -+ -+BasicLock* StackValue::resolve_monitor_lock(const frame* fr, Location location) { -+ assert(location.is_stack(), "for now we only look at the stack"); -+ int word_offset = location.stack_offset() / wordSize; -+ // (stack picture) -+ // high: [ ] word_offset + 1 -+ // low [ ] word_offset -+ // -+ // sp-> [ ] 0 -+ // the word_offset is the distance from the stack pointer to the lowest address -+ // The frame's original stack pointer, before any extension by its callee -+ // (due to Compiler1 linkage on SPARC), must be used. -+ return (BasicLock*) (fr->unextended_sp() + word_offset); -+} -+ -+ - #ifndef PRODUCT - - void StackValue::print_on(outputStream* st) const { -@@ -51,4 +178,3 @@ - } - - #endif -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/stackValue.hpp openjdk/hotspot/src/share/vm/runtime/stackValue.hpp ---- openjdk6/hotspot/src/share/vm/runtime/stackValue.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/stackValue.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)stackValue.hpp 1.36 07/05/05 17:06:58 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -93,10 +90,12 @@ - } - } - -+ static StackValue* create_stack_value(const frame* fr, const RegisterMap* reg_map, ScopeValue* sv); -+ static BasicLock* resolve_monitor_lock(const frame* fr, Location location); -+ - #ifndef PRODUCT - public: - // Printing - void print_on(outputStream* st) const; - #endif - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/stackValueCollection.cpp openjdk/hotspot/src/share/vm/runtime/stackValueCollection.cpp ---- openjdk6/hotspot/src/share/vm/runtime/stackValueCollection.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/stackValueCollection.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)stackValueCollection.cpp 1.18 07/05/05 17:06:53 JVM" --#endif - /* - * Copyright 2001-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/stackValueCollection.hpp openjdk/hotspot/src/share/vm/runtime/stackValueCollection.hpp ---- openjdk6/hotspot/src/share/vm/runtime/stackValueCollection.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/stackValueCollection.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)stackValueCollection.hpp 1.14 07/05/05 17:06:58 JVM" --#endif - /* - * Copyright 2001-2002 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/statSampler.cpp openjdk/hotspot/src/share/vm/runtime/statSampler.cpp ---- openjdk6/hotspot/src/share/vm/runtime/statSampler.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/statSampler.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)statSampler.cpp 1.24 07/05/05 17:06:58 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -360,4 +357,3 @@ - - StatSampler::destroy(); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/statSampler.hpp openjdk/hotspot/src/share/vm/runtime/statSampler.hpp ---- openjdk6/hotspot/src/share/vm/runtime/statSampler.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/statSampler.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)statSampler.hpp 1.12 07/05/05 17:06:58 JVM" --#endif - /* - * Copyright 2001-2002 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp openjdk/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp ---- openjdk6/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/stubCodeGenerator.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)stubCodeGenerator.cpp 1.30 07/05/17 16:06:31 JVM" --#endif - /* - * Copyright 1997-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -146,4 +143,3 @@ - JvmtiExport::post_dynamic_code_generated(_cdesc->name(), _cdesc->begin(), _cdesc->end()); - } - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/stubCodeGenerator.hpp openjdk/hotspot/src/share/vm/runtime/stubCodeGenerator.hpp ---- openjdk6/hotspot/src/share/vm/runtime/stubCodeGenerator.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/stubCodeGenerator.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)stubCodeGenerator.hpp 1.25 07/05/17 16:06:33 JVM" --#endif - /* - * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -121,4 +118,3 @@ - ~StubCodeMark(); - - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/stubRoutines.cpp openjdk/hotspot/src/share/vm/runtime/stubRoutines.cpp ---- openjdk6/hotspot/src/share/vm/runtime/stubRoutines.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/stubRoutines.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)stubRoutines.cpp 1.115 07/07/19 12:19:08 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -43,7 +40,6 @@ - address StubRoutines::_catch_exception_entry = NULL; - address StubRoutines::_forward_exception_entry = NULL; - address StubRoutines::_throw_AbstractMethodError_entry = NULL; --address StubRoutines::_throw_IncompatibleClassChangeError_entry = NULL; - address StubRoutines::_throw_ArithmeticException_entry = NULL; - address StubRoutines::_throw_NullPointerException_entry = NULL; - address StubRoutines::_throw_NullPointerException_at_call_entry = NULL; -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/stubRoutines.hpp openjdk/hotspot/src/share/vm/runtime/stubRoutines.hpp ---- openjdk6/hotspot/src/share/vm/runtime/stubRoutines.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/stubRoutines.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)stubRoutines.hpp 1.118 07/07/19 12:19:07 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -87,7 +84,6 @@ - static address _forward_exception_entry; - static address _catch_exception_entry; - static address _throw_AbstractMethodError_entry; -- static address _throw_IncompatibleClassChangeError_entry; - static address _throw_ArithmeticException_entry; - static address _throw_NullPointerException_entry; - static address _throw_NullPointerException_at_call_entry; -@@ -188,7 +184,6 @@ - static address forward_exception_entry() { return _forward_exception_entry; } - // Implicit exceptions - static address throw_AbstractMethodError_entry() { return _throw_AbstractMethodError_entry; } -- static address throw_IncompatibleClassChangeError_entry(){ return _throw_IncompatibleClassChangeError_entry; } - static address throw_ArithmeticException_entry() { return _throw_ArithmeticException_entry; } - static address throw_NullPointerException_entry() { return _throw_NullPointerException_entry; } - static address throw_NullPointerException_at_call_entry(){ return _throw_NullPointerException_at_call_entry; } -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/sweeper.cpp openjdk/hotspot/src/share/vm/runtime/sweeper.cpp ---- openjdk6/hotspot/src/share/vm/runtime/sweeper.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/sweeper.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)sweeper.cpp 1.39 07/05/05 17:06:50 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/sweeper.hpp openjdk/hotspot/src/share/vm/runtime/sweeper.hpp ---- openjdk6/hotspot/src/share/vm/runtime/sweeper.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/sweeper.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)sweeper.hpp 1.26 07/05/05 17:06:59 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/synchronizer.cpp openjdk/hotspot/src/share/vm/runtime/synchronizer.cpp ---- openjdk6/hotspot/src/share/vm/runtime/synchronizer.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/synchronizer.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)synchronizer.cpp 1.110 07/05/26 16:19:45 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -119,6 +116,7 @@ - volatile int _notified ; - volatile TStates TState ; - Sorted _Sorted ; // List placement disposition -+ bool _active ; // Contention monitoring is enabled - public: - ObjectWaiter(Thread* thread) { - _next = NULL; -@@ -127,8 +125,19 @@ - TState = TS_RUN ; - _thread = thread; - _event = thread->_ParkEvent ; -+ _active = false; - assert (_event != NULL, "invariant") ; - } -+ -+ void wait_reenter_begin(ObjectMonitor *mon) { -+ JavaThread *jt = (JavaThread *)this->_thread; -+ _active = JavaThreadBlockedOnMonitorEnterState::wait_reenter_begin(jt, mon); -+ } -+ -+ void wait_reenter_end(ObjectMonitor *mon) { -+ JavaThread *jt = (JavaThread *)this->_thread; -+ JavaThreadBlockedOnMonitorEnterState::wait_reenter_end(jt, _active); -+ } - }; - - enum ManifestConstants { -@@ -180,7 +189,7 @@ - - // Tunables ... - // The knob* variables are effectively final. Once set they should --// never be modified hence. -+// never be modified hence. Consider using __read_mostly with GCC. - - static int Knob_LogSpins = 0 ; // enable jvmstat tally for spins - static int Knob_HandOff = 0 ; -@@ -322,7 +331,7 @@ - // Typically the displaced header will be 0 (recursive stack lock) or - // unused_mark. Naively we'd like to assert that the displaced mark - // value is either 0, neutral, or 3. But with the advent of the -- // the store-before-CAS avoidance in fast_lock/compiler_lock_object -+ // store-before-CAS avoidance in fast_lock/compiler_lock_object - // we can find any flavor mark in the displaced mark. - } - // [RGV] The next line appears to do nothing! -@@ -450,7 +459,7 @@ - - typedef volatile int SpinLockT ; - --static void SpinAcquire (volatile int * adr, const char * LockName) { -+void Thread::SpinAcquire (volatile int * adr, const char * LockName) { - if (Atomic::cmpxchg (1, adr, 0) == 0) { - return ; // normal fast-path return - } -@@ -464,6 +473,8 @@ - ++ctr ; - if ((ctr & 0xFFF) == 0 || !os::is_MP()) { - if (Yields > 5) { -+ // Consider using a simple NakedSleep() instead. -+ // Then SpinAcquire could be called by non-JVM threads - Thread::current()->_ParkEvent->park(1) ; - } else { - os::NakedYield() ; -@@ -477,7 +488,7 @@ - } - } - --static void SpinRelease (volatile int * adr) { -+void Thread::SpinRelease (volatile int * adr) { - assert (*adr != 0, "invariant") ; - OrderAccess::fence() ; // guarantee at least release consistency. - // Roach-motel semantics. -@@ -494,12 +505,15 @@ - // The remainder of the word points to the head of a singly-linked list - // of threads blocked on the lock. - // --// * users of muxAcquire and muxRelease must be careful with regards to --// consuming unpark() "permits". This is particularly true when --// muxAcquire-muxRelease are used as part of the implementation of --// the sync subsystem. A safe rule of thumb is that a thread should never --// call muxAcquire() if it's enqueued (cxq, EntryList, WaitList, etc) and --// will subsequently park(). The park() operation in muxAcquire() could -+// * The current implementation of muxAcquire-muxRelease uses its own -+// dedicated Thread._MuxEvent instance. If we're interested in -+// minimizing the peak number of extant ParkEvent instances then -+// we could eliminate _MuxEvent and "borrow" _ParkEvent as long -+// as certain invariants were satisfied. Specifically, care would need -+// to be taken with regards to consuming unpark() "permits". -+// A safe rule of thumb is that a thread would never call muxAcquire() -+// if it's enqueued (cxq, EntryList, WaitList, etc) and will subsequently -+// park(). Otherwise the _ParkEvent park() operation in muxAcquire() could - // consume an unpark() permit intended for monitorenter, for instance. - // One way around this would be to widen the restricted-range semaphore - // implemented in park(). Another alternative would be to provide -@@ -507,9 +521,9 @@ - // instance would be dedicated to muxAcquire-muxRelease, for instance. - // - // * Usage: --// -- only as leaf locks --// -- for short-term locks only, as blocking MuxAcquire() does _not perform --// a state transition. -+// -- Only as leaf locks -+// -- for short-term locking only as muxAcquire does not perform -+// thread state transitions. - // - // Alternatives: - // * We could implement muxAcquire and muxRelease with MCS or CLH locks -@@ -531,12 +545,13 @@ - // to provide the usual futile-wakeup optimization. - // See RTStt for details. - // * Consider schedctl.sc_nopreempt to cover the critical section. -+// - - - typedef volatile intptr_t MutexT ; // Mux Lock-word - enum MuxBits { LOCKBIT = 1 } ; - --static void ATTR muxAcquire (volatile intptr_t * Lock, const char * LockName) { -+void Thread::muxAcquire (volatile intptr_t * Lock, const char * LockName) { - intptr_t w = Atomic::cmpxchg_ptr (LOCKBIT, Lock, 0) ; - if (w == 0) return ; - if ((w & LOCKBIT) == 0 && Atomic::cmpxchg_ptr (w|LOCKBIT, Lock, w) == w) { -@@ -544,10 +559,9 @@ - } - - TEVENT (muxAcquire - Contention) ; -- ParkEvent * Self = Thread::current()->_ParkEvent ; -+ ParkEvent * const Self = Thread::current()->_MuxEvent ; - assert ((intptr_t(Self) & LOCKBIT) == 0, "invariant") ; - for (;;) { -- intptr_t w ; - int its = (os::is_MP() ? 100 : 0) + 1 ; - - // Optional spin phase: spin-then-park strategy -@@ -567,6 +581,7 @@ - w = *Lock ; - if ((w & LOCKBIT) == 0) { - if (Atomic::cmpxchg_ptr (w|LOCKBIT, Lock, w) == w) { -+ Self->OnList = 0 ; // hygiene - allows stronger asserts - return ; - } - continue ; // Interference -- *Lock changed -- Just retry -@@ -582,17 +597,79 @@ - } - } - -+void Thread::muxAcquireW (volatile intptr_t * Lock, ParkEvent * ev) { -+ intptr_t w = Atomic::cmpxchg_ptr (LOCKBIT, Lock, 0) ; -+ if (w == 0) return ; -+ if ((w & LOCKBIT) == 0 && Atomic::cmpxchg_ptr (w|LOCKBIT, Lock, w) == w) { -+ return ; -+ } -+ -+ TEVENT (muxAcquire - Contention) ; -+ ParkEvent * ReleaseAfter = NULL ; -+ if (ev == NULL) { -+ ev = ReleaseAfter = ParkEvent::Allocate (NULL) ; -+ } -+ assert ((intptr_t(ev) & LOCKBIT) == 0, "invariant") ; -+ for (;;) { -+ guarantee (ev->OnList == 0, "invariant") ; -+ int its = (os::is_MP() ? 100 : 0) + 1 ; -+ -+ // Optional spin phase: spin-then-park strategy -+ while (--its >= 0) { -+ w = *Lock ; -+ if ((w & LOCKBIT) == 0 && Atomic::cmpxchg_ptr (w|LOCKBIT, Lock, w) == w) { -+ if (ReleaseAfter != NULL) { -+ ParkEvent::Release (ReleaseAfter) ; -+ } -+ return ; -+ } -+ } -+ -+ ev->reset() ; -+ ev->OnList = intptr_t(Lock) ; -+ // The following fence() isn't _strictly necessary as the subsequent -+ // CAS() both serializes execution and ratifies the fetched *Lock value. -+ OrderAccess::fence(); -+ for (;;) { -+ w = *Lock ; -+ if ((w & LOCKBIT) == 0) { -+ if (Atomic::cmpxchg_ptr (w|LOCKBIT, Lock, w) == w) { -+ ev->OnList = 0 ; -+ // We call ::Release while holding the outer lock, thus -+ // artificially lengthening the critical section. -+ // Consider deferring the ::Release() until the subsequent unlock(), -+ // after we've dropped the outer lock. -+ if (ReleaseAfter != NULL) { -+ ParkEvent::Release (ReleaseAfter) ; -+ } -+ return ; -+ } -+ continue ; // Interference -- *Lock changed -- Just retry -+ } -+ assert (w & LOCKBIT, "invariant") ; -+ ev->ListNext = (ParkEvent *) (w & ~LOCKBIT ); -+ if (Atomic::cmpxchg_ptr (intptr_t(ev)|LOCKBIT, Lock, w) == w) break ; -+ } -+ -+ while (ev->OnList != 0) { -+ ev->park() ; -+ } -+ } -+} -+ - // Release() must extract a successor from the list and then wake that thread. - // It can "pop" the front of the list or use a detach-modify-reattach (DMR) scheme - // similar to that used by ParkEvent::Allocate() and ::Release(). DMR-based --// Release() would (A) CAS() or swap() null to *Lock, releasing the lock and --// detaching the list. (B) Extract a successor from the private list "in-hand" --// (C) attempt to CAS() the residual back into *Lock over null. If there were any --// newly arrived threads and the CAS() would fail. In that case Release() would --// detach the RATs, re-merge the list in-hand with the RATs and repeat as needed. --// Alternately, Release() can detach and extract a successor, put then pass the --// residual list to the wakee. The wakee must reattach and remerge before it --// competes for the lock. -+// Release() would : -+// (A) CAS() or swap() null to *Lock, releasing the lock and detaching the list. -+// (B) Extract a successor from the private list "in-hand" -+// (C) attempt to CAS() the residual back into *Lock over null. -+// If there were any newly arrived threads and the CAS() would fail. -+// In that case Release() would detach the RATs, re-merge the list in-hand -+// with the RATs and repeat as needed. Alternately, Release() might -+// detach and extract a successor, but then pass the residual list to the wakee. -+// The wakee would be responsible for reattaching and remerging before it -+// competed for the lock. - // - // Both "pop" and DMR are immune from ABA corruption -- there can be - // multiple concurrent pushers, but only one popper or detacher. -@@ -600,9 +677,9 @@ - // but tends to provide excellent throughput as hot threads remain hot. - // (We wake recently run threads first). - --static void ATTR muxRelease (volatile intptr_t * Lock) { -+void Thread::muxRelease (volatile intptr_t * Lock) { - for (;;) { -- intptr_t w = Atomic::cmpxchg_ptr (0, Lock, LOCKBIT) ; -+ const intptr_t w = Atomic::cmpxchg_ptr (0, Lock, LOCKBIT) ; - assert (w & LOCKBIT, "invariant") ; - if (w == LOCKBIT) return ; - ParkEvent * List = (ParkEvent *) (w & ~LOCKBIT) ; -@@ -705,7 +782,7 @@ - // Reprovision the thread's omFreeList. - // Use bulk transfers to reduce the allocation rate and heat - // on various locks. -- muxAcquire (&ListLock, "omAlloc") ; -+ Thread::muxAcquire (&ListLock, "omAlloc") ; - for (int i = Self->omFreeProvision; --i >= 0 && gFreeList != NULL; ) { - ObjectMonitor * take = gFreeList ; - gFreeList = take->FreeNext ; -@@ -714,7 +791,7 @@ - take->Recycle() ; - omRelease (Self, take) ; - } -- muxRelease (&ListLock) ; -+ Thread::muxRelease (&ListLock) ; - Self->omFreeProvision += 1 + (Self->omFreeProvision/2) ; - if (Self->omFreeProvision > MAXPRIVATE ) Self->omFreeProvision = MAXPRIVATE ; - TEVENT (omFirst - reprovision) ; -@@ -758,7 +835,7 @@ - - // Acquire the ListLock to manipulate BlockList and FreeList. - // An Oyama-Taura-Yonezawa scheme might be more efficient. -- muxAcquire (&ListLock, "omAlloc [2]") ; -+ Thread::muxAcquire (&ListLock, "omAlloc [2]") ; - - // Add the new block to the list of extant blocks (gBlockList). - // The very first objectMonitor in a block is reserved and dedicated. -@@ -769,7 +846,7 @@ - // Add the new string of objectMonitors to the global free list - temp[_BLOCKSIZE - 1].FreeNext = gFreeList ; - gFreeList = temp + 1; -- muxRelease (&ListLock) ; -+ Thread::muxRelease (&ListLock) ; - TEVENT (Allocate block of monitors) ; - } - } -@@ -826,10 +903,10 @@ - } - - guarantee (Tail != NULL && List != NULL, "invariant") ; -- muxAcquire (&ListLock, "omFlush") ; -+ Thread::muxAcquire (&ListLock, "omFlush") ; - Tail->FreeNext = gFreeList ; - gFreeList = List ; -- muxRelease (&ListLock) ; -+ Thread::muxRelease (&ListLock) ; - TEVENT (omFlush) ; - } - -@@ -907,7 +984,7 @@ - int YieldThenBlock = 0 ; - assert (ix >= 0 && ix < NINFLATIONLOCKS, "invariant") ; - assert ((NINFLATIONLOCKS & (NINFLATIONLOCKS-1)) == 0, "invariant") ; -- muxAcquire (InflationLocks + ix, "InflationLock") ; -+ Thread::muxAcquire (InflationLocks + ix, "InflationLock") ; - while (obj->mark() == markOopDesc::INFLATING()) { - // Beware: NakedYield() is advisory and has almost no effect on some platforms - // so we periodically call Self->_ParkEvent->park(1). -@@ -918,7 +995,7 @@ - os::NakedYield() ; - } - } -- muxRelease (InflationLocks + ix ) ; -+ Thread::muxRelease (InflationLocks + ix ) ; - TEVENT (Inflate: INFLATING - yield/park) ; - } - } else { -@@ -958,7 +1035,7 @@ - // Only that thread can complete inflation -- other threads must wait. - // The INFLATING value is transient. - // Currently, we spin/yield/park and poll the markword, waiting for inflation to finish. -- // We could always eliminate polling by parking the thread on some auxilliary list. -+ // We could always eliminate polling by parking the thread on some auxiliary list. - if (mark == markOopDesc::INFLATING()) { - TEVENT (Inflate: spin while INFLATING) ; - ReadStableMark(object) ; -@@ -969,7 +1046,7 @@ - // Could be stack-locked either by this thread or by some other thread. - // - // Note that we allocate the objectmonitor speculatively, _before_ attempting -- // to install INFLATING into the mark word. We orginally installed INFLATING, -+ // to install INFLATING into the mark word. We originally installed INFLATING, - // allocated the objectmonitor, and then finally STed the address of the - // objectmonitor into the mark. This was correct, but artificially lengthened - // the interval in which INFLATED appeared in the mark, thus increasing -@@ -1022,7 +1099,7 @@ - // will then spin, waiting for the 0 value to disappear. Put another way, - // the 0 causes the owner to stall if the owner happens to try to - // drop the lock (restoring the header from the basiclock to the object) -- // while inflation is in-progess. This protocol avoids races that might -+ // while inflation is in-progress. This protocol avoids races that might - // would otherwise permit hashCode values to change or "flicker" for an object. - // Critically, while object->mark is 0 mark->displaced_mark_helper() is stable. - // 0 serves as a "BUSY" inflate-in-progress indicator. -@@ -1204,7 +1281,7 @@ - } - - #if 0 -- // The following optimization isn't particulary useful. -+ // The following optimization isn't particularly useful. - if (mark->has_monitor() && mark->monitor()->is_entered(THREAD)) { - lock->set_displaced_header (NULL) ; - return ; -@@ -1625,9 +1702,9 @@ - assert(THREAD == JavaThread::current(), "must be current Java thread"); - No_Safepoint_Verifier nsv ; - ReleaseJavaMonitorsClosure rjmc(THREAD); -- muxAcquire(&ListLock, "release_monitors_owned_by_thread"); -+ Thread::muxAcquire(&ListLock, "release_monitors_owned_by_thread"); - ObjectSynchronizer::monitors_iterate(&rjmc); -- muxRelease(&ListLock); -+ Thread::muxRelease(&ListLock); - THREAD->clear_pending_exception(); - } - -@@ -1769,10 +1846,10 @@ - guarantee (FreeTail != NULL && nScavenged > 0, "invariant") ; - assert (FreeTail->FreeNext == NULL, "invariant") ; - // constant-time list splice - prepend scavenged segment to gFreeList -- muxAcquire (&ListLock, "scavenge - return") ; -+ Thread::muxAcquire (&ListLock, "scavenge - return") ; - FreeTail->FreeNext = gFreeList ; - gFreeList = FreeHead ; -- muxRelease (&ListLock) ; -+ Thread::muxRelease (&ListLock) ; - } - - if (_sync_Deflations != NULL) _sync_Deflations->inc(nScavenged) ; -@@ -2161,7 +2238,7 @@ - // "rings" or oscillates between spinning and not spinning. This happens - // when spinning is just on the cusp of profitability, however, so the - // situation is not dire. The state is benign -- there's no need to add --// hysterisis control to damp the transition rate between spinning and -+// hysteresis control to damp the transition rate between spinning and - // not spinning. - // - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@@ -2209,7 +2286,7 @@ - // (that is, loadavg() << #cpus), we can instead suppress futile - // wakeup throttling, or even wake more than one successor at exit-time. - // The net effect is largely equivalent to spinning. In both cases, --// contenting threads go ONPROC and opportunistically attempt to acquire -+// contending threads go ONPROC and opportunistically attempt to acquire - // the lock, decreasing lock handover latency at the expense of wasted - // cycles and context switching. - // -@@ -2249,7 +2326,7 @@ - // for extended periods on the ready queue. - // - // * While spinning try to use the otherwise wasted time to help the VM make --// progess: -+// progress: - // - // -- YieldTo() the owner, if the owner is OFFPROC but ready - // Done our remaining quantum directly to the ready thread. -@@ -2280,7 +2357,7 @@ - // as the default spin state after inflation is aggressive (optimistic) - // and tends toward spinning. So in the worst case for a lock where - // spinning is not profitable we may spin unnecessarily for a brief --// period. But then again, if a lock is contented it'll tend not to deflate\ -+// period. But then again, if a lock is contended it'll tend not to deflate - // in the first place. - - -@@ -2397,7 +2474,7 @@ - // This is useful on classic SMP systems, but is of less utility on - // N1-style CMT platforms. - // -- // Trade-off: lock acquistion latency vs coherency bandwidth. -+ // Trade-off: lock acquisition latency vs coherency bandwidth. - // Lock hold times are typically short. A histogram - // of successful spin attempts shows that we usually acquire - // the lock early in the spin. That suggests we want to -@@ -2601,7 +2678,7 @@ - // * Invariant: A thread appears on at most one monitor list -- - // cxq, EntryList or WaitSet -- at any one time. - // --// * Contenting threads "push" themselves onto the cxq with CAS -+// * Contending threads "push" themselves onto the cxq with CAS - // and then spin/park. - // - // * After a contending thread eventually acquires the lock it must -@@ -2689,7 +2766,7 @@ - // by the notifier. - // - // * An interesting alternative is to encode cxq as (List,LockByte) where --// the LockByte is 0 iff the monitor is owned. _owner is simply an auxilliary -+// the LockByte is 0 iff the monitor is owned. _owner is simply an auxiliary - // variable, like _recursions, in the scheme. The threads or Events that form - // the list would have to be aligned in 256-byte addresses. A thread would - // try to acquire the lock or enqueue itself with CAS, but exiting threads -@@ -2962,7 +3039,7 @@ - // Given that, we'd call HSSEC after having returned from park(), - // but before attempting to acquire the monitor. This is only a - // partial solution. It avoids calling HSSEC while holding the --// monitor (good), but it still increases successor reacquistion latency -- -+// monitor (good), but it still increases successor reacquisition latency -- - // the interval between unparking a successor and the time the successor - // resumes and retries the lock. See ReenterI(), which defers state transitions. - // If we use this technique we can also avoid EnterI()-exit() loop -@@ -3278,7 +3355,7 @@ - // * Consider: set Wakee->UnparkTime = timeNow() - // When the thread wakes up it'll compute (timeNow() - Self->UnparkTime()). - // By measuring recent ONPROC latency we can approximate the -- // the system load. In turn, we can feed that information back -+ // system load. In turn, we can feed that information back - // into the spinning & succession policies. - // (ONPROC latency correlates strongly with load). - // -@@ -3300,7 +3377,7 @@ - // ~~~~~~ - // Note that the collector can't reclaim the objectMonitor or deflate - // the object out from underneath the thread calling ::exit() as the --// the thread calling ::exit() never transitions to a stable state. -+// thread calling ::exit() never transitions to a stable state. - // This inhibits GC, which in turn inhibits asynchronous (and - // inopportune) reclamation of "this". - // -@@ -3308,7 +3385,7 @@ - // There's one exception to the claim above, however. EnterI() can call - // exit() to drop a lock if the acquirer has been externally suspended. - // In that case exit() is called with _thread_state as _thread_blocked, --// but the monitor's _count field is > 0, which inhibits reclaimation. -+// but the monitor's _count field is > 0, which inhibits reclamation. - // - // 1-0 exit - // ~~~~~~~~ -@@ -3455,7 +3532,7 @@ - // I'd like to write one of the following: - // A. OrderAccess::release() ; _owner = NULL - // B. OrderAccess::loadstore(); OrderAccess::storestore(); _owner = NULL; -- // Unfortunatey OrderAccess::release() and OrderAccess::loadstore() both -+ // Unfortunately OrderAccess::release() and OrderAccess::loadstore() both - // store into a _dummy variable. That store is not needed, but can result - // in massive wasteful coherency traffic on classic SMP systems. - // Instead, I use release_store(), which is implemented as just a simple -@@ -3495,14 +3572,14 @@ - // (Note that we'd need to make the post-drop spin short, but no - // shorter than the worst-case round-trip cache-line migration time. - // The dropped lock needs to become visible to the spinner, and then -- // the acquistion of the lock by the spinner must become visible to -+ // the acquisition of the lock by the spinner must become visible to - // the exiting thread). - // - - // It appears that an heir-presumptive (successor) must be made ready. - // Only the current lock owner can manipulate the EntryList or - // drain _cxq, so we need to reacquire the lock. If we fail -- // to reaquire the lock the responsibility for ensuring succession -+ // to reacquire the lock the responsibility for ensuring succession - // falls to the new owner. - // - if (Atomic::cmpxchg_ptr (THREAD, &_owner, NULL) != NULL) { -@@ -3523,7 +3600,7 @@ - // in the fast-exit path raced an entering thread in the slow-enter - // path. - // We have two choices: -- // A. Try to reaquire the lock. -+ // A. Try to reacquire the lock. - // If the CAS() fails return immediately, otherwise - // we either restart/rerun the exit operation, or simply - // fall-through into the code below which wakes a successor. -@@ -3657,7 +3734,7 @@ - // notify() operation moves T1 from O's waitset to O's EntryList. T2 then - // release the lock "O". T2 resumes immediately after the ST of null into - // _owner, above. T2 notices that the EntryList is populated, so it -- // reaquires the lock and then finds itself on the EntryList. -+ // reacquires the lock and then finds itself on the EntryList. - // Given all that, we have to tolerate the circumstance where "w" is - // associated with Self. - assert (w->TState == ObjectWaiter::TS_ENTER, "invariant") ; -@@ -3828,9 +3905,9 @@ - // returns because of a timeout of interrupt. Contention is exceptionally rare - // so we use a simple spin-lock instead of a heavier-weight blocking lock. - -- SpinAcquire (&_WaitSetLock, "WaitSet - add") ; -+ Thread::SpinAcquire (&_WaitSetLock, "WaitSet - add") ; - AddWaiter (&node) ; -- SpinRelease (&_WaitSetLock) ; -+ Thread::SpinRelease (&_WaitSetLock) ; - - if ((SyncFlags & 4) == 0) { - _Responsible = NULL ; -@@ -3909,13 +3986,13 @@ - // That is, we fail toward safety. - - if (node.TState == ObjectWaiter::TS_WAIT) { -- SpinAcquire (&_WaitSetLock, "WaitSet - unlink") ; -+ Thread::SpinAcquire (&_WaitSetLock, "WaitSet - unlink") ; - if (node.TState == ObjectWaiter::TS_WAIT) { - DequeueSpecificWaiter (&node) ; // unlink from WaitSet - assert(node._notified == 0, "invariant"); - node.TState = ObjectWaiter::TS_RUN ; - } -- SpinRelease (&_WaitSetLock) ; -+ Thread::SpinRelease (&_WaitSetLock) ; - } - - // The thread is now either on off-list (TS_RUN), -@@ -3936,9 +4013,7 @@ - - // post monitor waited event. Note that this is past-tense, we are done waiting. - if (JvmtiExport::should_post_monitor_waited()) { -- JvmtiExport::post_monitor_waited(jt, this, (ret == OS_TIMEOUT) ? true : false); -- // Just to err on the conservative side ... -- if (_succ == Self) _succ = NULL ; -+ JvmtiExport::post_monitor_waited(jt, this, ret == OS_TIMEOUT); - } - OrderAccess::fence() ; - -@@ -3952,7 +4027,7 @@ - } else { - guarantee (v == ObjectWaiter::TS_ENTER || v == ObjectWaiter::TS_CXQ, "invariant") ; - ReenterI (Self, &node) ; -- node.TState = ObjectWaiter::TS_RUN ; -+ node.wait_reenter_end(this); - } - - // Self has reacquired the lock. -@@ -4009,7 +4084,7 @@ - - int Policy = Knob_MoveNotifyee ; - -- SpinAcquire (&_WaitSetLock, "WaitSet - notify") ; -+ Thread::SpinAcquire (&_WaitSetLock, "WaitSet - notify") ; - ObjectWaiter * iterator = DequeueWaiter() ; - if (iterator != NULL) { - TEVENT (Notify1 - Transfer) ; -@@ -4099,6 +4174,10 @@ - ev->unpark() ; - } - -+ if (Policy < 4) { -+ iterator->wait_reenter_begin(this); -+ } -+ - // _WaitSetLock protects the wait queue, not the EntryList. We could - // move the add-to-EntryList operation, above, outside the critical section - // protected by _WaitSetLock. In practice that's not useful. With the -@@ -4108,13 +4187,14 @@ - // critical section. - } - -- SpinRelease (&_WaitSetLock) ; -+ Thread::SpinRelease (&_WaitSetLock) ; - - if (iterator != NULL && ObjectSynchronizer::_sync_Notifications != NULL) { - ObjectSynchronizer::_sync_Notifications->inc() ; - } - } - -+ - void ObjectMonitor::notifyAll(TRAPS) { - CHECK_OWNER(); - ObjectWaiter* iterator; -@@ -4126,7 +4206,7 @@ - - int Policy = Knob_MoveNotifyee ; - int Tally = 0 ; -- SpinAcquire (&_WaitSetLock, "WaitSet - notifyall") ; -+ Thread::SpinAcquire (&_WaitSetLock, "WaitSet - notifyall") ; - - for (;;) { - iterator = DequeueWaiter () ; -@@ -4223,6 +4303,9 @@ - ev->unpark() ; - } - -+ if (Policy < 4) { -+ iterator->wait_reenter_begin(this); -+ } - - // _WaitSetLock protects the wait queue, not the EntryList. We could - // move the add-to-EntryList operation, above, outside the critical section -@@ -4233,7 +4316,7 @@ - // critical section. - } - -- SpinRelease (&_WaitSetLock) ; -+ Thread::SpinRelease (&_WaitSetLock) ; - - if (Tally != 0 && ObjectSynchronizer::_sync_Notifications != NULL) { - ObjectSynchronizer::_sync_Notifications->inc(Tally) ; -@@ -4631,6 +4714,3 @@ - } - - #endif -- -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/synchronizer.hpp openjdk/hotspot/src/share/vm/runtime/synchronizer.hpp ---- openjdk6/hotspot/src/share/vm/runtime/synchronizer.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/synchronizer.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)synchronizer.hpp 1.71 07/05/26 16:04:34 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/task.cpp openjdk/hotspot/src/share/vm/runtime/task.cpp ---- openjdk6/hotspot/src/share/vm/runtime/task.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/task.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)task.cpp 1.27 07/05/05 17:06:59 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/task.hpp openjdk/hotspot/src/share/vm/runtime/task.hpp ---- openjdk6/hotspot/src/share/vm/runtime/task.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/task.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)task.hpp 1.23 07/05/05 17:06:59 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/thread.cpp openjdk/hotspot/src/share/vm/runtime/thread.cpp ---- openjdk6/hotspot/src/share/vm/runtime/thread.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/thread.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)thread.cpp 1.809 07/06/01 01:36:09 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -146,7 +143,7 @@ - _SR_lock = new Monitor(Mutex::suspend_resume, "SR_lock", true); - _suspend_flags = 0; - -- // thread-specific hashCode stream generator state. -+ // thread-specific hashCode stream generator state - Marsaglia shift-xor form - _hashStateX = os::random() ; - _hashStateY = 842502087 ; - _hashStateZ = 0x8767 ; // (int)(3579807591LL & 0xffff) ; -@@ -156,7 +153,18 @@ - _schedctl = NULL ; - _Stalled = 0 ; - _TypeTag = 0x2BAD ; -+ -+ // Many of the following fields are effectively final - immutable -+ // Note that nascent threads can't use the Native Monitor-Mutex -+ // construct until the _MutexEvent is initialized ... -+ // CONSIDER: instead of using a fixed set of purpose-dedicated ParkEvents -+ // we might instead use a stack of ParkEvents that we could provision on-demand. -+ // The stack would act as a cache to avoid calls to ParkEvent::Allocate() -+ // and ::Release() - _ParkEvent = ParkEvent::Allocate (this) ; -+ _SleepEvent = ParkEvent::Allocate (this) ; -+ _MutexEvent = ParkEvent::Allocate (this) ; -+ _MuxEvent = ParkEvent::Allocate (this) ; - - #ifdef CHECK_UNHANDLED_OOPS - if (CheckUnhandledOops) { -@@ -208,11 +216,12 @@ - delete last_handle_mark(); - assert(last_handle_mark() == NULL, "check we have reached the end"); - -- // It's possible we can encounter a null _ParkEvent in stillborn threads. -- if (_ParkEvent != NULL) { -- ParkEvent::Release (_ParkEvent) ; -- _ParkEvent = NULL ; -- } -+ // It's possible we can encounter a null _ParkEvent, etc., in stillborn threads. -+ // We NULL out the fields for good hygiene. -+ ParkEvent::Release (_ParkEvent) ; _ParkEvent = NULL ; -+ ParkEvent::Release (_SleepEvent) ; _SleepEvent = NULL ; -+ ParkEvent::Release (_MutexEvent) ; _MutexEvent = NULL ; -+ ParkEvent::Release (_MuxEvent) ; _MuxEvent = NULL ; - - delete handle_area(); - -@@ -714,7 +723,7 @@ - - #ifdef ASSERT - void Thread::print_owned_locks_on(outputStream* st) const { -- Mutex *cur = _owned_locks; -+ Monitor *cur = _owned_locks; - if (cur == NULL) { - st->print(" (no locks) "); - } else { -@@ -729,7 +738,7 @@ - static int ref_use_count = 0; - - bool Thread::owns_locks_but_compiled_lock() const { -- for(Mutex *cur = _owned_locks; cur; cur = cur->next()) { -+ for(Monitor *cur = _owned_locks; cur; cur = cur->next()) { - if (cur != Compile_lock) return true; - } - return false; -@@ -756,7 +765,7 @@ - && !Universe::is_bootstrapping()) { - // Make sure we do not hold any locks that the VM thread also uses. - // This could potentially lead to deadlocks -- for(Mutex *cur = _owned_locks; cur; cur = cur->next()) { -+ for(Monitor *cur = _owned_locks; cur; cur = cur->next()) { - // Threads_lock is special, since the safepoint synchronization will not start before this is - // acquired. Hence, a JavaThread cannot be holding it at a safepoint. So is VMOperationRequest_lock, - // since it is used to transfer control between JavaThreads and the VMThread -@@ -2709,6 +2718,10 @@ - _task = NULL; - _queue = queue; - _counters = counters; -+ -+#ifndef PRODUCT -+ _ideal_graph_printer = NULL; -+#endif - } - - -@@ -2834,8 +2847,6 @@ - // crash Linux VM, see notes in os_linux.cpp. - main_thread->create_stack_guard_pages(); - -- HandleMark hm; -- - // Initialize Java-Leve synchronization subsystem - ObjectSynchronizer::Initialize() ; - -@@ -2847,6 +2858,8 @@ - return status; - } - -+ HandleMark hm; -+ - { MutexLocker mu(Threads_lock); - Threads::add(main_thread); - } -@@ -3096,6 +3109,28 @@ - // Try to load the agent from the standard dll directory - hpi::dll_build_name(buffer, sizeof(buffer), Arguments::get_dll_dir(), name); - library = hpi::dll_load(buffer, ebuf, sizeof ebuf); -+#ifdef KERNEL -+ // Download instrument dll -+ if (library == NULL && strcmp(name, "instrument") == 0) { -+ char *props = Arguments::get_kernel_properties(); -+ char *home = Arguments::get_java_home(); -+ const char *fmt = "%s/bin/java %s -Dkernel.background.download=false" -+ " sun.jkernel.DownloadManager -download client_jvm"; -+ int length = strlen(props) + strlen(home) + strlen(fmt) + 1; -+ char *cmd = AllocateHeap(length); -+ jio_snprintf(cmd, length, fmt, home, props); -+ int status = os::fork_and_exec(cmd); -+ FreeHeap(props); -+ FreeHeap(cmd); -+ if (status == -1) { -+ warning(cmd); -+ vm_exit_during_initialization("fork_and_exec failed: %s", -+ strerror(errno)); -+ } -+ // when this comes back the instrument.dll should be where it belongs. -+ library = hpi::dll_load(buffer, ebuf, sizeof ebuf); -+ } -+#endif // KERNEL - if (library == NULL) { // Try the local directory - char ns[1] = {0}; - hpi::dll_build_name(buffer, sizeof(buffer), ns, name); -@@ -3180,6 +3215,33 @@ - JvmtiExport::enter_primordial_phase(); - } - -+extern "C" { -+ typedef void (JNICALL *Agent_OnUnload_t)(JavaVM *); -+} -+ -+void Threads::shutdown_vm_agents() { -+ // Send any Agent_OnUnload notifications -+ const char *on_unload_symbols[] = AGENT_ONUNLOAD_SYMBOLS; -+ extern struct JavaVM_ main_vm; -+ for (AgentLibrary* agent = Arguments::agents(); agent != NULL; agent = agent->next()) { -+ -+ // Find the Agent_OnUnload function. -+ for (uint symbol_index = 0; symbol_index < ARRAY_SIZE(on_unload_symbols); symbol_index++) { -+ Agent_OnUnload_t unload_entry = CAST_TO_FN_PTR(Agent_OnUnload_t, -+ hpi::dll_lookup(agent->os_lib(), on_unload_symbols[symbol_index])); -+ -+ // Invoke the Agent_OnUnload function -+ if (unload_entry != NULL) { -+ JavaThread* thread = JavaThread::current(); -+ ThreadToNativeFromVM ttn(thread); -+ HandleMark hm(thread); -+ (*unload_entry)(&main_vm); -+ break; -+ } -+ } -+ } -+} -+ - // Called for after the VM is initialized for -Xrun libraries which have not been converted to agent libraries - // Invokes JVM_OnLoad - void Threads::create_vm_init_libraries() { -@@ -3322,6 +3384,11 @@ - VMThread::destroy(); - } - -+ // clean up ideal graph printers -+#if defined(COMPILER2) && !defined(PRODUCT) -+ IdealGraphPrinter::clean_up(); -+#endif -+ - // Now, all Java threads are gone except daemon threads. Daemon threads - // running Java code or in VM are stopped by the Safepoint. However, - // daemon threads executing native code are still running. But they -@@ -3690,11 +3757,12 @@ - - // Lifecycle management for TSM ParkEvents. - // ParkEvents are type-stable (TSM). -+// In our particular implementation they happen to be immortal. - // - // We manage concurrency on the FreeList with a CAS-based - // detach-modify-reattach idiom that avoids the ABA problems - // that would otherwise be present in a simple CAS-based --// push-pop implementation. -+// push-pop implementation. (push-one and pop-all) - // - // Caveat: Allocate() and Release() may be called from threads - // other than the thread associated with the Event! -@@ -3714,7 +3782,7 @@ - ParkEvent * volatile ParkEvent::FreeList = NULL ; - - ParkEvent * ParkEvent::Allocate (Thread * t) { -- guarantee (t != NULL, "invariant") ; -+ // In rare cases -- JVM_RawMonitor* operations -- we can find t == null. - ParkEvent * ev ; - - // Start by trying to recycle an existing but unassociated -@@ -3722,7 +3790,7 @@ - for (;;) { - ev = FreeList ; - if (ev == NULL) break ; -- // 1: Detach -+ // 1: Detach - sequester or privatize the list - // Tantamount to ev = Swap (&FreeList, NULL) - if (Atomic::cmpxchg_ptr (NULL, &FreeList, ev) != ev) { - continue ; -@@ -3757,40 +3825,58 @@ - guarantee (ev->AssociatedWith == NULL, "invariant") ; - } else { - // Do this the hard way -- materialize a new ParkEvent. -- // In rare cases an allocating thread might detach -- // a long list -- installing null into FreeList --and -- // then stall. Another thread calling Allocate() would see -- // FreeList == null and then invoke the ctor. In this case we -- // end up with more ParkEvents in circulation than we need, but -- // the race is rare and the outcome is benign. -- // Ideally, the # of extant ParkEvents is equal to the -- // maximum # of threads that existed at any one time. -- // Because of the race mentioned above, segments of the -- // freelist can be transiently inaccessible. At worst -- // we may end up with the # of ParkEvents in circulation -- // slightly above the ideal. -+ // In rare cases an allocating thread might detach a long list -- -+ // installing null into FreeList -- and then stall or be obstructed. -+ // A 2nd thread calling Allocate() would see FreeList == null. -+ // The list held privately by the 1st thread is unavailable to the 2nd thread. -+ // In that case the 2nd thread would have to materialize a new ParkEvent, -+ // even though free ParkEvents existed in the system. In this case we end up -+ // with more ParkEvents in circulation than we need, but the race is -+ // rare and the outcome is benign. Ideally, the # of extant ParkEvents -+ // is equal to the maximum # of threads that existed at any one time. -+ // Because of the race mentioned above, segments of the freelist -+ // can be transiently inaccessible. At worst we may end up with the -+ // # of ParkEvents in circulation slightly above the ideal. -+ // Note that if we didn't have the TSM/immortal constraint, then -+ // when reattaching, above, we could trim the list. - ev = new ParkEvent () ; -+ guarantee ((intptr_t(ev) & 0xFF) == 0, "invariant") ; - } -+ ev->reset() ; // courtesy to caller - ev->AssociatedWith = t ; // Associate ev with t - ev->FreeNext = NULL ; - return ev ; - } - -- -- - void ParkEvent::Release (ParkEvent * ev) { - if (ev == NULL) return ; -- guarantee (ev->AssociatedWith != NULL, "invariant") ; - guarantee (ev->FreeNext == NULL , "invariant") ; - ev->AssociatedWith = NULL ; - for (;;) { - // Push ev onto FreeList -+ // The mechanism is "half" lock-free. - ParkEvent * List = FreeList ; - ev->FreeNext = List ; - if (Atomic::cmpxchg_ptr (ev, &FreeList, List) == List) break ; - } - } - -+// Override operator new and delete so we can ensure that the -+// least significant byte of ParkEvent addresses is 0. -+// Beware that excessive address alignment is undesirable -+// as it can result in D$ index usage imbalance as -+// well as bank access imbalance on Niagara-like platforms, -+// although Niagara's hash function should help. -+ -+void * ParkEvent::operator new (size_t sz) { -+ return (void *) ((intptr_t (CHeapObj::operator new (sz + 256)) + 256) & -256) ; -+} -+ -+void ParkEvent::operator delete (void * a) { -+ // ParkEvents are type-stable and immortal ... -+ ShouldNotReachHere(); -+} -+ - - // 6399321 As a temporary measure we copied & modified the ParkEvent:: - // allocate() and release() code for use by Parkers. The Parker:: forms -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/thread.hpp openjdk/hotspot/src/share/vm/runtime/thread.hpp ---- openjdk6/hotspot/src/share/vm/runtime/thread.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/thread.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)thread.hpp 1.453 07/07/05 17:14:54 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -32,6 +29,7 @@ - class JvmtiGetLoadedClassesClosure; - class ThreadStatistics; - class ConcurrentLocksDump; -+class ParkEvent ; - - class ciEnv; - class CompileThread; -@@ -39,7 +37,6 @@ - class CompileTask; - class CompileQueue; - class CompilerCounters; --class RawMonitor; - class vframeArray; - - class DeoptResourceMark; -@@ -47,6 +44,7 @@ - - class GCTaskQueue; - class ThreadClosure; -+class IdealGraphPrinter; - - // Class hierarchy - // - Thread -@@ -458,15 +456,16 @@ - #ifdef ASSERT - private: - // Deadlock detection support for Mutex locks. List of locks own by thread. -- Mutex *_owned_locks; -+ Monitor *_owned_locks; - // Mutex::set_owner_implementation is the only place where _owned_locks is modified, - // thus the friendship - friend class Mutex; -+ friend class Monitor; - - public: - void print_owned_locks_on(outputStream* st) const; - void print_owned_locks() const { print_owned_locks_on(tty); } -- Mutex* owned_locks() const { return _owned_locks; } -+ Monitor * owned_locks() const { return _owned_locks; } - bool owns_locks() const { return owned_locks() != NULL; } - bool owns_locks_but_compiled_lock() const; - -@@ -511,17 +510,34 @@ - public: - volatile intptr_t _Stalled ; - volatile int _TypeTag ; -- class ParkEvent * _ParkEvent ; -+ ParkEvent * _ParkEvent ; // for synchronized() -+ ParkEvent * _SleepEvent ; // for Thread.sleep -+ ParkEvent * _MutexEvent ; // for native internal Mutex/Monitor -+ ParkEvent * _MuxEvent ; // for low-level muxAcquire-muxRelease -+ int NativeSyncRecursion ; // diagnostic -+ - volatile int _OnTrap ; // Resume-at IP delta -- int _hashStateW ; -- int _hashStateX ; // thread-specific hashCode generator state -- int _hashStateY ; -- int _hashStateZ ; -+ jint _hashStateW ; // Marsaglia Shift-XOR thread-local RNG -+ jint _hashStateX ; // thread-specific hashCode generator state -+ jint _hashStateY ; -+ jint _hashStateZ ; - void * _schedctl ; -- intptr_t _ScratchA, _ScratchB ; // Scratch locations for fast-path sync code - -+ intptr_t _ScratchA, _ScratchB ; // Scratch locations for fast-path sync code - static ByteSize ScratchA_offset() { return byte_offset_of(Thread, _ScratchA ); } - static ByteSize ScratchB_offset() { return byte_offset_of(Thread, _ScratchB ); } -+ -+ volatile jint rng [4] ; // RNG for spin loop -+ -+ // Low-level leaf-lock primitives used to implement synchronization -+ // and native monitor-mutex infrastructure. -+ // Not for general synchronization use. -+ static void SpinAcquire (volatile int * Lock, const char * Name) ; -+ static void SpinRelease (volatile int * Lock) ; -+ static void muxAcquire (volatile intptr_t * Lock, const char * Name) ; -+ static void muxAcquireW (volatile intptr_t * Lock, ParkEvent * ev) ; -+ static void muxRelease (volatile intptr_t * Lock) ; -+ - }; - - // Inline implementation of Thread::current() -@@ -1513,6 +1529,14 @@ - _log = log; - } - -+#ifndef PRODUCT -+private: -+ IdealGraphPrinter *_ideal_graph_printer; -+public: -+ IdealGraphPrinter *ideal_graph_printer() { return _ideal_graph_printer; } -+ void set_ideal_graph_printer(IdealGraphPrinter *n) { _ideal_graph_printer = n; } -+#endif -+ - // Get/set the thread's current task - CompileTask* task() { return _task; } - void set_task(CompileTask* task) { _task = task; } -@@ -1548,6 +1572,7 @@ - static void convert_vm_init_libraries_to_agents(); - static void create_vm_init_libraries(); - static void create_vm_init_agents(); -+ static void shutdown_vm_agents(); - static bool destroy_vm(); - // Supported VM versions via JNI - // Includes JNI_VERSION_1_1 -@@ -1658,15 +1683,16 @@ - // unpark threads. - // - // The base-class, PlatformEvent, is platform-specific while the ParkEvent is --// platform-independent. PlatformEvent provides park(), unpark(), etc. -+// platform-independent. PlatformEvent provides park(), unpark(), etc., and -+// is abstract -- that is, a PlatformEvent should never be instantiated except -+// as part of a ParkEvent. - // Equivalently we could have defined a platform-independent base-class that - // exported Allocate(), Release(), etc. The platform-specific class would extend - // that base-class, adding park(), unpark(), etc. - // --// A word of caution: The JVM uses 3 very similar constructs: -+// A word of caution: The JVM uses 2 very similar constructs: - // 1. ParkEvent are used for Java-level "monitor" synchronization. - // 2. Parkers are used by JSR166-JUC park-unpark. --// 3. interrupt_event() is used for threads blocked in Thread.sleep(). - // - // We'll want to eventually merge these redundant facilities and use ParkEvent. - -@@ -1680,16 +1706,18 @@ - intptr_t RawThreadIdentity ; // LWPID etc - volatile int Incarnation ; - -+ // diagnostic : keep track of last thread to wake this thread. -+ // this is useful for construction of dependency graphs. -+ void * LastWaker ; -+ - public: -- // MCS-CLH list linkage -+ // MCS-CLH list linkage and Native Mutex/Monitor - ParkEvent * volatile ListNext ; - ParkEvent * volatile ListPrev ; - volatile intptr_t OnList ; - volatile int TState ; -- -- // diagnostic : keep track of last thread to wake this thread. -- // this is useful for construction of dependency graphs. -- void * LastWaker ; -+ volatile int Notified ; // for native monitor construct -+ volatile int IsWaiting ; // Enqueued on WaitSet - - - private: -@@ -1712,11 +1740,18 @@ - ListPrev = NULL ; - OnList = 0 ; - TState = 0 ; -+ Notified = 0 ; -+ IsWaiting = 0 ; - } - -+ // We use placement-new to force ParkEvent instances to be -+ // aligned on 256-byte address boundaries. This ensures that the least -+ // significant byte of a ParkEvent address is always 0. -+ -+ void * operator new (size_t sz) ; -+ void operator delete (void * a) ; -+ - public: - static ParkEvent * Allocate (Thread * t) ; - static void Release (ParkEvent * e) ; - } ; -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/threadCritical.hpp openjdk/hotspot/src/share/vm/runtime/threadCritical.hpp ---- openjdk6/hotspot/src/share/vm/runtime/threadCritical.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/threadCritical.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)threadCritical.hpp 1.13 07/05/05 17:07:00 JVM" --#endif - /* - * Copyright 2001-2002 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -54,5 +51,3 @@ - ThreadCritical(); - ~ThreadCritical(); - }; -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/threadLocalStorage.cpp openjdk/hotspot/src/share/vm/runtime/threadLocalStorage.cpp ---- openjdk6/hotspot/src/share/vm/runtime/threadLocalStorage.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/threadLocalStorage.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)threadLocalStorage.cpp 1.46 07/05/05 17:07:00 JVM" --#endif - /* - * Copyright 1997-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -50,4 +47,3 @@ - set_thread_index(os::allocate_thread_local_storage()); - generate_code_for_get_thread(); - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/threadLocalStorage.hpp openjdk/hotspot/src/share/vm/runtime/threadLocalStorage.hpp ---- openjdk6/hotspot/src/share/vm/runtime/threadLocalStorage.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/threadLocalStorage.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)threadLocalStorage.hpp 1.45 07/05/05 17:07:00 JVM" --#endif - /* - * Copyright 1997-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -63,4 +60,3 @@ - static void pd_invalidate_all(); - - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/timer.cpp openjdk/hotspot/src/share/vm/runtime/timer.cpp ---- openjdk6/hotspot/src/share/vm/runtime/timer.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/timer.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)timer.cpp 1.33 07/05/05 17:06:59 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/timer.hpp openjdk/hotspot/src/share/vm/runtime/timer.hpp ---- openjdk6/hotspot/src/share/vm/runtime/timer.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/timer.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)timer.hpp 1.36 07/05/05 17:06:59 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/unhandledOops.cpp openjdk/hotspot/src/share/vm/runtime/unhandledOops.cpp ---- openjdk6/hotspot/src/share/vm/runtime/unhandledOops.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/unhandledOops.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)unhandledOops.cpp 1.11 07/05/05 17:07:00 JVM" --#endif - /* - * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/unhandledOops.hpp openjdk/hotspot/src/share/vm/runtime/unhandledOops.hpp ---- openjdk6/hotspot/src/share/vm/runtime/unhandledOops.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/unhandledOops.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)unhandledOops.hpp 1.7 07/05/05 17:07:01 JVM" --#endif - /* - * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/vframe.cpp openjdk/hotspot/src/share/vm/runtime/vframe.cpp ---- openjdk6/hotspot/src/share/vm/runtime/vframe.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/vframe.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)vframe.cpp 1.162 07/05/17 16:07:02 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -547,7 +544,8 @@ - void javaVFrame::print_value() const { - methodOop m = method(); - klassOop k = m->method_holder(); -- tty->print_cr("frame( sp=" INTPTR_FORMAT ", fp=" INTPTR_FORMAT ", pc=" INTPTR_FORMAT ")", _fr.sp(), _fr.fp(), _fr.pc()); -+ tty->print_cr("frame( sp=" INTPTR_FORMAT ", unextended_sp=" INTPTR_FORMAT ", fp=" INTPTR_FORMAT ", pc=" INTPTR_FORMAT ")", -+ _fr.sp(), _fr.unextended_sp(), _fr.fp(), _fr.pc()); - tty->print("%s.%s", Klass::cast(k)->internal_name(), m->name()->as_C_string()); - - if (!m->is_native()) { -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/vframe.hpp openjdk/hotspot/src/share/vm/runtime/vframe.hpp ---- openjdk6/hotspot/src/share/vm/runtime/vframe.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/vframe.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)vframe.hpp 1.89 07/05/17 16:07:04 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/vframeArray.cpp openjdk/hotspot/src/share/vm/runtime/vframeArray.cpp ---- openjdk6/hotspot/src/share/vm/runtime/vframeArray.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/vframeArray.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)vframeArray.cpp 1.144 07/06/08 15:21:45 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -141,9 +138,6 @@ - frame* caller, - bool is_top_frame, - int exec_mode) { --#if defined(CC_INTERP) && !defined(IA64) -- ShouldNotReachHere(); --#else - JavaThread* thread = (JavaThread*) Thread::current(); - - // Look at bci and decide on bcp and continuation pc -@@ -169,7 +163,7 @@ - // For Compiler2, there should be no pending exception when deoptimizing at monitorenter - // because there is no safepoint at the null pointer check (it is either handled explicitly - // or prior to the monitorenter) and asynchronous exceptions are not made "pending" by the -- // runtime interface for the slow case (see JRT_ENTRY_NO_ASYNC). If an asynchronous -+ // runtime interface for the slow case (see JRT_ENTRY_FOR_MONITORENTER). If an asynchronous - // exception was processed, the bytecode pointer would have to be extended one bytecode beyond - // the monitorenter to place it in the proper exception range. - // -@@ -373,6 +367,7 @@ - - #ifndef PRODUCT - if (TraceDeoptimization && Verbose) { -+ ttyLocker ttyl; - tty->print_cr("[%d Interpreted Frame]", ++unpack_counter); - iframe()->print_on(tty); - RegisterMap map(thread); -@@ -403,7 +398,6 @@ - - _locals = _expressions = NULL; - --#endif /* !CC_INTERP */ - } - - int vframeArrayElement::on_stack_size(int callee_parameters, -@@ -527,11 +521,6 @@ - caller_frame = *element(index)->iframe(); - } - --#ifdef CC_INTERP --#ifndef IA64 -- ShouldNotReachHere(); --#endif --#endif - - deallocate_monitor_chunks(); - } -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/vframeArray.hpp openjdk/hotspot/src/share/vm/runtime/vframeArray.hpp ---- openjdk6/hotspot/src/share/vm/runtime/vframeArray.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/vframeArray.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)vframeArray.hpp 1.77 07/05/05 17:07:01 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -202,4 +199,3 @@ - #endif - - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/vframe_hp.cpp openjdk/hotspot/src/share/vm/runtime/vframe_hp.cpp ---- openjdk6/hotspot/src/share/vm/runtime/vframe_hp.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/vframe_hp.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)vframe_hp.cpp 1.158 07/05/05 17:07:02 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -163,130 +160,17 @@ - return result; - } - --StackValue *compiledVFrame::create_stack_value(ScopeValue *sv) const { -- if (sv->is_location()) { -- // Stack or register value -- Location loc = ((LocationValue *)sv)->location(); -- --#ifdef SPARC -- // %%%%% Callee-save floats will NOT be working on a Sparc until we -- // handle the case of a 2 floats in a single double register. -- assert( !(loc.is_register() && loc.type() == Location::float_in_dbl), "Sparc does not handle callee-save floats yet" ); --#endif // SPARC -- -- // First find address of value -- -- address value_addr = loc.is_register() -- // Value was in a callee-save register -- ? register_map()->location(VMRegImpl::as_VMReg(loc.register_number())) -- // Else value was directly saved on the stack. The frame's original stack pointer, -- // before any extension by its callee (due to Compiler1 linkage on SPARC), must be used. -- : ((address)_fr.unextended_sp()) + loc.stack_offset(); -- -- // Then package it right depending on type -- // Note: the transfer of the data is thru a union that contains -- // an intptr_t. This is because an interpreter stack slot is -- // really an intptr_t. The use of a union containing an intptr_t -- // ensures that on a 64 bit platform we have proper alignment -- // and that we store the value where the interpreter will expect -- // to find it (i.e. proper endian). Similarly on a 32bit platform -- // using the intptr_t ensures that when a value is larger than -- // a stack slot (jlong/jdouble) that we capture the proper part -- // of the value for the stack slot in question. -- // -- switch( loc.type() ) { -- case Location::float_in_dbl: { // Holds a float in a double register? -- // The callee has no clue whether the register holds a float, -- // double or is unused. He always saves a double. Here we know -- // a double was saved, but we only want a float back. Narrow the -- // saved double to the float that the JVM wants. -- assert( loc.is_register(), "floats always saved to stack in 1 word" ); -- union { intptr_t p; jfloat jf; } value; -- value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF); -- value.jf = (jfloat) *(jdouble*) value_addr; -- return new StackValue(value.p); // 64-bit high half is stack junk -- } -- case Location::int_in_long: { // Holds an int in a long register? -- // The callee has no clue whether the register holds an int, -- // long or is unused. He always saves a long. Here we know -- // a long was saved, but we only want an int back. Narrow the -- // saved long to the int that the JVM wants. -- assert( loc.is_register(), "ints always saved to stack in 1 word" ); -- union { intptr_t p; jint ji;} value; -- value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF); -- value.ji = (jint) *(jlong*) value_addr; -- return new StackValue(value.p); // 64-bit high half is stack junk -- } --#ifdef _LP64 -- case Location::dbl: -- // Double value in an aligned adjacent pair -- return new StackValue(*(intptr_t*)value_addr); -- case Location::lng: -- // Long value in an aligned adjacent pair -- return new StackValue(*(intptr_t*)value_addr); --#endif -- case Location::oop: { -- Handle h(*(oop *)value_addr); // Wrap a handle around the oop -- return new StackValue(h); -- } -- case Location::addr: { -- ShouldNotReachHere(); // both C1 and C2 now inline jsrs -- } -- case Location::normal: { -- // Just copy all other bits straight through -- union { intptr_t p; jint ji;} value; -- value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF); -- value.ji = *(jint*)value_addr; -- return new StackValue(value.p); -- } -- case Location::invalid: -- return new StackValue(); -- default: -- ShouldNotReachHere(); -- } - -- } else if (sv->is_constant_int()) { -- // Constant int: treat same as register int. -- union { intptr_t p; jint ji;} value; -- value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF); -- value.ji = (jint)((ConstantIntValue*)sv)->value(); -- return new StackValue(value.p); -- } else if (sv->is_constant_oop()) { -- // constant oop -- return new StackValue(((ConstantOopReadValue *)sv)->value()); --#ifdef _LP64 -- } else if (sv->is_constant_double()) { -- // Constant double in a single stack slot -- union { intptr_t p; double d; } value; -- value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF); -- value.d = ((ConstantDoubleValue *)sv)->value(); -- return new StackValue(value.p); -- } else if (sv->is_constant_long()) { -- // Constant long in a single stack slot -- union { intptr_t p; jlong jl; } value; -- value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF); -- value.jl = ((ConstantLongValue *)sv)->value(); -- return new StackValue(value.p); --#endif -- } -+// The implementation of the following two methods was factorized into the -+// class StackValue because it is also used from within deoptimization.cpp for -+// rematerialization and relocking of non-escaping objects. - -- // Unknown ScopeValue type -- ShouldNotReachHere(); -- return new StackValue((intptr_t) 0); // dummy -+StackValue *compiledVFrame::create_stack_value(ScopeValue *sv) const { -+ return StackValue::create_stack_value(&_fr, register_map(), sv); - } - - BasicLock* compiledVFrame::resolve_monitor_lock(Location location) const { -- assert(location.is_stack(), "for now we only look at the stack"); -- int word_offset = location.stack_offset() / wordSize; -- // (stack picture) -- // high: [ ] word_offset + 1 -- // low [ ] word_offset -- // -- // sp-> [ ] 0 -- // the word_offset is the distance from the stack pointer to the lowest address -- // The frame's original stack pointer, before any extension by its callee -- // (due to Compiler1 linkage on SPARC), must be used. -- return (BasicLock*) (fr().unextended_sp() + word_offset); -+ return StackValue::resolve_monitor_lock(&_fr, location); - } - - -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/vframe_hp.hpp openjdk/hotspot/src/share/vm/runtime/vframe_hp.hpp ---- openjdk6/hotspot/src/share/vm/runtime/vframe_hp.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/vframe_hp.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)vframe_hp.hpp 1.54 07/05/05 17:07:01 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/virtualspace.cpp openjdk/hotspot/src/share/vm/runtime/virtualspace.cpp ---- openjdk6/hotspot/src/share/vm/runtime/virtualspace.cpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/virtualspace.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)virtualspace.cpp 1.62 07/05/05 17:07:03 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -34,21 +31,156 @@ - initialize(size, 0, false, NULL); - } - --ReservedSpace::ReservedSpace(size_t size, size_t forced_base_alignment, -+ReservedSpace::ReservedSpace(size_t size, size_t alignment, - bool large, char* requested_address) { -- initialize(size, forced_base_alignment, large, requested_address); -+ initialize(size, alignment, large, requested_address); - } - --void ReservedSpace::initialize(size_t size, size_t forced_base_alignment, -- bool large, char* requested_address) { -+char * -+ReservedSpace::align_reserved_region(char* addr, const size_t len, -+ const size_t prefix_size, -+ const size_t prefix_align, -+ const size_t suffix_size, -+ const size_t suffix_align) -+{ -+ assert(addr != NULL, "sanity"); -+ const size_t required_size = prefix_size + suffix_size; -+ assert(len >= required_size, "len too small"); -+ -+ const size_t s = size_t(addr); -+ const size_t beg_ofs = s + prefix_size & suffix_align - 1; -+ const size_t beg_delta = beg_ofs == 0 ? 0 : suffix_align - beg_ofs; -+ -+ if (len < beg_delta + required_size) { -+ return NULL; // Cannot do proper alignment. -+ } -+ const size_t end_delta = len - (beg_delta + required_size); -+ -+ if (beg_delta != 0) { -+ os::release_memory(addr, beg_delta); -+ } -+ -+ if (end_delta != 0) { -+ char* release_addr = (char*) (s + beg_delta + required_size); -+ os::release_memory(release_addr, end_delta); -+ } -+ -+ return (char*) (s + beg_delta); -+} -+ -+char* ReservedSpace::reserve_and_align(const size_t reserve_size, -+ const size_t prefix_size, -+ const size_t prefix_align, -+ const size_t suffix_size, -+ const size_t suffix_align) -+{ -+ assert(reserve_size > prefix_size + suffix_size, "should not be here"); -+ -+ char* raw_addr = os::reserve_memory(reserve_size, NULL, prefix_align); -+ if (raw_addr == NULL) return NULL; -+ -+ char* result = align_reserved_region(raw_addr, reserve_size, prefix_size, -+ prefix_align, suffix_size, -+ suffix_align); -+ if (result == NULL && !os::release_memory(raw_addr, reserve_size)) { -+ fatal("os::release_memory failed"); -+ } -+ -+#ifdef ASSERT -+ if (result != NULL) { -+ const size_t raw = size_t(raw_addr); -+ const size_t res = size_t(result); -+ assert(res >= raw, "alignment decreased start addr"); -+ assert(res + prefix_size + suffix_size <= raw + reserve_size, -+ "alignment increased end addr"); -+ assert((res & prefix_align - 1) == 0, "bad alignment of prefix"); -+ assert((res + prefix_size & suffix_align - 1) == 0, -+ "bad alignment of suffix"); -+ } -+#endif -+ -+ return result; -+} -+ -+ReservedSpace::ReservedSpace(const size_t prefix_size, -+ const size_t prefix_align, -+ const size_t suffix_size, -+ const size_t suffix_align) -+{ -+ assert(prefix_size != 0, "sanity"); -+ assert(prefix_align != 0, "sanity"); -+ assert(suffix_size != 0, "sanity"); -+ assert(suffix_align != 0, "sanity"); -+ assert((prefix_size & prefix_align - 1) == 0, -+ "prefix_size not divisible by prefix_align"); -+ assert((suffix_size & suffix_align - 1) == 0, -+ "suffix_size not divisible by suffix_align"); -+ assert((suffix_align & prefix_align - 1) == 0, -+ "suffix_align not divisible by prefix_align"); -+ -+ // On systems where the entire region has to be reserved and committed up -+ // front, the compound alignment normally done by this method is unnecessary. -+ const bool try_reserve_special = UseLargePages && -+ prefix_align == os::large_page_size(); -+ if (!os::can_commit_large_page_memory() && try_reserve_special) { -+ initialize(prefix_size + suffix_size, prefix_align, true); -+ return; -+ } - -- assert(size % os::vm_allocation_granularity() == 0, -- "size not allocation aligned"); -- assert((forced_base_alignment % os::vm_allocation_granularity()) == 0, -- "size not allocation aligned"); - _base = NULL; - _size = 0; -+ _alignment = 0; - _special = false; -+ -+ // Optimistically try to reserve the exact size needed. -+ const size_t size = prefix_size + suffix_size; -+ char* addr = os::reserve_memory(size, NULL, prefix_align); -+ if (addr == NULL) return; -+ -+ // Check whether the result has the needed alignment (unlikely unless -+ // prefix_align == suffix_align). -+ const size_t ofs = size_t(addr) + prefix_size & suffix_align - 1; -+ if (ofs != 0) { -+ // Wrong alignment. Release, allocate more space and do manual alignment. -+ // -+ // On most operating systems, another allocation with a somewhat larger size -+ // will return an address "close to" that of the previous allocation. The -+ // result is often the same address (if the kernel hands out virtual -+ // addresses from low to high), or an address that is offset by the increase -+ // in size. Exploit that to minimize the amount of extra space requested. -+ if (!os::release_memory(addr, size)) { -+ fatal("os::release_memory failed"); -+ } -+ -+ const size_t extra = MAX2(ofs, suffix_align - ofs); -+ addr = reserve_and_align(size + extra, prefix_size, prefix_align, -+ suffix_size, suffix_align); -+ if (addr == NULL) { -+ // Try an even larger region. If this fails, address space is exhausted. -+ addr = reserve_and_align(size + suffix_align, prefix_size, -+ prefix_align, suffix_size, suffix_align); -+ } -+ } -+ -+ _base = addr; -+ _size = size; -+ _alignment = prefix_align; -+} -+ -+void ReservedSpace::initialize(size_t size, size_t alignment, bool large, -+ char* requested_address) { -+ const size_t granularity = os::vm_allocation_granularity(); -+ assert((size & granularity - 1) == 0, -+ "size not aligned to os::vm_allocation_granularity()"); -+ assert((alignment & granularity - 1) == 0, -+ "alignment not aligned to os::vm_allocation_granularity()"); -+ assert(alignment == 0 || is_power_of_2((intptr_t)alignment), -+ "not a power of 2"); -+ -+ _base = NULL; -+ _size = 0; -+ _special = false; -+ _alignment = 0; - if (size == 0) { - return; - } -@@ -68,8 +200,8 @@ - - if (base != NULL) { - // Check alignment constraints -- if (forced_base_alignment > 0) { -- assert((uintptr_t) base % forced_base_alignment == 0, -+ if (alignment > 0) { -+ assert((uintptr_t) base % alignment == 0, - "Large pages returned a non-aligned address"); - } - _special = true; -@@ -90,23 +222,23 @@ - if (requested_address != 0) { - base = os::attempt_reserve_memory_at(size, requested_address); - } else { -- base = os::reserve_memory(size, NULL); -+ base = os::reserve_memory(size, NULL, alignment); - } - - if (base == NULL) return; - - // Check alignment constraints -- if (forced_base_alignment > 0 && ((uintptr_t) base % forced_base_alignment != 0)) { -+ if (alignment > 0 && ((size_t)base & alignment - 1) != 0) { - // Base not aligned, retry - if (!os::release_memory(base, size)) fatal("os::release_memory failed"); - // Reserve size large enough to do manual alignment and - // increase size to a multiple of the desired alignment -- size = align_size_up(size, forced_base_alignment); -- size_t extra_size = size + forced_base_alignment; -- char* extra_base = os::reserve_memory(extra_size); -+ size = align_size_up(size, alignment); -+ size_t extra_size = size + alignment; -+ char* extra_base = os::reserve_memory(extra_size, NULL, alignment); - if (extra_base == NULL) return; - // Do manual alignement -- base = (char*) align_size_up((uintptr_t) extra_base, forced_base_alignment); -+ base = (char*) align_size_up((uintptr_t) extra_base, alignment); - assert(base >= extra_base, "just checking"); - // Release unused areas - size_t unused_bottom_size = base - extra_base; -@@ -126,6 +258,8 @@ - // Done - _base = base; - _size = size; -+ _alignment = MAX2(alignment, (size_t) os::vm_page_size()); -+ - assert(markOopDesc::encode_pointer_as_mark(_base)->decode_pointer() == _base, - "area must be distinguisable from marks for mark-sweep"); - assert(markOopDesc::encode_pointer_as_mark(&_base[size])->decode_pointer() == &_base[size], -@@ -133,29 +267,33 @@ - } - - --ReservedSpace::ReservedSpace(char* base, size_t size, bool special) { -+ReservedSpace::ReservedSpace(char* base, size_t size, size_t alignment, -+ bool special) { - assert((size % os::vm_allocation_granularity()) == 0, - "size not allocation aligned"); - _base = base; - _size = size; -+ _alignment = alignment; - _special = special; - } - - --ReservedSpace ReservedSpace::first_part(size_t partition_size, -+ReservedSpace ReservedSpace::first_part(size_t partition_size, size_t alignment, - bool split, bool realloc) { - assert(partition_size <= size(), "partition failed"); - if (split) { - os::split_reserved_memory(_base, _size, partition_size, realloc); - } -- ReservedSpace result(base(), partition_size, special()); -+ ReservedSpace result(base(), partition_size, alignment, special()); - return result; - } - - --ReservedSpace ReservedSpace::last_part(size_t partition_size) { -+ReservedSpace -+ReservedSpace::last_part(size_t partition_size, size_t alignment) { - assert(partition_size <= size(), "partition failed"); -- ReservedSpace result(base() + partition_size, size() - partition_size, special()); -+ ReservedSpace result(base() + partition_size, size() - partition_size, -+ alignment, special()); - return result; - } - -@@ -235,11 +373,7 @@ - // No attempt is made to force large page alignment at the very top and - // bottom of the space if they are not aligned so already. - _lower_alignment = os::vm_page_size(); -- if (UseLargePages && rs.size() >= os::large_page_size()) { -- _middle_alignment = os::large_page_size(); -- } else { -- _middle_alignment = os::vm_page_size(); -- } -+ _middle_alignment = os::page_size_for_region(rs.size(), rs.size(), 1); - _upper_alignment = os::vm_page_size(); - - // End of each region -@@ -568,4 +702,3 @@ - } - - #endif -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/virtualspace.hpp openjdk/hotspot/src/share/vm/runtime/virtualspace.hpp ---- openjdk6/hotspot/src/share/vm/runtime/virtualspace.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/virtualspace.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)virtualspace.hpp 1.41 07/05/05 17:07:02 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -32,31 +29,62 @@ - private: - char* _base; - size_t _size; -+ size_t _alignment; - bool _special; - - // ReservedSpace -- ReservedSpace(char* base, size_t size, bool large); -- void initialize(size_t size, size_t forced_base_alignment, -- bool large, char* requested_address = NULL); -+ ReservedSpace(char* base, size_t size, size_t alignment, bool special); -+ void initialize(size_t size, size_t alignment, bool large, -+ char* requested_address = NULL); -+ -+ // Release parts of an already-reserved memory region [addr, addr + len) to -+ // get a new region that has "compound alignment." Return the start of the -+ // resulting region, or NULL on failure. -+ // -+ // The region is logically divided into a prefix and a suffix. The prefix -+ // starts at the result address, which is aligned to prefix_align. The suffix -+ // starts at result address + prefix_size, which is aligned to suffix_align. -+ // The total size of the result region is size prefix_size + suffix_size. -+ char* align_reserved_region(char* addr, const size_t len, -+ const size_t prefix_size, -+ const size_t prefix_align, -+ const size_t suffix_size, -+ const size_t suffix_align); -+ -+ // Reserve memory, call align_reserved_region() to alignment it and return the -+ // result. -+ char* reserve_and_align(const size_t reserve_size, -+ const size_t prefix_size, -+ const size_t prefix_align, -+ const size_t suffix_size, -+ const size_t suffix_align); - - public: - // Constructor - ReservedSpace(size_t size); -- ReservedSpace(size_t size, size_t forced_base_alignment, -- bool large, char* requested_address = NULL); -+ ReservedSpace(size_t size, size_t alignment, bool large, -+ char* requested_address = NULL); -+ ReservedSpace(const size_t prefix_size, const size_t prefix_align, -+ const size_t suffix_size, const size_t suffix_align); - - // Accessors -- char* base() { return _base; } -- size_t size() { return _size; } -- bool special(){ return _special;} -+ char* base() const { return _base; } -+ size_t size() const { return _size; } -+ size_t alignment() const { return _alignment; } -+ bool special() const { return _special; } - -- bool is_reserved() { return _base != NULL; } -+ bool is_reserved() const { return _base != NULL; } - void release(); - - // Splitting -- ReservedSpace first_part(size_t partition_size, -+ ReservedSpace first_part(size_t partition_size, size_t alignment, -+ bool split = false, bool realloc = true); -+ ReservedSpace last_part (size_t partition_size, size_t alignment); -+ -+ // These simply call the above using the default alignment. -+ inline ReservedSpace first_part(size_t partition_size, - bool split = false, bool realloc = true); -- ReservedSpace last_part (size_t partition_size); -+ inline ReservedSpace last_part (size_t partition_size); - - // Alignment - static size_t page_align_size_up(size_t size); -@@ -65,6 +93,16 @@ - static size_t allocation_align_size_down(size_t size); - }; - -+ReservedSpace -+ReservedSpace::first_part(size_t partition_size, bool split, bool realloc) -+{ -+ return first_part(partition_size, alignment(), split, realloc); -+} -+ -+ReservedSpace ReservedSpace::last_part(size_t partition_size) -+{ -+ return last_part(partition_size, alignment()); -+} - - // VirtualSpace is data structure for committing a previously reserved address range in smaller chunks. - -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/vmStructs.cpp openjdk/hotspot/src/share/vm/runtime/vmStructs.cpp ---- openjdk6/hotspot/src/share/vm/runtime/vmStructs.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/vmStructs.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)vmStructs.cpp 1.186 07/08/20 18:05:45 JVM" --#endif - /* - * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -244,6 +241,7 @@ - static_field(Universe, _constantPoolCacheKlassObj, klassOop) \ - static_field(Universe, _compiledICHolderKlassObj, klassOop) \ - static_field(Universe, _systemObjArrayKlassObj, klassOop) \ -+ static_field(Universe, _mirrors[0], oop) \ - static_field(Universe, _main_thread_group, oop) \ - static_field(Universe, _system_thread_group, oop) \ - static_field(Universe, _the_empty_byte_array, typeArrayOop) \ -@@ -289,11 +287,12 @@ - nonstatic_field(CardGeneration, _rs, GenRemSet*) \ - nonstatic_field(CardGeneration, _bts, BlockOffsetSharedArray*) \ - \ -- nonstatic_field(CardTableModRefBS, _whole_heap, MemRegion) \ -+ nonstatic_field(CardTableModRefBS, _whole_heap, const MemRegion) \ -+ nonstatic_field(CardTableModRefBS, _guard_index, const size_t) \ -+ nonstatic_field(CardTableModRefBS, _last_valid_index, const size_t) \ -+ nonstatic_field(CardTableModRefBS, _page_size, const size_t) \ -+ nonstatic_field(CardTableModRefBS, _byte_map_size, const size_t) \ - nonstatic_field(CardTableModRefBS, _byte_map, jbyte*) \ -- nonstatic_field(CardTableModRefBS, _byte_map_size, size_t) \ -- nonstatic_field(CardTableModRefBS, _last_valid_index, size_t) \ -- nonstatic_field(CardTableModRefBS, _guard_index, size_t) \ - nonstatic_field(CardTableModRefBS, _cur_covered_regions, int) \ - nonstatic_field(CardTableModRefBS, _covered, MemRegion*) \ - nonstatic_field(CardTableModRefBS, _committed, MemRegion*) \ -@@ -488,7 +487,6 @@ - static_field(SystemDictionary, _vector_klass, klassOop) \ - static_field(SystemDictionary, _hashtable_klass, klassOop) \ - static_field(SystemDictionary, _box_klasses[0], klassOop) \ -- static_field(SystemDictionary, _mirrors[0], oop) \ - static_field(SystemDictionary, _java_system_loader, oop) \ - \ - /*******************/ \ -@@ -1007,6 +1005,7 @@ - declare_toplevel_type(GenerationSpec) \ - declare_toplevel_type(HeapWord) \ - declare_toplevel_type(MemRegion) \ -+ declare_toplevel_type(const MemRegion) \ - declare_toplevel_type(PermanentGenerationSpec) \ - declare_toplevel_type(ThreadLocalAllocBuffer) \ - declare_toplevel_type(VirtualSpace) \ -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/vmStructs.hpp openjdk/hotspot/src/share/vm/runtime/vmStructs.hpp ---- openjdk6/hotspot/src/share/vm/runtime/vmStructs.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/vmStructs.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)vmStructs.hpp 1.13 07/05/05 17:07:02 JVM" --#endif - /* - * Copyright 2000-2001 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/vmThread.cpp openjdk/hotspot/src/share/vm/runtime/vmThread.cpp ---- openjdk6/hotspot/src/share/vm/runtime/vmThread.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/vmThread.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)vmThread.cpp 1.91 07/05/23 10:54:15 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -204,11 +201,6 @@ - PerfDataManager::create_counter(SUN_THREADS, "vmOperationTime", - PerfData::U_Ticks, CHECK); - } -- -- // Initialize safepoint intrumentation buffer etc. -- if (PrintSafepointStatistics || PrintSafepointStatisticsTimeout > 0){ -- SafepointSynchronize::initialize_stat(); -- } - } - - -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/vmThread.hpp openjdk/hotspot/src/share/vm/runtime/vmThread.hpp ---- openjdk6/hotspot/src/share/vm/runtime/vmThread.hpp 2008-07-10 22:04:36.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/vmThread.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)vmThread.hpp 1.40 07/05/05 17:07:03 JVM" --#endif - /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -149,5 +146,3 @@ - // Pointer to single-instance of VM thread - static VMThread* _vm_thread; - }; -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/vm_operations.cpp openjdk/hotspot/src/share/vm/runtime/vm_operations.cpp ---- openjdk6/hotspot/src/share/vm/runtime/vm_operations.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/vm_operations.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)vm_operations.cpp 1.192 07/05/23 10:54:18 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/vm_operations.hpp openjdk/hotspot/src/share/vm/runtime/vm_operations.hpp ---- openjdk6/hotspot/src/share/vm/runtime/vm_operations.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/vm_operations.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)vm_operations.hpp 1.130 07/05/23 10:54:21 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/vm_version.cpp openjdk/hotspot/src/share/vm/runtime/vm_version.cpp ---- openjdk6/hotspot/src/share/vm/runtime/vm_version.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/vm_version.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)vm_version.cpp 1.57 07/08/20 18:10:11 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -89,12 +86,16 @@ - #define VMLP "" - #endif - -+#ifdef KERNEL -+ #define VMTYPE "Kernel" -+#else // KERNEL - #ifdef TIERED - #define VMTYPE "Server" - #else - #define VMTYPE COMPILER1_PRESENT("Client") \ - COMPILER2_PRESENT("Server") - #endif // TIERED -+#endif // KERNEL - - #ifndef HOTSPOT_VM_DISTRO - #error HOTSPOT_VM_DISTRO must be defined -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/vm_version.hpp openjdk/hotspot/src/share/vm/runtime/vm_version.hpp ---- openjdk6/hotspot/src/share/vm/runtime/vm_version.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/vm_version.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)vm_version.hpp 1.27 07/08/08 19:44:04 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -66,5 +63,10 @@ - static unsigned int logical_processors_per_package() { - return _logical_processors_per_package; - } --}; - -+ // Number of page sizes efficiently supported by the hardware. Most chips now -+ // support two sizes, thus this default implementation. Processor-specific -+ // subclasses should define new versions to hide this one as needed. Note -+ // that the O/S may support more sizes, but at most this many are used. -+ static uint page_size_count() { return 2; } -+}; -diff -ruNb openjdk6/hotspot/src/share/vm/runtime/vtune.hpp openjdk/hotspot/src/share/vm/runtime/vtune.hpp ---- openjdk6/hotspot/src/share/vm/runtime/vtune.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/runtime/vtune.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)vtune.hpp 1.20 07/05/05 17:07:01 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -56,4 +53,3 @@ - VTuneClassLoadMarker() { VTune::start_class_load(); } - ~VTuneClassLoadMarker() { VTune::end_class_load(); } - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/services/attachListener.cpp openjdk/hotspot/src/share/vm/services/attachListener.cpp ---- openjdk6/hotspot/src/share/vm/services/attachListener.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/services/attachListener.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)attachListener.cpp 1.22 07/05/05 17:07:04 JVM" --#endif - /* - * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -140,6 +137,7 @@ - return JNI_OK; - } - -+#ifndef SERVICES_KERNEL // Heap dumping not supported - // Implementation of "dumpheap" command. - // - // Input arguments :- -@@ -180,6 +178,7 @@ - } - return JNI_OK; - } -+#endif // SERVICES_KERNEL - - // Implementation of "inspectheap" command - // -@@ -326,7 +325,9 @@ - static AttachOperationFunctionInfo funcs[] = { - { "agentProperties", get_agent_properties }, - { "datadump", data_dump }, -+#ifndef SERVICES_KERNEL - { "dumpheap", dump_heap }, -+#endif // SERVICES_KERNEL - { "load", JvmtiExport::load_agent_library }, - { "properties", get_system_properties }, - { "threaddump", thread_dump }, -diff -ruNb openjdk6/hotspot/src/share/vm/services/attachListener.hpp openjdk/hotspot/src/share/vm/services/attachListener.hpp ---- openjdk6/hotspot/src/share/vm/services/attachListener.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/services/attachListener.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)attachListener.hpp 1.11 07/05/05 17:07:04 JVM" --#endif - /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -34,6 +31,7 @@ - // complets the result value and any result data is returned to the client - // tool. - -+#ifndef SERVICES_KERNEL - - class AttachOperation; - -@@ -43,25 +41,31 @@ - const char* name; - AttachOperationFunction func; - }; -+#endif // SERVICES_KERNEL - - class AttachListener: AllStatic { -- private: -- static volatile bool _initialized; -- - public: -- static void init(); -- static bool is_initialized() { return _initialized; } -- static void set_initialized() { _initialized = true; } -- static void abort(); -+ static void init() KERNEL_RETURN; -+ static void abort() KERNEL_RETURN; - - // invoke to perform clean-up tasks when all clients detach -- static void detachall(); -+ static void detachall() KERNEL_RETURN; - - // indicates if the Attach Listener needs to be created at startup -- static bool init_at_startup(); -+ static bool init_at_startup() KERNEL_RETURN_(return false;); - - // indicates if we have a trigger to start the Attach Listener -- static bool is_init_trigger(); -+ static bool is_init_trigger() KERNEL_RETURN_(return false;); -+ -+#ifdef SERVICES_KERNEL -+ static bool is_attach_supported() { return false; } -+#else // SERVICES_KERNEL -+ private: -+ static volatile bool _initialized; -+ -+ public: -+ static bool is_initialized() { return _initialized; } -+ static void set_initialized() { _initialized = true; } - - // indicates if this VM supports attach-on-demand - static bool is_attach_supported() { return !DisableAttachMechanism; } -@@ -83,8 +87,10 @@ - - // dequeue the next operation - static AttachOperation* dequeue(); -+#endif // SERVICES_KERNEL - }; - -+#ifndef SERVICES_KERNEL - class AttachOperation: public CHeapObj { - public: - enum { -@@ -138,6 +144,4 @@ - // complete operation by sending result code and any result data to the client - virtual void complete(jint result, bufferedStream* result_stream) = 0; - }; -- -- -- -+#endif // SERVICES_KERNEL -diff -ruNb openjdk6/hotspot/src/share/vm/services/classLoadingService.cpp openjdk/hotspot/src/share/vm/services/classLoadingService.cpp ---- openjdk6/hotspot/src/share/vm/services/classLoadingService.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/services/classLoadingService.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)classLoadingService.cpp 1.15 07/05/05 17:07:04 JVM" --#endif - /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/services/classLoadingService.hpp openjdk/hotspot/src/share/vm/services/classLoadingService.hpp ---- openjdk6/hotspot/src/share/vm/services/classLoadingService.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/services/classLoadingService.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)classLoadingService.hpp 1.10 07/05/05 17:07:05 JVM" --#endif - /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -136,4 +133,3 @@ - _loaded_classes->append(h); - } - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/services/dtraceAttacher.cpp openjdk/hotspot/src/share/vm/services/dtraceAttacher.cpp ---- openjdk6/hotspot/src/share/vm/services/dtraceAttacher.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/services/dtraceAttacher.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)dtraceAttacher.cpp 1.8 07/05/23 10:54:23 JVM" --#endif - /* - * Copyright 2006-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/services/dtraceAttacher.hpp openjdk/hotspot/src/share/vm/services/dtraceAttacher.hpp ---- openjdk6/hotspot/src/share/vm/services/dtraceAttacher.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/services/dtraceAttacher.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)dtraceAttacher.hpp 1.5 07/05/05 17:07:05 JVM" --#endif - /* - * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -45,4 +42,3 @@ - // set ExtendedDTraceProbes flag - static void set_extended_dprobes(bool value); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/services/heapDumper.cpp openjdk/hotspot/src/share/vm/services/heapDumper.cpp ---- openjdk6/hotspot/src/share/vm/services/heapDumper.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/services/heapDumper.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)heapDumper.cpp 1.20 07/05/29 09:44:30 JVM" --#endif - /* - * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -1257,9 +1254,10 @@ - } - - // The VM operation that performs the heap dump --class VM_HeapDumper : public VM_Operation { -+class VM_HeapDumper : public VM_GC_Operation { - private: - DumpWriter* _writer; -+ bool _gc_before_heap_dump; - bool _is_segmented_dump; - jlong _dump_start; - -@@ -1270,6 +1268,8 @@ - jlong dump_start() const { return _dump_start; } - void set_dump_start(jlong pos); - -+ bool skip_operation() const; -+ - // writes a HPROF_LOAD_CLASS record - static void do_load_class(klassOop k); - -@@ -1296,8 +1296,12 @@ - void end_of_dump(); - - public: -- VM_HeapDumper(DumpWriter* writer){ -+ VM_HeapDumper(DumpWriter* writer, bool gc_before_heap_dump) : -+ VM_GC_Operation(0 /* total collections, dummy, ignored */, -+ 0 /* total full collections, dummy, ignored */, -+ gc_before_heap_dump) { - _writer = writer; -+ _gc_before_heap_dump = gc_before_heap_dump; - _is_segmented_dump = false; - _dump_start = (jlong)-1; - } -@@ -1308,6 +1312,10 @@ - void doit(); - }; - -+bool VM_HeapDumper::skip_operation() const { -+ return false; -+} -+ - // sets the dump starting position - void VM_HeapDumper::set_dump_start(jlong pos) { - _dump_start = pos; -@@ -1550,8 +1558,15 @@ - // roots. - - void VM_HeapDumper::doit() { -- // need to ensure that we can iterate over the heap -- Universe::heap()->ensure_parsability(false); // no need to retire TLABs -+ -+ HandleMark hm; -+ CollectedHeap* ch = Universe::heap(); -+ if (_gc_before_heap_dump) { -+ ch->collect_as_vm_thread(GCCause::_heap_dump); -+ } else { -+ // make the heap parsable (no need to retire TLABs) -+ ch->ensure_parsability(false); -+ } - - // Write the file header - use 1.0.2 for large heaps, otherwise 1.0.1 - size_t used; -@@ -1653,13 +1668,8 @@ - return -1; - } - -- // Do a full GC before heap dump -- if (_gc_before_heap_dump) { -- Universe::heap()->collect(GCCause::_heap_dump); -- } - // generate the dump -- MutexLocker ml(Heap_lock); -- VM_HeapDumper dumper(&writer); -+ VM_HeapDumper dumper(&writer, _gc_before_heap_dump); - VMThread::execute(&dumper); - - // close dump file and record any error that the writer may have encountered -@@ -1714,3 +1724,50 @@ - assert(_error != NULL, "allocation failure"); - } - } -+ -+ -+// Called by error reporting -+void HeapDumper::dump_heap() { -+ static char path[JVM_MAXPATHLEN]; -+ -+ // The dump file defaults to java_pid.hprof in the current working -+ // directory. HeapDumpPath= can be used to specify an alternative -+ // dump file name or a directory where dump file is created. -+ bool use_default_filename = true; -+ if (HeapDumpPath == NULL || HeapDumpPath[0] == '\0') { -+ path[0] = '\0'; // HeapDumpPath= not specified -+ } else { -+ assert(strlen(HeapDumpPath) < sizeof(path), "HeapDumpPath too long"); -+ strcpy(path, HeapDumpPath); -+ // check if the path is a directory (must exist) -+ DIR* dir = os::opendir(path); -+ if (dir == NULL) { -+ use_default_filename = false; -+ } else { -+ // HeapDumpPath specified a directory. We append a file separator -+ // (if needed). -+ os::closedir(dir); -+ size_t fs_len = strlen(os::file_separator()); -+ if (strlen(path) >= fs_len) { -+ char* end = path; -+ end += (strlen(path) - fs_len); -+ if (strcmp(end, os::file_separator()) != 0) { -+ assert(strlen(path) + strlen(os::file_separator()) < sizeof(path), -+ "HeapDumpPath too long"); -+ strcat(path, os::file_separator()); -+ } -+ } -+ } -+ } -+ // If HeapDumpPath wasn't a file name then we append the default name -+ if (use_default_filename) { -+ char fn[32]; -+ sprintf(fn, "java_pid%d.hprof", os::current_process_id()); -+ assert(strlen(path) + strlen(fn) < sizeof(path), "HeapDumpPath too long"); -+ strcat(path, fn); -+ } -+ -+ HeapDumper dumper(false /* no GC before heap dump */, -+ true /* send to tty */); -+ dumper.dump(path); -+} -diff -ruNb openjdk6/hotspot/src/share/vm/services/heapDumper.hpp openjdk/hotspot/src/share/vm/services/heapDumper.hpp ---- openjdk6/hotspot/src/share/vm/services/heapDumper.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/services/heapDumper.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,8 +1,5 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)heapDumper.hpp 1.8 07/05/05 17:07:05 JVM" --#endif - /* -- * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. -+ * Copyright 2005-2007 Sun Microsystems, Inc. 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 -@@ -25,7 +22,6 @@ - * - */ - -- - // HeapDumper is used to dump the java heap to file in HPROF binary format: - // - // { HeapDumper dumper(true /* full GC before heap dump */); -@@ -68,5 +64,6 @@ - - // returns error message (resource allocated), or NULL if no error - char* error_as_C_string() const; --}; - -+ static void dump_heap() KERNEL_RETURN; -+}; -diff -ruNb openjdk6/hotspot/src/share/vm/services/jmm.h openjdk/hotspot/src/share/vm/services/jmm.h ---- openjdk6/hotspot/src/share/vm/services/jmm.h 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/services/jmm.h 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)jmm.h 1.36 07/05/05 17:07:04 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -288,4 +285,3 @@ - #endif /* __cplusplus */ - - #endif /* !_JAVA_JMM_H_ */ -- -diff -ruNb openjdk6/hotspot/src/share/vm/services/lowMemoryDetector.cpp openjdk/hotspot/src/share/vm/services/lowMemoryDetector.cpp ---- openjdk6/hotspot/src/share/vm/services/lowMemoryDetector.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/services/lowMemoryDetector.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)lowMemoryDetector.cpp 1.28 07/05/05 17:07:04 JVM" --#endif - /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/services/lowMemoryDetector.hpp openjdk/hotspot/src/share/vm/services/lowMemoryDetector.hpp ---- openjdk6/hotspot/src/share/vm/services/lowMemoryDetector.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/services/lowMemoryDetector.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)lowMemoryDetector.hpp 1.22 07/05/05 17:07:05 JVM" --#endif - /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/services/management.cpp openjdk/hotspot/src/share/vm/services/management.cpp ---- openjdk6/hotspot/src/share/vm/services/management.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/services/management.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)management.cpp 1.82 07/05/05 17:07:05 JVM" --#endif - /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -40,7 +37,7 @@ - klassOop Management::_garbageCollectorMXBean_klass = NULL; - klassOop Management::_managementFactory_klass = NULL; - --jmmOptionalSupport Management::_optional_support; -+jmmOptionalSupport Management::_optional_support = {0}; - TimeStamp Management::_stamp; - - void management_init() { -@@ -83,7 +80,10 @@ - } - _optional_support.isBootClassPathSupported = 1; - _optional_support.isObjectMonitorUsageSupported = 1; -+#ifndef SERVICES_KERNEL -+ // This depends on the heap inspector - _optional_support.isSynchronizerUsageSupported = 1; -+#endif // SERVICES_KERNEL - } - - void Management::initialize(TRAPS) { -@@ -1186,11 +1186,12 @@ - - typeArrayOop ta = typeArrayOop(JNIHandles::resolve(thread_ids)); - int num_threads = (ta != NULL ? ta->length() : 0); -- ThreadDumpResult dump_result(num_threads); -- -- if (ta != NULL) { - typeArrayHandle ids_ah(THREAD, ta); - -+ ThreadDumpResult dump_result(num_threads); // can safepoint -+ -+ if (ids_ah() != NULL) { -+ - // validate the thread id array - validate_thread_id_array(ids_ah, CHECK_NULL); - -@@ -1943,6 +1944,7 @@ - - // Dump heap - Returns 0 if succeeds. - JVM_ENTRY(jint, jmm_DumpHeap0(JNIEnv *env, jstring outputfile, jboolean live)) -+#ifndef SERVICES_KERNEL - ResourceMark rm(THREAD); - oop on = JNIHandles::resolve_external_guard(outputfile); - if (on == NULL) { -@@ -1959,8 +1961,10 @@ - const char* errmsg = dumper.error_as_C_string(); - THROW_MSG_(vmSymbols::java_io_IOException(), errmsg, -1); - } -- - return 0; -+#else // SERVICES_KERNEL -+ return -1; -+#endif // SERVICES_KERNEL - JVM_END - - jlong Management::ticks_to_ms(jlong ticks) { -diff -ruNb openjdk6/hotspot/src/share/vm/services/management.hpp openjdk/hotspot/src/share/vm/services/management.hpp ---- openjdk6/hotspot/src/share/vm/services/management.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/services/management.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)management.hpp 1.23 07/05/05 17:07:05 JVM" --#endif - /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/services/memoryManager.cpp openjdk/hotspot/src/share/vm/services/memoryManager.cpp ---- openjdk6/hotspot/src/share/vm/services/memoryManager.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/services/memoryManager.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)memoryManager.cpp 1.28 07/05/05 17:07:05 JVM" --#endif - /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/services/memoryManager.hpp openjdk/hotspot/src/share/vm/services/memoryManager.hpp ---- openjdk6/hotspot/src/share/vm/services/memoryManager.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/services/memoryManager.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)memoryManager.hpp 1.15 07/05/05 17:07:05 JVM" --#endif - /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/services/memoryPool.cpp openjdk/hotspot/src/share/vm/services/memoryPool.cpp ---- openjdk6/hotspot/src/share/vm/services/memoryPool.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/services/memoryPool.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)memoryPool.cpp 1.35 07/05/29 09:44:30 JVM" --#endif - /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/services/memoryPool.hpp openjdk/hotspot/src/share/vm/services/memoryPool.hpp ---- openjdk6/hotspot/src/share/vm/services/memoryPool.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/services/memoryPool.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)memoryPool.hpp 1.25 07/05/29 09:44:30 JVM" --#endif - /* - * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/services/memoryService.cpp openjdk/hotspot/src/share/vm/services/memoryService.cpp ---- openjdk6/hotspot/src/share/vm/services/memoryService.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/services/memoryService.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)memoryService.cpp 1.35 07/05/29 09:44:30 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/services/memoryService.hpp openjdk/hotspot/src/share/vm/services/memoryService.hpp ---- openjdk6/hotspot/src/share/vm/services/memoryService.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/services/memoryService.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)memoryService.hpp 1.16 07/05/05 17:07:05 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/services/memoryUsage.hpp openjdk/hotspot/src/share/vm/services/memoryUsage.hpp ---- openjdk6/hotspot/src/share/vm/services/memoryUsage.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/services/memoryUsage.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)memoryUsage.hpp 1.12 07/05/05 17:07:06 JVM" --#endif - /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/services/psMemoryPool.cpp openjdk/hotspot/src/share/vm/services/psMemoryPool.cpp ---- openjdk6/hotspot/src/share/vm/services/psMemoryPool.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/services/psMemoryPool.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)psMemoryPool.cpp 1.1 07/05/01 16:48:51 JVM" --#endif - /* - * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/services/psMemoryPool.hpp openjdk/hotspot/src/share/vm/services/psMemoryPool.hpp ---- openjdk6/hotspot/src/share/vm/services/psMemoryPool.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/services/psMemoryPool.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)psMemoryPool.hpp 1.1 07/05/01 16:48:51 JVM" --#endif - /* - * Copyright (c) 2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/services/runtimeService.cpp openjdk/hotspot/src/share/vm/services/runtimeService.cpp ---- openjdk6/hotspot/src/share/vm/services/runtimeService.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/services/runtimeService.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)runtimeService.cpp 1.16 07/05/05 17:07:06 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -97,6 +94,9 @@ - memset((void*) capabilities, '0', len); - capabilities[len-1] = '\0'; - capabilities[0] = AttachListener::is_attach_supported() ? '1' : '0'; -+#ifdef KERNEL -+ capabilities[1] = '1'; -+#endif // KERNEL - PerfDataManager::create_string_constant(SUN_RT, "jvmCapabilities", - capabilities, CHECK); - } -diff -ruNb openjdk6/hotspot/src/share/vm/services/runtimeService.hpp openjdk/hotspot/src/share/vm/services/runtimeService.hpp ---- openjdk6/hotspot/src/share/vm/services/runtimeService.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/services/runtimeService.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)runtimeService.hpp 1.10 07/05/05 17:07:06 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/services/serviceUtil.hpp openjdk/hotspot/src/share/vm/services/serviceUtil.hpp ---- openjdk6/hotspot/src/share/vm/services/serviceUtil.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/services/serviceUtil.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)serviceUtil.hpp 1.8 07/05/05 17:07:06 JVM" --#endif - /* - * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/services/threadService.cpp openjdk/hotspot/src/share/vm/services/threadService.cpp ---- openjdk6/hotspot/src/share/vm/services/threadService.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/services/threadService.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)threadService.cpp 1.54 07/05/17 16:07:12 JVM" --#endif - /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/services/threadService.hpp openjdk/hotspot/src/share/vm/services/threadService.hpp ---- openjdk6/hotspot/src/share/vm/services/threadService.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/services/threadService.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)threadService.hpp 1.41 07/05/05 17:07:06 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -385,16 +382,21 @@ - - void save_old_state(JavaThread* java_thread) { - _java_thread = java_thread; -- _is_alive = (_java_thread != NULL) && (_java_thread->threadObj() != NULL); -+ _is_alive = is_alive(java_thread); - if (is_alive()) { - _old_state = java_lang_Thread::get_thread_status(_java_thread->threadObj()); - } - } - - public: -+ static void set_thread_status(JavaThread* java_thread, -+ java_lang_Thread::ThreadStatus state) { -+ java_lang_Thread::set_thread_status(java_thread->threadObj(), state); -+ } -+ - void set_thread_status(java_lang_Thread::ThreadStatus state) { - if (is_alive()) { -- java_lang_Thread::set_thread_status(_java_thread->threadObj(), state); -+ set_thread_status(_java_thread, state); - } - } - -@@ -411,6 +413,11 @@ - ~JavaThreadStatusChanger() { - set_thread_status(_old_state); - } -+ -+ static bool is_alive(JavaThread* java_thread) { -+ return java_thread != NULL && java_thread->threadObj() != NULL; -+ } -+ - bool is_alive() { - return _is_alive; - } -@@ -479,7 +486,37 @@ - private: - ThreadStatistics* _stat; - bool _active; -+ -+ static bool contended_enter_begin(JavaThread *java_thread) { -+ set_thread_status(java_thread, java_lang_Thread::BLOCKED_ON_MONITOR_ENTER); -+ ThreadStatistics* stat = java_thread->get_thread_stat(); -+ stat->contended_enter(); -+ bool active = ThreadService::is_thread_monitoring_contention(); -+ if (active) { -+ stat->contended_enter_begin(); -+ } -+ return active; -+ } -+ - public: -+ // java_thread is waiting thread being blocked on monitor reenter. -+ // Current thread is the notifying thread which holds the monitor. -+ static bool wait_reenter_begin(JavaThread *java_thread, ObjectMonitor *obj_m) { -+ assert((java_thread != NULL), "Java thread should not be null here"); -+ bool active = false; -+ if (is_alive(java_thread) && ServiceUtil::visible_oop((oop)obj_m->object())) { -+ active = contended_enter_begin(java_thread); -+ } -+ return active; -+ } -+ -+ static void wait_reenter_end(JavaThread *java_thread, bool active) { -+ if (active) { -+ java_thread->get_thread_stat()->contended_enter_end(); -+ } -+ set_thread_status(java_thread, java_lang_Thread::RUNNABLE); -+ } -+ - JavaThreadBlockedOnMonitorEnterState(JavaThread *java_thread, ObjectMonitor *obj_m) : - JavaThreadStatusChanger(java_thread) { - assert((java_thread != NULL), "Java thread should not be null here"); -@@ -487,16 +524,10 @@ - // enter done for external java world objects and it is contended. All other cases - // like for vm internal objects and for external objects which are not contended - // thread status is not changed and contended enter stat is not collected. -+ _active = false; - if (is_alive() && ServiceUtil::visible_oop((oop)obj_m->object()) && obj_m->contentions() > 0) { -- set_thread_status(java_lang_Thread::BLOCKED_ON_MONITOR_ENTER); - _stat = java_thread->get_thread_stat(); -- _stat->contended_enter(); -- _active = ThreadService::is_thread_monitoring_contention(); -- if (_active) { -- _stat->contended_enter_begin(); -- } -- } else { -- _active = false; -+ _active = contended_enter_begin(java_thread); - } - } - -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/accessFlags.cpp openjdk/hotspot/src/share/vm/utilities/accessFlags.cpp ---- openjdk6/hotspot/src/share/vm/utilities/accessFlags.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/accessFlags.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)accessFlags.cpp 1.25 07/05/05 17:07:07 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/accessFlags.hpp openjdk/hotspot/src/share/vm/utilities/accessFlags.hpp ---- openjdk6/hotspot/src/share/vm/utilities/accessFlags.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/accessFlags.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)accessFlags.hpp 1.68 07/05/05 17:07:07 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/array.cpp openjdk/hotspot/src/share/vm/utilities/array.cpp ---- openjdk6/hotspot/src/share/vm/utilities/array.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/array.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)array.cpp 1.20 07/05/05 17:07:07 JVM" --#endif - /* - * Copyright 2000-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/array.hpp openjdk/hotspot/src/share/vm/utilities/array.hpp ---- openjdk6/hotspot/src/share/vm/utilities/array.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/array.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)array.hpp 1.15 07/05/05 17:07:07 JVM" --#endif - /* - * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/bitMap.cpp openjdk/hotspot/src/share/vm/utilities/bitMap.cpp ---- openjdk6/hotspot/src/share/vm/utilities/bitMap.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/bitMap.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)bitMap.cpp 1.48 07/05/05 17:07:07 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/bitMap.hpp openjdk/hotspot/src/share/vm/utilities/bitMap.hpp ---- openjdk6/hotspot/src/share/vm/utilities/bitMap.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/bitMap.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)bitMap.hpp 1.45 07/05/05 17:07:06 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -116,6 +113,10 @@ - } - - public: -+ -+ // Constructs a bitmap with no map, and size 0. -+ BitMap() : _map(NULL), _size(0) {} -+ - // Construction - BitMap(idx_t* map, idx_t size_in_bits); - -@@ -393,4 +394,3 @@ - } - } - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/bitMap.inline.hpp openjdk/hotspot/src/share/vm/utilities/bitMap.inline.hpp ---- openjdk6/hotspot/src/share/vm/utilities/bitMap.inline.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/bitMap.inline.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)bitMap.inline.hpp 1.8 07/05/05 17:07:07 JVM" --#endif - /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/constantTag.cpp openjdk/hotspot/src/share/vm/utilities/constantTag.cpp ---- openjdk6/hotspot/src/share/vm/utilities/constantTag.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/constantTag.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)constantTag.cpp 1.21 07/05/05 17:07:08 JVM" --#endif - /* - * Copyright 1997-1999 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/constantTag.hpp openjdk/hotspot/src/share/vm/utilities/constantTag.hpp ---- openjdk6/hotspot/src/share/vm/utilities/constantTag.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/constantTag.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)constantTag.hpp 1.28 07/05/05 17:07:08 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -87,4 +84,3 @@ - - void print_on(outputStream* st) const PRODUCT_RETURN; - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/copy.hpp openjdk/hotspot/src/share/vm/utilities/copy.hpp ---- openjdk6/hotspot/src/share/vm/utilities/copy.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/copy.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)copy.hpp 1.15 07/05/17 16:07:14 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/debug.cpp openjdk/hotspot/src/share/vm/utilities/debug.cpp ---- openjdk6/hotspot/src/share/vm/utilities/debug.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/debug.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)debug.cpp 1.180 07/05/05 17:07:08 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -252,7 +249,6 @@ - - void report_java_out_of_memory(const char* message) { - static jint out_of_memory_reported = 0; -- static char path[JVM_MAXPATHLEN]; - - // A number of threads may attempt to report OutOfMemoryError at around the - // same time. To avoid dumping the heap or executing the data collection -@@ -262,47 +258,7 @@ - // create heap dump before OnOutOfMemoryError commands are executed - if (HeapDumpOnOutOfMemoryError) { - tty->print_cr("java.lang.OutOfMemoryError: %s", message); -- -- // The dump file defaults to java_pid.hprof in the current working -- // directory. HeapDumpPath= can be used to specify an alternative -- // dump file name or a directory where dump file is created. -- bool use_default_filename = true; -- if (HeapDumpPath == NULL || HeapDumpPath[0] == '\0') { -- path[0] = '\0'; // HeapDumpPath= not specified -- } else { -- assert(strlen(HeapDumpPath) < sizeof(path), "HeapDumpPath too long"); -- strcpy(path, HeapDumpPath); -- // check if the path is a directory (must exist) -- DIR* dir = os::opendir(path); -- if (dir == NULL) { -- use_default_filename = false; -- } else { -- // HeapDumpPath specified a directory. We append a file separator -- // (if needed). -- os::closedir(dir); -- size_t fs_len = strlen(os::file_separator()); -- if (strlen(path) >= fs_len) { -- char* end = path; -- end += (strlen(path) - fs_len); -- if (strcmp(end, os::file_separator()) != 0) { -- assert(strlen(path) + strlen(os::file_separator()) < sizeof(path), -- "HeapDumpPath too long"); -- strcat(path, os::file_separator()); -- } -- } -- } -- } -- // If HeapDumpPath wasn't a file name then we append the default name -- if (use_default_filename) { -- char fn[32]; -- sprintf(fn, "java_pid%d.hprof", os::current_process_id()); -- assert(strlen(path) + strlen(fn) < sizeof(path), "HeapDumpPath too long"); -- strcat(path, fn); -- } -- -- HeapDumper dumper(false /* no GC before heap dump */, -- true /* send to tty */); -- dumper.dump(path); -+ HeapDumper::dump_heap(); - } - - if (OnOutOfMemoryError && OnOutOfMemoryError[0]) { -@@ -978,4 +934,3 @@ - #endif - - #endif // PRODUCT -- -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/debug.hpp openjdk/hotspot/src/share/vm/utilities/debug.hpp ---- openjdk6/hotspot/src/share/vm/utilities/debug.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/debug.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)debug.hpp 1.50 07/05/05 17:07:07 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/defaultStream.hpp openjdk/hotspot/src/share/vm/utilities/defaultStream.hpp ---- openjdk6/hotspot/src/share/vm/utilities/defaultStream.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/defaultStream.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)defaultStream.hpp 1.13 07/05/05 17:07:08 JVM" --#endif - /* - * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/dtrace.hpp openjdk/hotspot/src/share/vm/utilities/dtrace.hpp ---- openjdk6/hotspot/src/share/vm/utilities/dtrace.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/dtrace.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)dtrace.hpp 1.11 07/05/05 17:07:08 JVM" --#endif - /* - * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -126,4 +123,3 @@ - HS_DTRACE_PROBE_N(provider,name,((uintptr_t)a0,(uintptr_t)a1,(uintptr_t)a2,\ - (uintptr_t)a3,(uintptr_t)a4,(uintptr_t)a5,(uintptr_t)a6,(uintptr_t)a7,\ - (uintptr_t)a8,(uintptr_t)a9)) -- -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/events.cpp openjdk/hotspot/src/share/vm/utilities/events.cpp ---- openjdk6/hotspot/src/share/vm/utilities/events.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/events.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)events.cpp 1.40 07/05/05 17:07:07 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -250,4 +247,3 @@ - int print_all_events(outputStream *st) { return 0; } - - #endif // PRODUCT -- -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/events.hpp openjdk/hotspot/src/share/vm/utilities/events.hpp ---- openjdk6/hotspot/src/share/vm/utilities/events.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/events.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)events.hpp 1.22 07/05/05 17:07:09 JVM" --#endif - /* - * Copyright 1997-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -65,4 +62,3 @@ - }; - - int print_all_events(outputStream *st); -- -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/exceptions.cpp openjdk/hotspot/src/share/vm/utilities/exceptions.cpp ---- openjdk6/hotspot/src/share/vm/utilities/exceptions.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/exceptions.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)exceptions.cpp 1.99 07/05/05 17:07:09 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -376,14 +373,14 @@ - #ifndef PRODUCT - // caller frees value_string if necessary - void Exceptions::debug_check_abort(const char *value_string) { -- if (AbortVMOnException[0] != '\0' && value_string != NULL && -+ if (AbortVMOnException != NULL && value_string != NULL && - strstr(value_string, AbortVMOnException)) { - fatal1("Saw %s, aborting", value_string); - } - } - - void Exceptions::debug_check_abort(Handle exception) { -- if (AbortVMOnException[0] != '\0') { -+ if (AbortVMOnException != NULL) { - ResourceMark rm; - debug_check_abort(instanceKlass::cast(exception()->klass())->external_name()); - } -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/exceptions.hpp openjdk/hotspot/src/share/vm/utilities/exceptions.hpp ---- openjdk6/hotspot/src/share/vm/utilities/exceptions.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/exceptions.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)exceptions.hpp 1.51 07/05/05 17:07:09 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -276,5 +273,3 @@ - // exceptions. - - #define EXCEPTION_MARK Thread* THREAD; ExceptionMark __em(THREAD); -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/globalDefinitions.cpp openjdk/hotspot/src/share/vm/utilities/globalDefinitions.cpp ---- openjdk6/hotspot/src/share/vm/utilities/globalDefinitions.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/globalDefinitions.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)globalDefinitions.cpp 1.48 07/05/05 17:07:09 JVM" --#endif - /* - * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/globalDefinitions.hpp openjdk/hotspot/src/share/vm/utilities/globalDefinitions.hpp ---- openjdk6/hotspot/src/share/vm/utilities/globalDefinitions.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/globalDefinitions.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)globalDefinitions.hpp 1.217 07/05/23 10:54:27 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp openjdk/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp ---- openjdk6/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)globalDefinitions_gcc.hpp 1.47 07/05/05 17:07:10 JVM" --#endif - /* - * Copyright 1998-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -276,4 +273,3 @@ - # undef offsetof - #endif - #define offsetof(klass,field) offset_of(klass,field) -- -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp openjdk/hotspot/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp ---- openjdk6/hotspot/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/globalDefinitions_sparcWorks.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)globalDefinitions_sparcWorks.hpp 1.80 07/05/05 17:07:10 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp openjdk/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp ---- openjdk6/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/globalDefinitions_visCPP.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)globalDefinitions_visCPP.hpp 1.68 07/05/05 17:07:10 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/growableArray.cpp openjdk/hotspot/src/share/vm/utilities/growableArray.cpp ---- openjdk6/hotspot/src/share/vm/utilities/growableArray.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/growableArray.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)growableArray.cpp 1.37 07/05/05 17:07:10 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -54,4 +51,3 @@ - return _arena->Amalloc(elementSize * _max); - } - } -- -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/growableArray.hpp openjdk/hotspot/src/share/vm/utilities/growableArray.hpp ---- openjdk6/hotspot/src/share/vm/utilities/growableArray.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/growableArray.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)growableArray.hpp 1.55 07/05/05 17:07:09 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/hashtable.cpp openjdk/hotspot/src/share/vm/utilities/hashtable.cpp ---- openjdk6/hotspot/src/share/vm/utilities/hashtable.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/hashtable.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)hashtable.cpp 1.13 07/05/05 17:07:10 JVM" --#endif - /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/hashtable.hpp openjdk/hotspot/src/share/vm/utilities/hashtable.hpp ---- openjdk6/hotspot/src/share/vm/utilities/hashtable.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/hashtable.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)hashtable.hpp 1.14 07/05/05 17:07:10 JVM" --#endif - /* - * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/hashtable.inline.hpp openjdk/hotspot/src/share/vm/utilities/hashtable.inline.hpp ---- openjdk6/hotspot/src/share/vm/utilities/hashtable.inline.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/hashtable.inline.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)hashtable.inline.hpp 1.9 07/05/05 17:07:10 JVM" --#endif - /* - * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/histogram.cpp openjdk/hotspot/src/share/vm/utilities/histogram.cpp ---- openjdk6/hotspot/src/share/vm/utilities/histogram.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/histogram.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)histogram.cpp 1.21 07/05/05 17:07:09 JVM" --#endif - /* - * Copyright 1998-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/histogram.hpp openjdk/hotspot/src/share/vm/utilities/histogram.hpp ---- openjdk6/hotspot/src/share/vm/utilities/histogram.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/histogram.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)histogram.hpp 1.17 07/05/05 17:07:11 JVM" --#endif - /* - * Copyright 1998-2000 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/macros.hpp openjdk/hotspot/src/share/vm/utilities/macros.hpp ---- openjdk6/hotspot/src/share/vm/utilities/macros.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/macros.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)macros.hpp 1.41 07/05/29 09:44:30 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -38,6 +35,21 @@ - #ifdef KERNEL - #define COMPILER1 - #define SERIALGC -+ -+#define JVMTI_KERNEL -+#define FPROF_KERNEL -+#define VM_STRUCTS_KERNEL -+#define JNICHECK_KERNEL -+#define SERVICES_KERNEL -+ -+#define KERNEL_RETURN {} -+#define KERNEL_RETURN_(code) { code } -+ -+#else // KERNEL -+ -+#define KERNEL_RETURN /* next token must be ; */ -+#define KERNEL_RETURN_(code) /* next token must be ; */ -+ - #endif // KERNEL - - // COMPILER1 variant -@@ -81,6 +93,14 @@ - #define NOT_CHECK_UNHANDLED_OOPS(code) code - #endif // CHECK_UNHANDLED_OOPS - -+#ifdef CC_INTERP -+#define CC_INTERP_ONLY(code) code -+#define NOT_CC_INTERP(code) -+#else -+#define CC_INTERP_ONLY(code) -+#define NOT_CC_INTERP(code) code -+#endif // CC_INTERP -+ - #ifdef ASSERT - #define DEBUG_ONLY(code) code - #define NOT_DEBUG(code) -@@ -159,4 +179,3 @@ - #define FIX_THIS(code) report_assertion_failure("FIX_THIS",__FILE__, __LINE__, "") - - #define define_pd_global(type, name, value) const type pd_##name = value; -- -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/ostream.cpp openjdk/hotspot/src/share/vm/utilities/ostream.cpp ---- openjdk6/hotspot/src/share/vm/utilities/ostream.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/ostream.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)ostream.cpp 1.78 07/06/08 23:17:46 JVM" --#endif - /* - * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -358,7 +355,7 @@ - - void defaultStream::init_log() { - // %%% Need a MutexLocker? -- const char* log_name = strlen(LogFile) > 0 ? LogFile : "hotspot.log"; -+ const char* log_name = LogFile != NULL ? LogFile : "hotspot.log"; - char buf[O_BUFLEN*2]; - const char* try_name = make_log_name(log_name, NULL, buf); - fileStream* file = new(ResourceObj::C_HEAP) fileStream(try_name); -@@ -762,6 +759,7 @@ - } - memcpy(buffer + buffer_pos, s, len); - buffer_pos += len; -+ update_position(s, len); - } - - char* bufferedStream::as_string() { -@@ -777,3 +775,76 @@ - } - } - -+#ifndef PRODUCT -+ -+#if defined(SOLARIS) || defined(LINUX) -+#include -+#include -+#include -+#include -+#endif -+ -+// Network access -+networkStream::networkStream() { -+ -+ _socket = -1; -+ -+ hpi::initialize_socket_library(); -+ -+ int result = hpi::socket(AF_INET, SOCK_STREAM, 0); -+ if (result <= 0) { -+ assert(false, "Socket could not be created!"); -+ } else { -+ _socket = result; -+ } -+} -+ -+int networkStream::read(char *buf, size_t len) { -+ return hpi::recv(_socket, buf, (int)len, 0); -+} -+ -+void networkStream::flush() { -+ if (size() != 0) { -+ hpi::send(_socket, (char *)base(), (int)size(), 0); -+ } -+ reset(); -+} -+ -+networkStream::~networkStream() { -+ close(); -+} -+ -+void networkStream::close() { -+ if (_socket != -1) { -+ flush(); -+ hpi::socket_close(_socket); -+ _socket = -1; -+ } -+} -+ -+bool networkStream::connect(const char *ip, short port) { -+ -+ struct sockaddr_in server; -+ server.sin_family = AF_INET; -+ server.sin_port = htons(port); -+ -+ server.sin_addr.s_addr = inet_addr(ip); -+ if (server.sin_addr.s_addr == (unsigned long)-1) { -+#ifdef _WINDOWS -+ struct hostent* host = hpi::get_host_by_name((char*)ip); -+#else -+ struct hostent* host = gethostbyname(ip); -+#endif -+ if (host != NULL) { -+ memcpy(&server.sin_addr, host->h_addr_list[0], host->h_length); -+ } else { -+ return false; -+ } -+ } -+ -+ -+ int result = hpi::connect(_socket, (struct sockaddr*)&server, sizeof(struct sockaddr_in)); -+ return (result >= 0); -+} -+ -+#endif -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/ostream.hpp openjdk/hotspot/src/share/vm/utilities/ostream.hpp ---- openjdk6/hotspot/src/share/vm/utilities/ostream.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/ostream.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)ostream.hpp 1.43 07/06/08 23:18:20 JVM" --#endif - /* - * Copyright 1997-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -222,3 +219,23 @@ - }; - - #define O_BUFLEN 2000 // max size of output of individual print() methods -+ -+#ifndef PRODUCT -+ -+class networkStream : public bufferedStream { -+ -+ private: -+ int _socket; -+ -+ public: -+ networkStream(); -+ ~networkStream(); -+ -+ bool connect(const char *host, short port); -+ bool is_open() const { return _socket != -1; } -+ int read(char *buf, size_t len); -+ void close(); -+ virtual void flush(); -+}; -+ -+#endif -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/preserveException.cpp openjdk/hotspot/src/share/vm/utilities/preserveException.cpp ---- openjdk6/hotspot/src/share/vm/utilities/preserveException.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/preserveException.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)preserveException.cpp 1.21 07/05/05 17:07:11 JVM" --#endif - /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/preserveException.hpp openjdk/hotspot/src/share/vm/utilities/preserveException.hpp ---- openjdk6/hotspot/src/share/vm/utilities/preserveException.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/preserveException.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)preserveException.hpp 1.20 07/05/05 17:07:11 JVM" --#endif - /* - * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/sizes.cpp openjdk/hotspot/src/share/vm/utilities/sizes.cpp ---- openjdk6/hotspot/src/share/vm/utilities/sizes.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/sizes.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)sizes.cpp 1.11 07/05/05 17:07:10 JVM" --#endif - /* - * Copyright 2000 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/sizes.hpp openjdk/hotspot/src/share/vm/utilities/sizes.hpp ---- openjdk6/hotspot/src/share/vm/utilities/sizes.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/sizes.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)sizes.hpp 1.19 07/05/05 17:07:08 JVM" --#endif - /* - * Copyright 2000-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -145,4 +142,3 @@ - // Use the following #define to get C++ field member offsets - - #define byte_offset_of(klass,field) in_ByteSize((int)offset_of(klass, field)) -- -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/taskqueue.cpp openjdk/hotspot/src/share/vm/utilities/taskqueue.cpp ---- openjdk6/hotspot/src/share/vm/utilities/taskqueue.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/taskqueue.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)taskqueue.cpp 1.25 07/05/05 17:07:10 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -54,8 +51,7 @@ - ParallelTaskTerminator(int n_threads, TaskQueueSetSuper* queue_set) : - _n_threads(n_threads), - _queue_set(queue_set), -- _offered_termination(0), _terminated(0), -- _term_monitor(Mutex::leaf+1, "ParTaskTerm", true) {} -+ _offered_termination(0) {} - - bool ParallelTaskTerminator::peek_in_queue_set() { - return _queue_set->peek(); -@@ -111,519 +107,6 @@ - } - } - --OopTaskQueue::OopTaskQueue() : TaskQueueSuper() { -- assert(sizeof(Age) == sizeof(jint), "Depends on this."); --} -- --void OopTaskQueue::initialize() { -- _elems = NEW_C_HEAP_ARRAY(Task, n()); -- guarantee(_elems != NULL, "Allocation failed."); --} -- --bool OopTaskQueue::push_slow(Task t, juint dirty_n_elems) { -- if (dirty_n_elems == n() - 1) { -- // Actually means 0, so do the push. -- juint localBot = _bottom; -- _elems[localBot] = t; -- _bottom = increment_index(localBot); -- return true; -- } else -- return false; --} -- --bool OopTaskQueue:: --pop_local_slow(juint localBot, Age oldAge) { -- // This queue was observed to contain exactly one element; either this -- // thread will claim it, or a competing "pop_global". In either case, -- // the queue will be logically empty afterwards. Create a new Age value -- // that represents the empty queue for the given value of "_bottom". (We -- // must also increment "tag" because of the case where "bottom == 1", -- // "top == 0". A pop_global could read the queue element in that case, -- // then have the owner thread do a pop followed by another push. Without -- // the incrementing of "tag", the pop_global's CAS could succeed, -- // allowing it to believe it has claimed the stale element.) -- Age newAge; -- newAge._top = localBot; -- newAge._tag = oldAge.tag() + 1; -- // Perhaps a competing pop_global has already incremented "top", in which -- // case it wins the element. -- if (localBot == oldAge.top()) { -- Age tempAge; -- // No competing pop_global has yet incremented "top"; we'll try to -- // install new_age, thus claiming the element. -- assert(sizeof(Age) == sizeof(jint) && sizeof(jint) == sizeof(juint), -- "Assumption about CAS unit."); -- *(jint*)&tempAge = Atomic::cmpxchg(*(jint*)&newAge, (volatile jint*)&_age, *(jint*)&oldAge); -- if (tempAge == oldAge) { -- // We win. -- assert(dirty_size(localBot, get_top()) != n() - 1, -- "Shouldn't be possible..."); -- return true; -- } -- } -- // We fail; a completing pop_global gets the element. But the queue is -- // empty (and top is greater than bottom.) Fix this representation of -- // the empty queue to become the canonical one. -- set_age(newAge); -- assert(dirty_size(localBot, get_top()) != n() - 1, -- "Shouldn't be possible..."); -- return false; --} -- --bool OopTaskQueue::pop_global(Task& t) { -- Age newAge; -- Age oldAge = get_age(); -- juint localBot = _bottom; -- juint n_elems = size(localBot, oldAge.top()); -- if (n_elems == 0) { -- return false; -- } -- t = _elems[oldAge.top()]; -- newAge = oldAge; -- newAge._top = increment_index(newAge.top()); -- if ( newAge._top == 0 ) newAge._tag++; -- Age resAge; -- *(jint*)&resAge = Atomic::cmpxchg(*(jint*)&newAge, (volatile jint*)&_age, *(jint*)&oldAge); -- // Note that using "_bottom" here might fail, since a pop_local might -- // have decremented it. -- assert(dirty_size(localBot, newAge._top) != n() - 1, -- "Shouldn't be possible..."); -- return (resAge == oldAge); --} -- --OopTaskQueue::~OopTaskQueue() { -- FREE_C_HEAP_ARRAY(Task, _elems); --} -- --OopStarTaskQueue::OopStarTaskQueue() : TaskQueueSuper() { -- assert(sizeof(Age) == sizeof(jint), "Depends on this."); --} -- --void OopStarTaskQueue::initialize() { -- _elems = NEW_C_HEAP_ARRAY(StarTask, n()); -- guarantee(_elems != NULL, "Allocation failed."); --} -- --bool OopStarTaskQueue::push_slow(StarTask t, juint dirty_n_elems) { -- if (dirty_n_elems == n() - 1) { -- // Actually means 0, so do the push. -- juint localBot = _bottom; -- _elems[localBot] = t; -- _bottom = increment_index(localBot); -- return true; -- } else -- return false; --} -- --bool OopStarTaskQueue:: --pop_local_slow(juint localBot, Age oldAge) { -- // This queue was observed to contain exactly one element; either this -- // thread will claim it, or a competing "pop_global". In either case, -- // the queue will be logically empty afterwards. Create a new Age value -- // that represents the empty queue for the given value of "_bottom". (We -- // must also increment "tag" because of the case where "bottom == 1", -- // "top == 0". A pop_global could read the queue element in that case, -- // then have the owner thread do a pop followed by another push. Without -- // the incrementing of "tag", the pop_global's CAS could succeed, -- // allowing it to believe it has claimed the stale element.) -- Age newAge; -- newAge._top = localBot; -- newAge._tag = oldAge.tag() + 1; -- // Perhaps a competing pop_global has already incremented "top", in which -- // case it wins the element. -- if (localBot == oldAge.top()) { -- Age tempAge; -- // No competing pop_global has yet incremented "top"; we'll try to -- // install new_age, thus claiming the element. -- assert(sizeof(Age) == sizeof(jint) && sizeof(jint) == sizeof(juint), -- "Assumption about CAS unit."); -- *(jint*)&tempAge = Atomic::cmpxchg(*(jint*)&newAge, (volatile jint*)&_age, *(jint*)&oldAge); -- if (tempAge == oldAge) { -- // We win. -- assert(dirty_size(localBot, get_top()) != n() - 1, -- "Shouldn't be possible..."); -- return true; -- } -- } -- // We fail; a completing pop_global gets the element. But the queue is -- // empty (and top is greater than bottom.) Fix this representation of -- // the empty queue to become the canonical one. -- set_age(newAge); -- assert(dirty_size(localBot, get_top()) != n() - 1, -- "Shouldn't be possible..."); -- return false; --} -- --bool OopStarTaskQueue::pop_global(StarTask& t) { -- Age newAge; -- Age oldAge = get_age(); -- juint localBot = _bottom; -- juint n_elems = size(localBot, oldAge.top()); -- if (n_elems == 0) { -- return false; -- } -- t = _elems[oldAge.top()]; -- newAge = oldAge; -- newAge._top = increment_index(newAge.top()); -- if ( newAge._top == 0 ) newAge._tag++; -- Age resAge; -- *(jint*)&resAge = Atomic::cmpxchg(*(jint*)&newAge, (volatile jint*)&_age, *(jint*)&oldAge); -- // Note that using "_bottom" here might fail, since a pop_local might -- // have decremented it. -- assert(dirty_size(localBot, newAge._top) != n() - 1, -- "Shouldn't be possible..."); -- return (resAge == oldAge); --} -- --OopStarTaskQueue::~OopStarTaskQueue() { -- FREE_C_HEAP_ARRAY(Task, _elems); --} -- --// GenTaskQueue is an exact clone of OopTaskQueue. See --// header file for questions about why GenTaskQueue exists. -- --GenTaskQueue::GenTaskQueue() : TaskQueueSuper() { -- assert(sizeof(Age) == sizeof(jint), "Depends on this."); --} -- --void GenTaskQueue::initialize() { -- _elems = NEW_C_HEAP_ARRAY(GenTask, n()); -- guarantee(_elems != NULL, "Allocation failed."); --} -- --bool GenTaskQueue::push_slow(GenTask t, juint dirty_n_elems) { -- if (dirty_n_elems == n() - 1) { -- // Actually means 0, so do the push. -- juint localBot = _bottom; -- _elems[localBot] = t; -- _bottom = increment_index(localBot); -- return true; -- } else -- return false; --} -- --bool GenTaskQueue:: --pop_local_slow(juint localBot, Age oldAge) { -- // This queue was observed to contain exactly one element; either this -- // thread will claim it, or a competing "pop_global". In either case, -- // the queue will be logically empty afterwards. Create a new Age value -- // that represents the empty queue for the given value of "_bottom". (We -- // must also increment "tag" because of the case where "bottom == 1", -- // "top == 0". A pop_global could read the queue element in that case, -- // then have the owner thread do a pop followed by another push. Without -- // the incrementing of "tag", the pop_global's CAS could succeed, -- // allowing it to believe it has claimed the stale element.) -- Age newAge; -- newAge._top = localBot; -- newAge._tag = oldAge.tag() + 1; -- // Perhaps a competing pop_global has already incremented "top", in which -- // case it wins the element. -- if (localBot == oldAge.top()) { -- Age tempAge; -- // No competing pop_global has yet incremented "top"; we'll try to -- // install new_age, thus claiming the element. -- assert(sizeof(Age) == sizeof(jint) && sizeof(jint) == sizeof(juint), -- "Assumption about CAS unit."); -- *(jint*)&tempAge = Atomic::cmpxchg(*(jint*)&newAge, (volatile jint*)&_age, *(jint*)&oldAge); -- if (tempAge == oldAge) { -- // We win. -- assert(dirty_size(localBot, get_top()) != n() - 1, -- "Shouldn't be possible..."); -- return true; -- } -- } -- // We fail; a completing pop_global gets the element. But the queue is -- // empty (and top is greater than bottom.) Fix this representation of -- // the empty queue to become the canonical one. -- set_age(newAge); -- assert(dirty_size(localBot, get_top()) != n() - 1, -- "Shouldn't be possible..."); -- return false; --} -- --bool GenTaskQueue::pop_global(GenTask& t) { -- Age newAge; -- Age oldAge = get_age(); -- juint localBot = _bottom; -- juint n_elems = size(localBot, oldAge.top()); -- if (n_elems == 0) { -- return false; -- } -- t = _elems[oldAge.top()]; -- newAge = oldAge; -- newAge._top = increment_index(newAge.top()); -- if ( newAge._top == 0 ) newAge._tag++; -- Age resAge; -- *(jint*)&resAge = Atomic::cmpxchg(*(jint*)&newAge, (volatile jint*)&_age, *(jint*)&oldAge); -- // Note that using "_bottom" here might fail, since a pop_local might -- // have decremented it. -- assert(dirty_size(localBot, newAge._top) != n() - 1, -- "Shouldn't be possible..."); -- return (resAge == oldAge); --} -- --GenTaskQueue::~GenTaskQueue() { -- FREE_C_HEAP_ARRAY(GenTask, _elems); --} --// End of GenTaskQueue clone -- --void OopTaskQueueSet::register_queue(int i, OopTaskQueue* q) { -- assert(0 <= i && i < _n, "index out of range."); -- _queues[i] = q; --} -- --OopTaskQueue* OopTaskQueueSet::queue(int i) { -- return _queues[i]; --} -- --bool OopTaskQueueSet::steal(int queue_num, int* seed, Task& t) { -- for (int i = 0; i < 2 * _n; i++) -- if (steal_best_of_2(queue_num, seed, t)) -- return true; -- return false; --} -- --bool OopTaskQueueSet::steal_best_of_all(int queue_num, int* seed, Task& t) { -- if (_n > 2) { -- int best_k; -- jint best_sz = 0; -- for (int k = 0; k < _n; k++) { -- if (k == queue_num) continue; -- jint sz = _queues[k]->size(); -- if (sz > best_sz) { -- best_sz = sz; -- best_k = k; -- } -- } -- return best_sz > 0 && _queues[best_k]->pop_global(t); -- } else if (_n == 2) { -- // Just try the other one. -- int k = (queue_num + 1) % 2; -- return _queues[k]->pop_global(t); -- } else { -- assert(_n == 1, "can't be zero."); -- return false; -- } --} -- --bool OopTaskQueueSet::steal_1_random(int queue_num, int* seed, Task& t) { -- if (_n > 2) { -- int k = queue_num; -- while (k == queue_num) k = randomParkAndMiller(seed) % _n; -- return _queues[2]->pop_global(t); -- } else if (_n == 2) { -- // Just try the other one. -- int k = (queue_num + 1) % 2; -- return _queues[k]->pop_global(t); -- } else { -- assert(_n == 1, "can't be zero."); -- return false; -- } --} -- --bool OopTaskQueueSet::steal_best_of_2(int queue_num, int* seed, Task& t) { -- if (_n > 2) { -- int k1 = queue_num; -- while (k1 == queue_num) k1 = randomParkAndMiller(seed) % _n; -- int k2 = queue_num; -- while (k2 == queue_num || k2 == k1) k2 = randomParkAndMiller(seed) % _n; -- // Sample both and try the larger. -- juint sz1 = _queues[k1]->size(); -- juint sz2 = _queues[k2]->size(); -- if (sz2 > sz1) return _queues[k2]->pop_global(t); -- else return _queues[k1]->pop_global(t); -- } else if (_n == 2) { -- // Just try the other one. -- int k = (queue_num + 1) % 2; -- return _queues[k]->pop_global(t); -- } else { -- assert(_n == 1, "can't be zero."); -- return false; -- } --} -- --bool OopTaskQueueSet::peek() { -- // Try all the queues. -- for (int j = 0; j < _n; j++) { -- if (_queues[j]->peek()) -- return true; -- } -- return false; --} -- --void OopStarTaskQueueSet::register_queue(int i, OopStarTaskQueue* q) { -- assert(0 <= i && i < _n, "index out of range."); -- _queues[i] = q; --} -- --OopStarTaskQueue* OopStarTaskQueueSet::queue(int i) { -- return _queues[i]; --} -- --bool OopStarTaskQueueSet::steal(int queue_num, int* seed, StarTask& t) { -- for (int i = 0; i < 2 * _n; i++) -- if (steal_best_of_2(queue_num, seed, t)) -- return true; -- return false; --} -- --bool OopStarTaskQueueSet::steal_best_of_all(int queue_num, int* seed, -- StarTask& t) { -- if (_n > 2) { -- int best_k; -- jint best_sz = 0; -- for (int k = 0; k < _n; k++) { -- if (k == queue_num) continue; -- jint sz = _queues[k]->size(); -- if (sz > best_sz) { -- best_sz = sz; -- best_k = k; -- } -- } -- return best_sz > 0 && _queues[best_k]->pop_global(t); -- } else if (_n == 2) { -- // Just try the other one. -- int k = (queue_num + 1) % 2; -- return _queues[k]->pop_global(t); -- } else { -- assert(_n == 1, "can't be zero."); -- return false; -- } --} -- --bool OopStarTaskQueueSet::steal_1_random(int queue_num, int* seed, -- StarTask& t) { -- if (_n > 2) { -- int k = queue_num; -- while (k == queue_num) k = randomParkAndMiller(seed) % _n; -- return _queues[2]->pop_global(t); -- } else if (_n == 2) { -- // Just try the other one. -- int k = (queue_num + 1) % 2; -- return _queues[k]->pop_global(t); -- } else { -- assert(_n == 1, "can't be zero."); -- return false; -- } --} -- --bool OopStarTaskQueueSet::steal_best_of_2(int queue_num, int* seed, -- StarTask& t) { -- if (_n > 2) { -- int k1 = queue_num; -- while (k1 == queue_num) k1 = randomParkAndMiller(seed) % _n; -- int k2 = queue_num; -- while (k2 == queue_num || k2 == k1) k2 = randomParkAndMiller(seed) % _n; -- // Sample both and try the larger. -- juint sz1 = _queues[k1]->size(); -- juint sz2 = _queues[k2]->size(); -- if (sz2 > sz1) return _queues[k2]->pop_global(t); -- else return _queues[k1]->pop_global(t); -- } else if (_n == 2) { -- // Just try the other one. -- int k = (queue_num + 1) % 2; -- return _queues[k]->pop_global(t); -- } else { -- assert(_n == 1, "can't be zero."); -- return false; -- } --} -- --bool OopStarTaskQueueSet::peek() { -- // Try all the queues. -- for (int j = 0; j < _n; j++) { -- if (_queues[j]->peek()) -- return true; -- } -- return false; --} -- --// Clone of OopTaskQueueSet for GenTask --void GenTaskQueueSet::register_queue(int i, GenTaskQueue* q) { -- assert(0 <= i && i < _n, "index out of range."); -- _queues[i] = q; --} -- --GenTaskQueue* GenTaskQueueSet::queue(int i) { -- return _queues[i]; --} -- --bool GenTaskQueueSet::steal(int queue_num, int* seed, GenTask& t) { -- for (int i = 0; i < 2 * _n; i++) -- if (steal_best_of_all(queue_num, seed, t)) -- return true; -- return false; --} -- --bool GenTaskQueueSet::steal_best_of_all(int queue_num, int* seed, GenTask& t) { -- if (_n > 2) { -- int best_k; -- jint best_sz = 0; -- for (int k = 0; k < _n; k++) { -- if (k == queue_num) continue; -- jint sz = _queues[k]->size(); -- if (sz > best_sz) { -- best_sz = sz; -- best_k = k; -- } -- } -- return best_sz > 0 && _queues[best_k]->pop_global(t); -- } else if (_n == 2) { -- // Just try the other one. -- int k = (queue_num + 1) % 2; -- return _queues[k]->pop_global(t); -- } else { -- assert(_n == 1, "can't be zero."); -- return false; -- } --} -- --bool GenTaskQueueSet::steal_1_random(int queue_num, int* seed, GenTask& t) { -- if (_n > 2) { -- int k = queue_num; -- while (k == queue_num) k = randomParkAndMiller(seed) % _n; -- return _queues[2]->pop_global(t); -- } else if (_n == 2) { -- // Just try the other one. -- int k = (queue_num + 1) % 2; -- return _queues[k]->pop_global(t); -- } else { -- assert(_n == 1, "can't be zero."); -- return false; -- } --} -- --bool GenTaskQueueSet::steal_best_of_2(int queue_num, int* seed, GenTask& t) { -- if (_n > 2) { -- int k1 = queue_num; -- while (k1 == queue_num) k1 = randomParkAndMiller(seed) % _n; -- int k2 = queue_num; -- while (k2 == queue_num || k2 == k1) k2 = randomParkAndMiller(seed) % _n; -- // Sample both and try the larger. -- juint sz1 = _queues[k1]->size(); -- juint sz2 = _queues[k2]->size(); -- if (sz2 > sz1) return _queues[k2]->pop_global(t); -- else return _queues[k1]->pop_global(t); -- } else if (_n == 2) { -- // Just try the other one. -- int k = (queue_num + 1) % 2; -- return _queues[k]->pop_global(t); -- } else { -- assert(_n == 1, "can't be zero."); -- return false; -- } --} -- --bool GenTaskQueueSet::peek() { -- // Try all the queues. -- for (int j = 0; j < _n; j++) { -- if (_queues[j]->peek()) -- return true; -- } -- return false; --} --// End clone of OopTaskQueueSet for GenTask -- - bool ChunkTaskQueueWithOverflow::is_empty() { - return (_chunk_queue.size() == 0) && - (_overflow_stack->length() == 0); -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/taskqueue.hpp openjdk/hotspot/src/share/vm/utilities/taskqueue.hpp ---- openjdk6/hotspot/src/share/vm/utilities/taskqueue.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/taskqueue.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)taskqueue.hpp 1.38 07/05/05 17:07:10 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -26,8 +23,6 @@ - */ - - class TaskQueueSuper: public CHeapObj { -- friend class ChunkTaskQueue; -- - protected: - // The first free element after the last one pushed (mod _n). - // (For now we'll assume only 32-bit CAS). -@@ -131,115 +126,129 @@ - - }; - --typedef oop Task; --class OopTaskQueue: public TaskQueueSuper { --private: -- // Slow paths for push, pop_local. (pop_global has no fast path.) -- bool push_slow(Task t, juint dirty_n_elems); -- bool pop_local_slow(juint localBot, Age oldAge); -- --public: -- // Initializes the queue to empty. -- OopTaskQueue(); -- -- void initialize(); -- -- // Push the task "t" on the queue. Returns "false" iff the queue is -- // full. -- inline bool push(Task t); -- -- // If succeeds in claiming a task (from the 'local' end, that is, the -- // most recently pushed task), returns "true" and sets "t" to that task. -- // Otherwise, the queue is empty and returns false. -- inline bool pop_local(Task& t); -- -- // If succeeds in claiming a task (from the 'global' end, that is, the -- // least recently pushed task), returns "true" and sets "t" to that task. -- // Otherwise, the queue is empty and returns false. -- bool pop_global(Task& t); -- -- // Delete any resource associated with the queue. -- ~OopTaskQueue(); -- --private: -- // Element array. -- volatile Task* _elems; -- --}; -- --typedef oop* StarTask; --class OopStarTaskQueue: public TaskQueueSuper { -+template class GenericTaskQueue: public TaskQueueSuper { - private: - // Slow paths for push, pop_local. (pop_global has no fast path.) -- bool push_slow(StarTask t, juint dirty_n_elems); -+ bool push_slow(E t, juint dirty_n_elems); - bool pop_local_slow(juint localBot, Age oldAge); - - public: - // Initializes the queue to empty. -- OopStarTaskQueue(); -+ GenericTaskQueue(); - - void initialize(); - - // Push the task "t" on the queue. Returns "false" iff the queue is - // full. -- inline bool push(StarTask t); -+ inline bool push(E t); - - // If succeeds in claiming a task (from the 'local' end, that is, the - // most recently pushed task), returns "true" and sets "t" to that task. - // Otherwise, the queue is empty and returns false. -- inline bool pop_local(StarTask& t); -+ inline bool pop_local(E& t); - - // If succeeds in claiming a task (from the 'global' end, that is, the - // least recently pushed task), returns "true" and sets "t" to that task. - // Otherwise, the queue is empty and returns false. -- bool pop_global(StarTask& t); -+ bool pop_global(E& t); - - // Delete any resource associated with the queue. -- ~OopStarTaskQueue(); -+ ~GenericTaskQueue(); - - private: - // Element array. -- volatile StarTask* _elems; -- -+ volatile E* _elems; - }; - --// Clone of OopTaskQueue with GenTask instead of Task --typedef size_t GenTask; // Generic task --class GenTaskQueue: public TaskQueueSuper { --private: -- // Slow paths for push, pop_local. (pop_global has no fast path.) -- bool push_slow(GenTask t, juint dirty_n_elems); -- bool pop_local_slow(juint localBot, Age oldAge); -- --public: -- // Initializes the queue to empty. -- GenTaskQueue(); -- -- void initialize(); -- -- // Push the task "t" on the queue. Returns "false" iff the queue is -- // full. -- inline bool push(GenTask t); -+template -+GenericTaskQueue::GenericTaskQueue():TaskQueueSuper() { -+ assert(sizeof(Age) == sizeof(jint), "Depends on this."); -+} - -- // If succeeds in claiming a task (from the 'local' end, that is, the -- // most recently pushed task), returns "true" and sets "t" to that task. -- // Otherwise, the queue is empty and returns false. -- inline bool pop_local(GenTask& t); -+template -+void GenericTaskQueue::initialize() { -+ _elems = NEW_C_HEAP_ARRAY(E, n()); -+ guarantee(_elems != NULL, "Allocation failed."); -+} - -- // If succeeds in claiming a task (from the 'global' end, that is, the -- // least recently pushed task), returns "true" and sets "t" to that task. -- // Otherwise, the queue is empty and returns false. -- bool pop_global(GenTask& t); -+template -+bool GenericTaskQueue::push_slow(E t, juint dirty_n_elems) { -+ if (dirty_n_elems == n() - 1) { -+ // Actually means 0, so do the push. -+ juint localBot = _bottom; -+ _elems[localBot] = t; -+ _bottom = increment_index(localBot); -+ return true; -+ } else -+ return false; -+} - -- // Delete any resource associated with the queue. -- ~GenTaskQueue(); -+template -+bool GenericTaskQueue:: -+pop_local_slow(juint localBot, Age oldAge) { -+ // This queue was observed to contain exactly one element; either this -+ // thread will claim it, or a competing "pop_global". In either case, -+ // the queue will be logically empty afterwards. Create a new Age value -+ // that represents the empty queue for the given value of "_bottom". (We -+ // must also increment "tag" because of the case where "bottom == 1", -+ // "top == 0". A pop_global could read the queue element in that case, -+ // then have the owner thread do a pop followed by another push. Without -+ // the incrementing of "tag", the pop_global's CAS could succeed, -+ // allowing it to believe it has claimed the stale element.) -+ Age newAge; -+ newAge._top = localBot; -+ newAge._tag = oldAge.tag() + 1; -+ // Perhaps a competing pop_global has already incremented "top", in which -+ // case it wins the element. -+ if (localBot == oldAge.top()) { -+ Age tempAge; -+ // No competing pop_global has yet incremented "top"; we'll try to -+ // install new_age, thus claiming the element. -+ assert(sizeof(Age) == sizeof(jint) && sizeof(jint) == sizeof(juint), -+ "Assumption about CAS unit."); -+ *(jint*)&tempAge = Atomic::cmpxchg(*(jint*)&newAge, (volatile jint*)&_age, *(jint*)&oldAge); -+ if (tempAge == oldAge) { -+ // We win. -+ assert(dirty_size(localBot, get_top()) != n() - 1, -+ "Shouldn't be possible..."); -+ return true; -+ } -+ } -+ // We fail; a completing pop_global gets the element. But the queue is -+ // empty (and top is greater than bottom.) Fix this representation of -+ // the empty queue to become the canonical one. -+ set_age(newAge); -+ assert(dirty_size(localBot, get_top()) != n() - 1, -+ "Shouldn't be possible..."); -+ return false; -+} - --private: -- // Element array. -- volatile GenTask* _elems; -+template -+bool GenericTaskQueue::pop_global(E& t) { -+ Age newAge; -+ Age oldAge = get_age(); -+ juint localBot = _bottom; -+ juint n_elems = size(localBot, oldAge.top()); -+ if (n_elems == 0) { -+ return false; -+ } -+ t = _elems[oldAge.top()]; -+ newAge = oldAge; -+ newAge._top = increment_index(newAge.top()); -+ if ( newAge._top == 0 ) newAge._tag++; -+ Age resAge; -+ *(jint*)&resAge = Atomic::cmpxchg(*(jint*)&newAge, (volatile jint*)&_age, *(jint*)&oldAge); -+ // Note that using "_bottom" here might fail, since a pop_local might -+ // have decremented it. -+ assert(dirty_size(localBot, newAge._top) != n() - 1, -+ "Shouldn't be possible..."); -+ return (resAge == oldAge); -+} - --}; --// End clone of OopTaskQueue with GenTask instead of Task -+template -+GenericTaskQueue::~GenericTaskQueue() { -+ FREE_C_HEAP_ARRAY(E, _elems); -+} - - // Inherits the typedef of "Task" from above. - class TaskQueueSetSuper: public CHeapObj { -@@ -250,100 +259,129 @@ - virtual bool peek() = 0; - }; - --class OopTaskQueueSet: public TaskQueueSetSuper { -+template class GenericTaskQueueSet: public TaskQueueSetSuper { - private: - int _n; -- OopTaskQueue** _queues; -+ GenericTaskQueue** _queues; - -- bool steal_1_random(int queue_num, int* seed, Task& t); -- bool steal_best_of_2(int queue_num, int* seed, Task& t); -- bool steal_best_of_all(int queue_num, int* seed, Task& t); - public: -- OopTaskQueueSet(int n) : _n(n) { -- typedef OopTaskQueue* OopTaskQueuePtr; -- _queues = NEW_C_HEAP_ARRAY(OopTaskQueuePtr, n); -+ GenericTaskQueueSet(int n) : _n(n) { -+ typedef GenericTaskQueue* GenericTaskQueuePtr; -+ _queues = NEW_C_HEAP_ARRAY(GenericTaskQueuePtr, n); - guarantee(_queues != NULL, "Allocation failure."); -- for (int i = 0; i < n; i++) _queues[i] = NULL; -+ for (int i = 0; i < n; i++) { -+ _queues[i] = NULL; - } -- -- void register_queue(int i, OopTaskQueue* q); -- -- OopTaskQueue* queue(int n); -- -- // The thread with queue number "queue_num" (and whose random number seed -- // is at "seed") is trying to steal a task from some other queue. (It -- // may try several queues, according to some configuration parameter.) -- // If some steal succeeds, returns "true" and sets "t" the stolen task, -- // otherwise returns false. -- bool steal(int queue_num, int* seed, Task& t); -- -- bool peek(); --}; -- --class OopStarTaskQueueSet: public TaskQueueSetSuper { --private: -- int _n; -- OopStarTaskQueue** _queues; -- -- bool steal_1_random(int queue_num, int* seed, StarTask& t); -- bool steal_best_of_2(int queue_num, int* seed, StarTask& t); -- bool steal_best_of_all(int queue_num, int* seed, StarTask& t); --public: -- OopStarTaskQueueSet(int n) : _n(n) { -- typedef OopStarTaskQueue* OopStarTaskQueuePtr; -- _queues = NEW_C_HEAP_ARRAY(OopStarTaskQueuePtr, n); -- guarantee(_queues != NULL, "Allocation failure."); -- for (int i = 0; i < n; i++) _queues[i] = NULL; - } - -- void register_queue(int i, OopStarTaskQueue* q); -+ bool steal_1_random(int queue_num, int* seed, E& t); -+ bool steal_best_of_2(int queue_num, int* seed, E& t); -+ bool steal_best_of_all(int queue_num, int* seed, E& t); -+ -+ void register_queue(int i, GenericTaskQueue* q); - -- OopStarTaskQueue* queue(int n); -+ GenericTaskQueue* queue(int n); - - // The thread with queue number "queue_num" (and whose random number seed - // is at "seed") is trying to steal a task from some other queue. (It - // may try several queues, according to some configuration parameter.) - // If some steal succeeds, returns "true" and sets "t" the stolen task, - // otherwise returns false. -- bool steal(int queue_num, int* seed, StarTask& t); -+ bool steal(int queue_num, int* seed, E& t); - - bool peek(); - }; - --// Clone of OopTaskQueueSet for GenTask --class GenTaskQueueSet: public TaskQueueSetSuper { -- friend class ChunkTaskQueueSet; -+template -+void GenericTaskQueueSet::register_queue(int i, GenericTaskQueue* q) { -+ assert(0 <= i && i < _n, "index out of range."); -+ _queues[i] = q; -+} - --private: -- int _n; -- GenTaskQueue** _queues; -+template -+GenericTaskQueue* GenericTaskQueueSet::queue(int i) { -+ return _queues[i]; -+} - --protected: -- bool steal_1_random(int queue_num, int* seed, GenTask& t); -- bool steal_best_of_2(int queue_num, int* seed, GenTask& t); -- bool steal_best_of_all(int queue_num, int* seed, GenTask& t); --public: -- GenTaskQueueSet(int n) : _n(n) { -- typedef GenTaskQueue* GenTaskQueuePtr; -- _queues = NEW_C_HEAP_ARRAY(GenTaskQueuePtr, n); -- guarantee(_queues != NULL, "Allocation failure."); -- for (int i = 0; i < n; i++) _queues[i] = NULL; -- } -+template -+bool GenericTaskQueueSet::steal(int queue_num, int* seed, E& t) { -+ for (int i = 0; i < 2 * _n; i++) -+ if (steal_best_of_2(queue_num, seed, t)) -+ return true; -+ return false; -+} - -- void register_queue(int i, GenTaskQueue* q); -+template -+bool GenericTaskQueueSet::steal_best_of_all(int queue_num, int* seed, E& t) { -+ if (_n > 2) { -+ int best_k; -+ jint best_sz = 0; -+ for (int k = 0; k < _n; k++) { -+ if (k == queue_num) continue; -+ jint sz = _queues[k]->size(); -+ if (sz > best_sz) { -+ best_sz = sz; -+ best_k = k; -+ } -+ } -+ return best_sz > 0 && _queues[best_k]->pop_global(t); -+ } else if (_n == 2) { -+ // Just try the other one. -+ int k = (queue_num + 1) % 2; -+ return _queues[k]->pop_global(t); -+ } else { -+ assert(_n == 1, "can't be zero."); -+ return false; -+ } -+} - -- GenTaskQueue* queue(int n); -+template -+bool GenericTaskQueueSet::steal_1_random(int queue_num, int* seed, E& t) { -+ if (_n > 2) { -+ int k = queue_num; -+ while (k == queue_num) k = randomParkAndMiller(seed) % _n; -+ return _queues[2]->pop_global(t); -+ } else if (_n == 2) { -+ // Just try the other one. -+ int k = (queue_num + 1) % 2; -+ return _queues[k]->pop_global(t); -+ } else { -+ assert(_n == 1, "can't be zero."); -+ return false; -+ } -+} - -- // The thread with queue number "queue_num" (and whose random number seed -- // is at "seed") is trying to steal a task from some other queue. (It -- // may try several queues, according to some configuration parameter.) -- // If some steal succeeds, returns "true" and sets "t" the stolen task, -- // otherwise returns false. -- bool steal(int queue_num, int* seed, GenTask& t); -+template -+bool GenericTaskQueueSet::steal_best_of_2(int queue_num, int* seed, E& t) { -+ if (_n > 2) { -+ int k1 = queue_num; -+ while (k1 == queue_num) k1 = randomParkAndMiller(seed) % _n; -+ int k2 = queue_num; -+ while (k2 == queue_num || k2 == k1) k2 = randomParkAndMiller(seed) % _n; -+ // Sample both and try the larger. -+ juint sz1 = _queues[k1]->size(); -+ juint sz2 = _queues[k2]->size(); -+ if (sz2 > sz1) return _queues[k2]->pop_global(t); -+ else return _queues[k1]->pop_global(t); -+ } else if (_n == 2) { -+ // Just try the other one. -+ int k = (queue_num + 1) % 2; -+ return _queues[k]->pop_global(t); -+ } else { -+ assert(_n == 1, "can't be zero."); -+ return false; -+ } -+} - -- bool peek(); --}; --// End clone of OopTaskQueueSet for GenTask -+template -+bool GenericTaskQueueSet::peek() { -+ // Try all the queues. -+ for (int j = 0; j < _n; j++) { -+ if (_queues[j]->peek()) -+ return true; -+ } -+ return false; -+} - - // A class to aid in the termination of a set of parallel tasks using - // TaskQueueSet's for work stealing. -@@ -353,8 +391,6 @@ - int _n_threads; - TaskQueueSetSuper* _queue_set; - jint _offered_termination; -- jint _terminated; -- Monitor _term_monitor; - - bool peek_in_queue_set(); - protected: -@@ -383,7 +419,7 @@ - - #define SIMPLE_STACK 0 - --inline bool OopTaskQueue::push(Task t) { -+template inline bool GenericTaskQueue::push(E t) { - #if SIMPLE_STACK - juint localBot = _bottom; - if (_bottom < max_elems()) { -@@ -410,7 +446,7 @@ - #endif - } - --inline bool OopTaskQueue::pop_local(Task& t) { -+template inline bool GenericTaskQueue::pop_local(E& t) { - #if SIMPLE_STACK - juint localBot = _bottom; - assert(localBot > 0, "precondition."); -@@ -450,167 +486,21 @@ - #endif - } - --inline bool OopStarTaskQueue::push(StarTask t) { --#if SIMPLE_STACK -- juint localBot = _bottom; -- if (_bottom < max_elems()) { -- _elems[localBot] = t; -- _bottom = localBot + 1; -- return true; -- } else { -- return false; -- } --#else -- juint localBot = _bottom; -- assert((localBot >= 0) && (localBot < n()), "_bottom out of range."); -- jushort top = get_top(); -- juint dirty_n_elems = dirty_size(localBot, top); -- assert((dirty_n_elems >= 0) && (dirty_n_elems < n()), -- "n_elems out of range."); -- if (dirty_n_elems < max_elems()) { -- _elems[localBot] = t; -- _bottom = increment_index(localBot); -- return true; -- } else { -- return push_slow(t, dirty_n_elems); -- } --#endif --} -- --inline bool OopStarTaskQueue::pop_local(StarTask& t) { --#if SIMPLE_STACK -- juint localBot = _bottom; -- assert(localBot > 0, "precondition."); -- localBot--; -- t = _elems[localBot]; -- _bottom = localBot; -- return true; --#else -- juint localBot = _bottom; -- // This value cannot be n-1. That can only occur as a result of -- // the assignment to bottom in this method. If it does, this method -- // resets the size( to 0 before the next call (which is sequential, -- // since this is pop_local.) -- juint dirty_n_elems = dirty_size(localBot, get_top()); -- assert(dirty_n_elems != n() - 1, "Shouldn't be possible..."); -- if (dirty_n_elems == 0) return false; -- localBot = decrement_index(localBot); -- _bottom = localBot; -- // This is necessary to prevent any read below from being reordered -- // before the store just above. -- OrderAccess::fence(); -- t = _elems[localBot]; -- // This is a second read of "age"; the "size()" above is the first. -- // If there's still at least one element in the queue, based on the -- // "_bottom" and "age" we've read, then there can be no interference with -- // a "pop_global" operation, and we're done. -- juint tp = get_top(); -- if (size(localBot, tp) > 0) { -- assert(dirty_size(localBot, tp) != n() - 1, -- "Shouldn't be possible..."); -- return true; -- } else { -- // Otherwise, the queue contained exactly one element; we take the slow -- // path. -- return pop_local_slow(localBot, get_age()); -- } --#endif --} -- --// Clone of OopTaskQueue for GenTask -- --inline bool GenTaskQueue::push(GenTask t) { --#if SIMPLE_STACK -- juint localBot = _bottom; -- if (_bottom < max_elems()) { -- _elems[localBot] = t; -- _bottom = localBot + 1; -- return true; -- } else { -- return false; -- } --#else -- juint localBot = _bottom; -- assert((localBot >= 0) && (localBot < n()), "_bottom out of range."); -- jushort top = get_top(); -- juint dirty_n_elems = dirty_size(localBot, top); -- assert((dirty_n_elems >= 0) && (dirty_n_elems < n()), -- "n_elems out of range."); -- if (dirty_n_elems < max_elems()) { -- _elems[localBot] = t; -- _bottom = increment_index(localBot); -- return true; -- } else { -- return push_slow(t, dirty_n_elems); -- } --#endif --} -+typedef oop Task; -+typedef GenericTaskQueue OopTaskQueue; -+typedef GenericTaskQueueSet OopTaskQueueSet; - --inline bool GenTaskQueue::pop_local(GenTask& t) { --#if SIMPLE_STACK -- juint localBot = _bottom; -- assert(localBot > 0, "precondition."); -- localBot--; -- t = _elems[localBot]; -- _bottom = localBot; -- return true; --#else -- juint localBot = _bottom; -- // This value cannot be n-1. That can only occur as a result of -- // the assignment to bottom in this method. If it does, this method -- // resets the size( to 0 before the next call (which is sequential, -- // since this is pop_local.) -- juint dirty_n_elems = dirty_size(localBot, get_top()); -- assert(dirty_n_elems != n() - 1, "Shouldn't be possible..."); -- if (dirty_n_elems == 0) return false; -- localBot = decrement_index(localBot); -- _bottom = localBot; -- // This is necessary to prevent any read below from being reordered -- // before the store just above. -- OrderAccess::fence(); -- t = _elems[localBot]; -- // This is a second read of "age"; the "size()" above is the first. -- // If there's still at least one element in the queue, based on the -- // "_bottom" and "age" we've read, then there can be no interference with -- // a "pop_global" operation, and we're done. -- juint tp = get_top(); -- if (size(localBot, tp) > 0) { -- assert(dirty_size(localBot, tp) != n() - 1, -- "Shouldn't be possible..."); -- return true; -- } else { -- // Otherwise, the queue contained exactly one element; we take the slow -- // path. -- return pop_local_slow(localBot, get_age()); -- } --#endif --} --// End clone of OopTaskQueue for GenTask -+typedef oop* StarTask; -+typedef GenericTaskQueue OopStarTaskQueue; -+typedef GenericTaskQueueSet OopStarTaskQueueSet; - - typedef size_t ChunkTask; // index for chunk -- --class ChunkTaskQueue: public CHeapObj { --private: -- GenTaskQueue _chunk_queue; -- -- public: -- ChunkTaskQueue() {}; -- ~ChunkTaskQueue() {}; -- -- bool push_slow(ChunkTask t, juint dirty_n_elems); -- bool pop_local_slow(juint localBot, TaskQueueSuper::Age oldAge); -- -- inline void initialize() { _chunk_queue.initialize(); } -- inline bool push(ChunkTask t) { return _chunk_queue.push((GenTask) t); } -- inline bool pop_local(ChunkTask& t) { return _chunk_queue.pop_local((GenTask&) t); } -- bool pop_global(ChunkTask& t) { return _chunk_queue.pop_global((GenTask&) t); } -- juint size() { return _chunk_queue.size(); } --}; -+typedef GenericTaskQueue ChunkTaskQueue; -+typedef GenericTaskQueueSet ChunkTaskQueueSet; - - class ChunkTaskQueueWithOverflow: public CHeapObj { -- friend class ChunkTaskQueueSet; - protected: -- GenTaskQueue _chunk_queue; -+ ChunkTaskQueue _chunk_queue; - GrowableArray* _overflow_stack; - - public: -@@ -629,50 +519,7 @@ - bool stealable_is_empty(); - bool overflow_is_empty(); - juint stealable_size() { return _chunk_queue.size(); } -+ ChunkTaskQueue* task_queue() { return &_chunk_queue; } - }; - --class ChunkTaskQueueSet: public CHeapObj { --private: -- GenTaskQueueSet _task_queue_set; -- -- bool steal_1_random(int queue_num, int* seed, GenTask& t) { -- return _task_queue_set.steal_1_random(queue_num, seed, t); -- } -- bool steal_best_of_2(int queue_num, int* seed, GenTask& t) { -- return _task_queue_set.steal_best_of_2(queue_num, seed, t); -- } -- bool steal_best_of_all(int queue_num, int* seed, GenTask& t) { -- return _task_queue_set.steal_best_of_all(queue_num, seed, t); -- } --public: -- ChunkTaskQueueSet(int n) : _task_queue_set(n) {} -- - #define USE_ChunkTaskQueueWithOverflow -- void register_queue(int i, GenTaskQueue* q) { -- _task_queue_set.register_queue(i, q); -- } -- -- void register_queue(int i, ChunkTaskQueueWithOverflow* q) { -- register_queue(i, &q->_chunk_queue); -- } -- -- ChunkTaskQueue* queue(int n) { -- return (ChunkTaskQueue*) _task_queue_set.queue(n); -- } -- -- GenTaskQueueSet* task_queue_set() { return &_task_queue_set; } -- -- // The thread with queue number "queue_num" (and whose random number seed -- // is at "seed") is trying to steal a task from some other queue. (It -- // may try several queues, according to some configuration parameter.) -- // If some steal succeeds, returns "true" and sets "t" the stolen task, -- // otherwise returns false. -- bool steal(int queue_num, int* seed, GenTask& t) { -- return _task_queue_set.steal(queue_num, seed, t); -- } -- -- bool peek() { -- return _task_queue_set.peek(); -- } --}; --// End clone of OopTaskQueueSet for GenTask -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/top.hpp openjdk/hotspot/src/share/vm/utilities/top.hpp ---- openjdk6/hotspot/src/share/vm/utilities/top.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/top.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)top.hpp 1.16 07/05/05 17:07:11 JVM" --#endif - /* - * Copyright 1997 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/utf8.cpp openjdk/hotspot/src/share/vm/utilities/utf8.cpp ---- openjdk6/hotspot/src/share/vm/utilities/utf8.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/utf8.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)utf8.cpp 1.30 07/05/05 17:07:07 JVM" --#endif - /* - * Copyright 1997-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -245,6 +242,3 @@ - } - *utf8_buffer = '\0'; - } -- -- -- -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/utf8.hpp openjdk/hotspot/src/share/vm/utilities/utf8.hpp ---- openjdk6/hotspot/src/share/vm/utilities/utf8.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/utf8.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)utf8.hpp 1.22 07/05/05 17:07:11 JVM" --#endif - /* - * Copyright 1997-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/vmError.cpp openjdk/hotspot/src/share/vm/utilities/vmError.cpp ---- openjdk6/hotspot/src/share/vm/utilities/vmError.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/vmError.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)vmError.cpp 1.31 07/05/23 10:54:29 JVM" --#endif - /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -728,7 +725,7 @@ - // open log file - int fd = -1; - -- if (strlen(ErrorFile) > 0) { -+ if (ErrorFile != NULL) { - bool copy_ok = - Arguments::copy_expand_pid(ErrorFile, strlen(ErrorFile), buffer, sizeof(buffer)); - if (copy_ok) { -@@ -802,7 +799,7 @@ - out.print_raw (cmd); - out.print_raw_cr("\" ..."); - -- fork_and_exec(cmd); -+ os::fork_and_exec(cmd); - } - - // done with OnError -@@ -865,7 +862,7 @@ - #endif - tty->print_cr("\"%s\"...", cmd); - -- _err->fork_and_exec(cmd); -+ os::fork_and_exec(cmd); - } - } - -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/vmError.hpp openjdk/hotspot/src/share/vm/utilities/vmError.hpp ---- openjdk6/hotspot/src/share/vm/utilities/vmError.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/vmError.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)vmError.hpp 1.17 07/05/05 17:07:11 JVM" --#endif - /* - * Copyright 2003-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -63,9 +60,6 @@ - // used by reporting about OOM - size_t _size; - -- // run cmd in a separate process and return its exit code; or -1 on failures -- int fork_and_exec(char* cmd); -- - // set signal handlers on Solaris/Linux or the default exception filter - // on Windows, to handle recursive crashes. - void reset_signal_handlers(); -@@ -107,4 +101,3 @@ - // signal was not changed by error reporter - static address get_resetted_sighandler(int sig); - }; -- -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/workgroup.cpp openjdk/hotspot/src/share/vm/utilities/workgroup.cpp ---- openjdk6/hotspot/src/share/vm/utilities/workgroup.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/workgroup.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)workgroup.cpp 1.36 07/05/05 17:07:11 JVM" --#endif - /* - * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/workgroup.hpp openjdk/hotspot/src/share/vm/utilities/workgroup.hpp ---- openjdk6/hotspot/src/share/vm/utilities/workgroup.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/workgroup.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)workgroup.hpp 1.22 07/05/05 17:07:11 JVM" --#endif - /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/xmlstream.cpp openjdk/hotspot/src/share/vm/utilities/xmlstream.cpp ---- openjdk6/hotspot/src/share/vm/utilities/xmlstream.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/xmlstream.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)xmlstream.cpp 1.17 07/05/05 17:07:12 JVM" --#endif - /* - * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/xmlstream.hpp openjdk/hotspot/src/share/vm/utilities/xmlstream.hpp ---- openjdk6/hotspot/src/share/vm/utilities/xmlstream.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/xmlstream.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)xmlstream.hpp 1.12 07/05/05 17:07:11 JVM" --#endif - /* - * Copyright 2002-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/yieldingWorkgroup.cpp openjdk/hotspot/src/share/vm/utilities/yieldingWorkgroup.cpp ---- openjdk6/hotspot/src/share/vm/utilities/yieldingWorkgroup.cpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/yieldingWorkgroup.cpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)yieldingWorkgroup.cpp 1.11 07/05/05 17:07:11 JVM" --#endif - /* - * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/share/vm/utilities/yieldingWorkgroup.hpp openjdk/hotspot/src/share/vm/utilities/yieldingWorkgroup.hpp ---- openjdk6/hotspot/src/share/vm/utilities/yieldingWorkgroup.hpp 2008-07-10 22:04:37.000000000 +0200 -+++ openjdk/hotspot/src/share/vm/utilities/yieldingWorkgroup.hpp 2007-12-14 08:57:03.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)yieldingWorkgroup.hpp 1.10 07/05/05 17:07:12 JVM" --#endif - /* - * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/os/linux/launcher/java_md.c openjdk/hotspot/src/os/linux/launcher/java_md.c ---- openjdk6/hotspot/src/os/linux/launcher/java_md.c 2008-07-10 22:04:27.000000000 +0200 -+++ openjdk/hotspot/src/os/linux/launcher/java_md.c 2007-12-14 08:57:02.000000000 +0100 -@@ -671,11 +671,11 @@ - - char *p; - -- snprintf(jvmpath, jvmpathsize, GetExecname()); -+ snprintf(jvmpath, jvmpathsize, "%s", GetExecname()); - p = strrchr(jvmpath, '/'); - if (p) { - /* replace executable name with libjvm.so */ -- snprintf(p + 1, jvmpathsize - (p + 1 - jvmpath), JVM_DLL); -+ snprintf(p + 1, jvmpathsize - (p + 1 - jvmpath), "%s", JVM_DLL); - } else { - /* this case shouldn't happen */ - snprintf(jvmpath, jvmpathsize, "%s", JVM_DLL); -diff -ruNb openjdk6/hotspot/src/os/linux/vm/attachListener_linux.cpp openjdk/hotspot/src/os/linux/vm/attachListener_linux.cpp ---- openjdk6/hotspot/src/os/linux/vm/attachListener_linux.cpp 2008-07-10 22:04:27.000000000 +0200 -+++ openjdk/hotspot/src/os/linux/vm/attachListener_linux.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)attachListener_linux.cpp 1.14 07/05/05 17:04:34 JVM" --#endif - /* - * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/os/linux/vm/c1_globals_linux.hpp openjdk/hotspot/src/os/linux/vm/c1_globals_linux.hpp ---- openjdk6/hotspot/src/os/linux/vm/c1_globals_linux.hpp 2008-07-10 22:04:27.000000000 +0200 -+++ openjdk/hotspot/src/os/linux/vm/c1_globals_linux.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)c1_globals_linux.hpp 1.12 07/05/05 17:04:35 JVM" --#endif - /* - * Copyright 2000-2001 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/os/linux/vm/c2_globals_linux.hpp openjdk/hotspot/src/os/linux/vm/c2_globals_linux.hpp ---- openjdk6/hotspot/src/os/linux/vm/c2_globals_linux.hpp 2008-07-10 22:04:27.000000000 +0200 -+++ openjdk/hotspot/src/os/linux/vm/c2_globals_linux.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)c2_globals_linux.hpp 1.12 07/05/05 17:04:35 JVM" --#endif - /* - * Copyright 2000-2001 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/os/linux/vm/chaitin_linux.cpp openjdk/hotspot/src/os/linux/vm/chaitin_linux.cpp ---- openjdk6/hotspot/src/os/linux/vm/chaitin_linux.cpp 2008-07-10 22:04:27.000000000 +0200 -+++ openjdk/hotspot/src/os/linux/vm/chaitin_linux.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)chaitin_linux.cpp 1.11 07/05/05 17:04:35 JVM" --#endif - /* - * Copyright 1999-2001 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/os/linux/vm/globals_linux.hpp openjdk/hotspot/src/os/linux/vm/globals_linux.hpp ---- openjdk6/hotspot/src/os/linux/vm/globals_linux.hpp 2008-07-10 22:04:27.000000000 +0200 -+++ openjdk/hotspot/src/os/linux/vm/globals_linux.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)globals_linux.hpp 1.12 07/05/05 17:04:35 JVM" --#endif - /* - * Copyright 2005-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/os/linux/vm/hpi_linux.cpp openjdk/hotspot/src/os/linux/vm/hpi_linux.cpp ---- openjdk6/hotspot/src/os/linux/vm/hpi_linux.cpp 2008-07-10 22:04:27.000000000 +0200 -+++ openjdk/hotspot/src/os/linux/vm/hpi_linux.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)hpi_linux.cpp 1.16 07/05/05 17:04:35 JVM" --#endif - /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/os/linux/vm/hpi_linux.hpp openjdk/hotspot/src/os/linux/vm/hpi_linux.hpp ---- openjdk6/hotspot/src/os/linux/vm/hpi_linux.hpp 2008-07-10 22:04:27.000000000 +0200 -+++ openjdk/hotspot/src/os/linux/vm/hpi_linux.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)hpi_linux.hpp 1.18 07/05/05 17:04:34 JVM" --#endif - /* - * Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/os/linux/vm/interfaceSupport_linux.hpp openjdk/hotspot/src/os/linux/vm/interfaceSupport_linux.hpp ---- openjdk6/hotspot/src/os/linux/vm/interfaceSupport_linux.hpp 2008-07-10 22:04:27.000000000 +0200 -+++ openjdk/hotspot/src/os/linux/vm/interfaceSupport_linux.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)interfaceSupport_linux.hpp 1.6 07/05/05 17:04:35 JVM" --#endif - /* - * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -30,4 +27,3 @@ - static inline void serialize_memory(JavaThread *thread) { - os::write_memory_serialize_page(thread); - } -- -diff -ruNb openjdk6/hotspot/src/os/linux/vm/jsig.c openjdk/hotspot/src/os/linux/vm/jsig.c ---- openjdk6/hotspot/src/os/linux/vm/jsig.c 2008-07-10 22:04:27.000000000 +0200 -+++ openjdk/hotspot/src/os/linux/vm/jsig.c 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)jsig.c 1.12 07/05/05 17:04:34 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/os/linux/vm/jvm_linux.cpp openjdk/hotspot/src/os/linux/vm/jvm_linux.cpp ---- openjdk6/hotspot/src/os/linux/vm/jvm_linux.cpp 2008-07-10 22:04:27.000000000 +0200 -+++ openjdk/hotspot/src/os/linux/vm/jvm_linux.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)jvm_linux.cpp 1.22 08/06/16 14:15:16 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -135,7 +132,7 @@ - */ - - struct siglabel { -- const char *name; -+ char *name; - int number; - }; - -diff -ruNb openjdk6/hotspot/src/os/linux/vm/jvm_linux.h openjdk/hotspot/src/os/linux/vm/jvm_linux.h ---- openjdk6/hotspot/src/os/linux/vm/jvm_linux.h 2008-07-10 22:04:27.000000000 +0200 -+++ openjdk/hotspot/src/os/linux/vm/jvm_linux.h 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)jvm_linux.h 1.15 07/05/05 17:04:35 JVM" --#endif - /* - * Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/os/linux/vm/mutex_linux.cpp openjdk/hotspot/src/os/linux/vm/mutex_linux.cpp ---- openjdk6/hotspot/src/os/linux/vm/mutex_linux.cpp 2008-07-10 22:04:27.000000000 +0200 -+++ openjdk/hotspot/src/os/linux/vm/mutex_linux.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,8 +1,5 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)mutex_linux.cpp 1.48 07/05/29 11:38:16 JVM" --#endif - /* -- * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. -+ * Copyright (c) 2007 Sun Microsystems, Inc. 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 -@@ -30,470 +27,3 @@ - - // put OS-includes here - # include -- --// Implementation of Mutex -- --// A simple Mutex for VM locking: it is not guaranteed to interoperate with --// the fast object locking, so exclusively use Mutex locking or exclusively --// use fast object locking. -- --Mutex::Mutex(int rank, const char *name, bool allow_vm_block) -- debug_only( : _rank(rank) ) --{ -- _lock_event = new os::Linux::Event; -- _suppress_signal = false; -- _owner = INVALID_THREAD; -- _name = name; -- --#ifdef ASSERT -- if (CountVMLocks) { -- _histogram = new MutexHistogramElement(name); -- _contend_histogram = new MutexContentionHistogramElement(name); -- } --#endif -- --#ifndef PRODUCT -- _lock_count = -1; // unused in solaris -- _allow_vm_block = allow_vm_block; -- debug_only(_next = NULL;) -- debug_only(_last_owner = INVALID_THREAD;) --#endif --} -- -- --Mutex::~Mutex() { -- os::Linux::Event* const _Lock_Event = (os::Linux::Event*)_lock_event; -- -- assert(_owner == INVALID_THREAD, "Owned Mutex being deleted"); -- assert(_lock_count == -1, "Mutex being deleted with non -1 lock count"); -- delete _Lock_Event; --} -- -- --void Mutex::unlock() { -- os::Linux::Event* const _Lock_Event = (os::Linux::Event*)_lock_event; -- -- assert(_owner == Thread::current(), "Mutex not being unlocked by owner"); -- -- set_owner(INVALID_THREAD); -- -- if (_suppress_signal) { -- assert(SafepointSynchronize::is_at_safepoint() && -- Thread::current()->is_VM_thread(), "can't sneak"); -- _suppress_signal = false; -- } -- else { -- assert(_lock_count >= 0, "Mutex being unlocked without positive lock count"); -- debug_only(_lock_count--;) -- _Lock_Event->unlock(); -- } --} -- -- --// Can be called by non-Java threads (JVM_RawMonitorExit) --void Mutex::jvm_raw_unlock() { -- os::Linux::Event* const _Lock_Event = (os::Linux::Event*)_lock_event; -- // Do not call set_owner, as this would break. -- _owner = INVALID_THREAD; -- if (_suppress_signal) { -- assert(SafepointSynchronize::is_at_safepoint() && -- Thread::current()->is_VM_thread(), "can't sneak"); -- _suppress_signal = false; -- } -- else { -- debug_only(_lock_count--;) -- _Lock_Event->unlock(); -- } --} -- -- --void Mutex::wait_for_lock_blocking_implementation(JavaThread *thread) { -- ThreadBlockInVM tbivm(thread); -- -- wait_for_lock_implementation(); --} -- -- --#ifndef PRODUCT --void Mutex::print_on(outputStream* st) const { -- os::Linux::Event* const _Lock_Event = (os::Linux::Event*)_lock_event; -- -- st->print_cr("Mutex: [0x%x/0x%x] %s - owner: 0x%x", this, _Lock_Event, _name, _owner); --} --#endif -- -- --// --// Monitor --// -- -- --Monitor::Monitor(int rank, const char *name, bool allow_vm_block) : Mutex(rank, name, allow_vm_block) { -- _event = NULL; -- _counter = 0; -- _tickets = 0; -- _waiters = 0; --} -- -- --Monitor::~Monitor() { --} -- -- --bool Monitor::wait(bool no_safepoint_check, long timeout, -- bool as_suspend_equivalent) { -- os::Linux::Event* const _Lock_Event = (os::Linux::Event*)_lock_event; -- Thread* thread = Thread::current(); -- -- assert(_owner != INVALID_THREAD, "Wait on unknown thread"); -- assert(_owner == thread, "Wait on Monitor not by owner"); -- -- // The design rule for use of mutexes of rank special or less is -- // that we are guaranteed not to block while holding such mutexes. -- // Here we verify that the least ranked mutex that we hold, -- // modulo the mutex we are about to relinquish, satisfies that -- // constraint, since we are about to block in a wait. -- #ifdef ASSERT -- Mutex* least = get_least_ranked_lock_besides_this(thread->owned_locks()); -- assert(least != this, "Specification of get_least_... call above"); -- if (least != NULL && least->rank() <= special) { -- tty->print("Attempting to wait on monitor %s/%d while holding" -- " lock %s/%d -- possible deadlock", -- name(), rank(), least->name(), least->rank()); -- assert(false, -- "Shouldn't block(wait) while holding a lock of rank special"); -- } -- #endif // ASSERT -- -- long c = _counter; -- -- #ifdef ASSERT -- // Don't catch signals while blocked; let the running threads have the signals. -- // (This allows a debugger to break into the running thread.) -- sigset_t oldsigs; -- sigset_t* allowdebug_blocked = os::Linux::allowdebug_blocked_signals(); -- pthread_sigmask(SIG_BLOCK, allowdebug_blocked, &oldsigs); -- #endif -- -- _waiters++; -- // Loop until condition variable is signaled. Tickets will -- // reflect the number of threads which have been notified. The counter -- // field is used to make sure we don't respond to notifications that -- // have occurred *before* we started waiting, and is incremented each -- // time the condition variable is signaled. -- // Use a ticket scheme to guard against spurious wakeups. -- int wait_status; -- -- while (true) { -- -- if (no_safepoint_check) { -- -- // conceptually set the owner to INVALID_THREAD in anticipation of yielding the lock in wait -- set_owner(Mutex::INVALID_THREAD); -- -- // (SafepointTimeout is not implemented) -- if(timeout == 0) { -- wait_status = _Lock_Event->wait(); -- } -- else { -- wait_status = _Lock_Event->timedwait(timeout); -- } -- } else { -- JavaThread *jt = (JavaThread *)thread; -- -- // conceptually set the owner to INVALID_THREAD in anticipation of yielding the lock in wait -- set_owner(Mutex::INVALID_THREAD); -- -- // Enter safepoint region -- ThreadBlockInVM tbivm(jt); -- OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */); -- -- if (as_suspend_equivalent) { -- jt->set_suspend_equivalent(); -- // cleared by handle_special_suspend_equivalent_condition() or -- // java_suspend_self() -- } -- -- if(timeout == 0) { -- wait_status = _Lock_Event->wait(); -- } -- else { -- wait_status = _Lock_Event->timedwait(timeout); -- } -- -- // were we externally suspended while we were waiting? -- if (as_suspend_equivalent && -- jt->handle_special_suspend_equivalent_condition()) { -- // -- // Our event wait has finished and we own the _Lock_Event, but -- // while we were waiting another thread suspended us. We don't -- // want to hold the _Lock_Event while suspended because that -- // would surprise the thread that suspended us. -- // -- _Lock_Event->unlock(); -- jt->java_suspend_self(); -- _Lock_Event->lock(); -- } -- } // if no_safepoint_check -- -- // conceptually reaquire the lock (the actual Linux lock is already reacquired after waiting) -- set_owner(thread); -- -- // We get to this point if either: -- // a) a notify has been executed by some other thread and woke us up -- // b) a signal has been delivered to this thread and terminated wait -- // c) the above two events happened while we were waiting - that is a signal -- // was delivered while notify was executed by some other thread. -- -- // Handle cases a) and c) here. We consume one ticket even in case c) when notify -- // and a signal arrive together -- if (_tickets != 0 && _counter != c) { -- break; -- } -- -- // If wait was interrupted by a signal or timeout, do not use up a ticket -- if (wait_status == EINTR || wait_status == ETIME || wait_status == ETIMEDOUT) { -- ++_tickets; // will be decremented again below -- break; -- } -- -- -- } -- _waiters--; -- _tickets--; -- --#ifdef ASSERT -- pthread_sigmask(SIG_SETMASK, &oldsigs, NULL); --#endif -- -- // return true if timed out -- return (wait_status == ETIME || wait_status == ETIMEDOUT); --} -- -- --// Notify a single thread waiting on this condition variable --bool Monitor::notify() { -- os::Linux::Event* const _Lock_Event = (os::Linux::Event*)_lock_event; -- -- assert(_owner != INVALID_THREAD, "notify on unknown thread"); -- assert(_owner == Thread::current(), "notify on Monitor not by owner"); -- -- if (_waiters > _tickets) { -- -- _Lock_Event->signal(); -- -- _tickets++; -- _counter++; -- } -- -- return true; -- --} -- -- --// Notify all threads waiting on this ConditionVariable --bool Monitor::notify_all() { -- os::Linux::Event* const _Lock_Event = (os::Linux::Event*)_lock_event; -- -- assert(_owner != INVALID_THREAD, "notify on unknown thread"); -- assert(_owner == Thread::current(), "notify on Monitor not by owner"); -- -- if (_waiters > 0) { -- -- _Lock_Event->broadcast(); -- -- _tickets = _waiters; -- _counter++; -- } -- -- return true; --} -- --// JSR166 --// ------------------------------------------------------- -- --/* -- * The solaris and linux implementations of park/unpark are fairly -- * conservative for now, but can be improved. They currently use a -- * mutex/condvar pair, plus a a count. -- * Park decrements count if > 0, else does a condvar wait. Unpark -- * sets count to 1 and signals condvar. Only one thread ever waits -- * on the condvar. Contention seen when trying to park implies that someone -- * is unparking you, so don't wait. And spurious returns are fine, so there -- * is no need to track notifications. -- */ -- --#define NANOSECS_PER_SEC 1000000000 --#define NANOSECS_PER_MILLISEC 1000000 --#define MAX_SECS 100000000 --/* -- * This code is common to linux and solaris and will be moved to a -- * common place in dolphin. -- * -- * The passed in time value is either a relative time in nanoseconds -- * or an absolute time in milliseconds. Either way it has to be unpacked -- * into suitable seconds and nanoseconds components and stored in the -- * given timespec structure. -- * Given time is a 64-bit value and the time_t used in the timespec is only -- * a signed-32-bit value (except on 64-bit Linux) we have to watch for -- * overflow if times way in the future are given. Further on Solaris versions -- * prior to 10 there is a restriction (see cond_timedwait) that the specified -- * number of seconds, in abstime, is less than current_time + 100,000,000. -- * As it will be 28 years before "now + 100000000" will overflow we can -- * ignore overflow and just impose a hard-limit on seconds using the value -- * of "now + 100,000,000". This places a limit on the timeout of about 3.17 -- * years from "now". -- */ --static void unpackTime(timespec* absTime, bool isAbsolute, jlong time) { -- assert (time > 0, "convertTime"); -- -- struct timeval now; -- int status = gettimeofday(&now, NULL); -- assert(status == 0, "gettimeofday"); -- -- time_t max_secs = now.tv_sec + MAX_SECS; -- -- if (isAbsolute) { -- jlong secs = time / 1000; -- if (secs > max_secs) { -- absTime->tv_sec = max_secs; -- } -- else { -- absTime->tv_sec = secs; -- } -- absTime->tv_nsec = (time % 1000) * NANOSECS_PER_MILLISEC; -- } -- else { -- jlong secs = time / NANOSECS_PER_SEC; -- if (secs >= MAX_SECS) { -- absTime->tv_sec = max_secs; -- absTime->tv_nsec = 0; -- } -- else { -- absTime->tv_sec = now.tv_sec + secs; -- absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_usec*1000; -- if (absTime->tv_nsec >= NANOSECS_PER_SEC) { -- absTime->tv_nsec -= NANOSECS_PER_SEC; -- ++absTime->tv_sec; // note: this must be <= max_secs -- } -- } -- } -- assert(absTime->tv_sec >= 0, "tv_sec < 0"); -- assert(absTime->tv_sec <= max_secs, "tv_sec > max_secs"); -- assert(absTime->tv_nsec >= 0, "tv_nsec < 0"); -- assert(absTime->tv_nsec < NANOSECS_PER_SEC, "tv_nsec >= nanos_per_sec"); --} -- --void Parker::park(bool isAbsolute, jlong time) { -- // Optional fast-path check: -- // Return immediately if a permit is available. -- if (_counter > 0) { -- _counter = 0 ; -- return ; -- } -- -- Thread* thread = Thread::current(); -- assert(thread->is_Java_thread(), "Must be JavaThread"); -- JavaThread *jt = (JavaThread *)thread; -- -- // Optional optimization -- avoid state transitions if there's an interrupt pending. -- // Check interrupt before trying to wait -- if (Thread::is_interrupted(thread, false)) { -- return; -- } -- -- // Next, demultiplex/decode time arguments -- timespec absTime; -- if (time < 0) { // don't wait at all -- return; -- } -- if (time > 0) { -- unpackTime(&absTime, isAbsolute, time); -- } -- -- -- // Enter safepoint region -- // Beware of deadlocks such as 6317397. -- // The per-thread Parker:: mutex is a classic leaf-lock. -- // In particular a thread must never block on the Threads_lock while -- // holding the Parker:: mutex. If safepoints are pending both the -- // the ThreadBlockInVM() CTOR and DTOR may grab Threads_lock. -- ThreadBlockInVM tbivm(jt); -- -- // Don't wait if cannot get lock since interference arises from -- // unblocking. Also. check interrupt before trying wait -- if (Thread::is_interrupted(thread, false) || pthread_mutex_trylock(_mutex) != 0) { -- return; -- } -- -- int status ; -- if (_counter > 0) { // no wait needed -- _counter = 0; -- status = pthread_mutex_unlock(_mutex); -- assert (status == 0, "invariant") ; -- return; -- } -- --#ifdef ASSERT -- // Don't catch signals while blocked; let the running threads have the signals. -- // (This allows a debugger to break into the running thread.) -- sigset_t oldsigs; -- sigset_t* allowdebug_blocked = os::Linux::allowdebug_blocked_signals(); -- pthread_sigmask(SIG_BLOCK, allowdebug_blocked, &oldsigs); --#endif -- -- OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */); -- jt->set_suspend_equivalent(); -- // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self() -- -- if (time == 0) { -- status = pthread_cond_wait (_cond, _mutex) ; -- } else { -- status = os::Linux::safe_cond_timedwait (_cond, _mutex, &absTime) ; -- if (status != 0 && WorkAroundNPTLTimedWaitHang) { -- pthread_cond_destroy (_cond) ; -- pthread_cond_init (_cond, NULL); -- } -- } -- assert_status(status == 0 || status == EINTR || -- status == ETIME || status == ETIMEDOUT, -- status, "cond_timedwait"); -- --#ifdef ASSERT -- pthread_sigmask(SIG_SETMASK, &oldsigs, NULL); --#endif -- -- _counter = 0 ; -- status = pthread_mutex_unlock(_mutex) ; -- assert_status(status == 0, status, "invariant") ; -- // If externally suspended while waiting, re-suspend -- if (jt->handle_special_suspend_equivalent_condition()) { -- jt->java_suspend_self(); -- } -- --} -- --void Parker::unpark() { -- int s, status ; -- status = pthread_mutex_lock(_mutex); -- assert (status == 0, "invariant") ; -- s = _counter; -- _counter = 1; -- if (s < 1) { -- if (WorkAroundNPTLTimedWaitHang) { -- status = pthread_cond_signal (_cond) ; -- assert (status == 0, "invariant") ; -- status = pthread_mutex_unlock(_mutex); -- assert (status == 0, "invariant") ; -- } else { -- status = pthread_mutex_unlock(_mutex); -- assert (status == 0, "invariant") ; -- status = pthread_cond_signal (_cond) ; -- assert (status == 0, "invariant") ; -- } -- } else { -- pthread_mutex_unlock(_mutex); -- assert (status == 0, "invariant") ; -- } --} -- -diff -ruNb openjdk6/hotspot/src/os/linux/vm/mutex_linux.inline.hpp openjdk/hotspot/src/os/linux/vm/mutex_linux.inline.hpp ---- openjdk6/hotspot/src/os/linux/vm/mutex_linux.inline.hpp 2008-07-10 22:04:27.000000000 +0200 -+++ openjdk/hotspot/src/os/linux/vm/mutex_linux.inline.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)mutex_linux.inline.hpp 1.12 07/05/05 17:04:36 JVM" --#endif - /* - * Copyright 1999-2002 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -25,26 +22,6 @@ - * - */ - --inline bool Mutex::lock_implementation() { -- int status = ((os::Linux::Event*)_lock_event)->trylock(); -- if (status != 0) { -- debug_only(_lock_count++); -- return true; -- } -- return false; --} -- --inline bool Mutex::try_lock_implementation() { -- // Same on Linux. -- return lock_implementation(); --} -- -- --inline void Mutex::wait_for_lock_implementation() { -- assert(!owned_by_self(), "deadlock"); -- ((os::Linux::Event*)_lock_event)->lock(); -- debug_only(_lock_count++;) --} - - // Reconciliation History - // mutex_solaris.inline.hpp 1.5 99/06/22 16:38:49 -diff -ruNb openjdk6/hotspot/src/os/linux/vm/objectMonitor_linux.cpp openjdk/hotspot/src/os/linux/vm/objectMonitor_linux.cpp ---- openjdk6/hotspot/src/os/linux/vm/objectMonitor_linux.cpp 2008-07-10 22:04:27.000000000 +0200 -+++ openjdk/hotspot/src/os/linux/vm/objectMonitor_linux.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)objectMonitor_linux.cpp 1.69 07/05/05 17:04:36 JVM" --#endif - - /* - * Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved. -@@ -25,4 +22,3 @@ - * have any questions. - * - */ -- -diff -ruNb openjdk6/hotspot/src/os/linux/vm/objectMonitor_linux.hpp openjdk/hotspot/src/os/linux/vm/objectMonitor_linux.hpp ---- openjdk6/hotspot/src/os/linux/vm/objectMonitor_linux.hpp 2008-07-10 22:04:27.000000000 +0200 -+++ openjdk/hotspot/src/os/linux/vm/objectMonitor_linux.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)objectMonitor_linux.hpp 1.18 07/05/05 17:04:36 JVM" --#endif - /* - * Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -26,4 +23,3 @@ - */ - - private: -- -diff -ruNb openjdk6/hotspot/src/os/linux/vm/objectMonitor_linux.inline.hpp openjdk/hotspot/src/os/linux/vm/objectMonitor_linux.inline.hpp ---- openjdk6/hotspot/src/os/linux/vm/objectMonitor_linux.inline.hpp 2008-07-10 22:04:27.000000000 +0200 -+++ openjdk/hotspot/src/os/linux/vm/objectMonitor_linux.inline.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)objectMonitor_linux.inline.hpp 1.14 07/05/05 17:04:36 JVM" --#endif - /* - * Copyright 1999-2005 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -24,4 +21,3 @@ - * have any questions. - * - */ -- -diff -ruNb openjdk6/hotspot/src/os/linux/vm/osThread_linux.cpp openjdk/hotspot/src/os/linux/vm/osThread_linux.cpp ---- openjdk6/hotspot/src/os/linux/vm/osThread_linux.cpp 2008-07-10 22:04:27.000000000 +0200 -+++ openjdk/hotspot/src/os/linux/vm/osThread_linux.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)osThread_linux.cpp 1.24 07/05/05 17:04:36 JVM" --#endif - /* - * Copyright 1999-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -29,17 +26,6 @@ - # include "incls/_osThread_linux.cpp.incl" - - --// Events associated with threads via "interrupt_event" must --// reside in a TSM (type-stable memory) pool. --// The relationship between the interrupt_event and a thread --// must be stable for the lifetime of the thread. --// --// A slightly better implementation would be to subclass Event --// with a "TSMEvent" that added the FreeNext field. -- --static os::Linux::Event * EventFreeList = NULL ; --static pthread_mutex_t EventFreeLock = PTHREAD_MUTEX_INITIALIZER ; -- - void OSThread::pd_initialize() { - assert(this != NULL, "check"); - _thread_id = 0; -@@ -51,37 +37,10 @@ - - sigemptyset(&_caller_sigmask); - -- // Try to allocate an Event from the TSM list, otherwise -- // instantiate a new Event. -- pthread_mutex_lock (&EventFreeLock) ; -- os::Linux::Event * ie = EventFreeList ; -- if (ie != NULL) { -- guarantee (ie->Immortal, "invariant") ; -- EventFreeList = ie->FreeNext ; -- } -- pthread_mutex_unlock (&EventFreeLock) ; -- if (ie == NULL) { -- ie = new os::Linux::Event(); -- } else { -- ie->reset () ; -- } -- ie->FreeNext = (os::Linux::Event *) 0xBAD ; -- ie->Immortal = 1 ; -- _interrupt_event = ie ; -- - _startThread_lock = new Monitor(Mutex::event, "startThread_lock", true); - assert(_startThread_lock !=NULL, "check"); - } - - void OSThread::pd_destroy() { -- os::Linux::Event * ie = _interrupt_event ; -- _interrupt_event = NULL ; -- guarantee (ie != NULL, "invariant") ; -- guarantee (ie->Immortal, "invariant") ; -- pthread_mutex_lock (&EventFreeLock) ; -- ie->FreeNext = EventFreeList ; -- EventFreeList = ie ; -- pthread_mutex_unlock (&EventFreeLock) ; -- - delete _startThread_lock; - } -diff -ruNb openjdk6/hotspot/src/os/linux/vm/osThread_linux.hpp openjdk/hotspot/src/os/linux/vm/osThread_linux.hpp ---- openjdk6/hotspot/src/os/linux/vm/osThread_linux.hpp 2008-07-10 22:04:27.000000000 +0200 -+++ openjdk/hotspot/src/os/linux/vm/osThread_linux.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)osThread_linux.hpp 1.37 07/05/05 17:04:36 JVM" --#endif - /* - * Copyright 1999-2004 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -121,25 +118,11 @@ - void set_alt_sig_stack(address val) { _alt_sig_stack = val; } - address alt_sig_stack(void) { return _alt_sig_stack; } - -- // *************************************************************** -- // The interrupt_event is used to implement java.lang.Thread.interrupt, -- // which on Linux can interrupt sleep and ObjectMonitor::wait(). -- // *************************************************************** -- - private: -- -- os::Linux::Event* _interrupt_event; - Monitor* _startThread_lock; // sync parent and child in thread creation - - public: - -- os::Linux::Event* interrupt_event() const { -- return _interrupt_event; -- } -- void set_interrupt_event(os::Linux::Event* ptr) { -- _interrupt_event = ptr; -- } -- - Monitor* startThread_lock() const { - return _startThread_lock; - } -diff -ruNb openjdk6/hotspot/src/os/linux/vm/os_linux.cpp openjdk/hotspot/src/os/linux/vm/os_linux.cpp ---- openjdk6/hotspot/src/os/linux/vm/os_linux.cpp 2008-07-10 22:04:27.000000000 +0200 -+++ openjdk/hotspot/src/os/linux/vm/os_linux.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)os_linux.cpp 1.258 08/06/16 14:16:05 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -78,8 +75,8 @@ - bool os::Linux::_is_floating_stack = false; - bool os::Linux::_is_NPTL = false; - bool os::Linux::_supports_fast_thread_cpu_time = false; --const char * os::Linux::_glibc_version = NULL; --const char * os::Linux::_libpthread_version = NULL; -+char * os::Linux::_glibc_version = NULL; -+char * os::Linux::_libpthread_version = NULL; - - static jlong initial_time_count=0; - -@@ -202,7 +199,7 @@ - // the system call returns 1. This causes the VM to act as if it is - // a single processor and elide locking (see is_MP() call). - static bool unsafe_chroot_detected = false; --static const char *unstable_chroot_error = "/proc file system not found.\n" -+static char *unstable_chroot_error = "/proc file system not found.\n" - "Java may be unstable running multithreaded in a chroot " - "environment on Linux when /proc filesystem is not mounted."; - -@@ -536,18 +533,20 @@ - - // Vanilla RH-9 (glibc 2.3.2) has a bug that confstr() always tells - // us "NPTL-0.29" even we are running with LinuxThreads. Check if this -- // is the case. Also, LinuxThreads has a hard limit on max number of -- // threads. So sysconf(_SC_THREAD_THREADS_MAX) will return a positive -- // value.On the other hand, NPTL does not have such a limit, sysconf() -- // will return -1 and errno is not changed. Check if it is really NPTL. -+ // is the case: - if (strcmp(os::Linux::glibc_version(), "glibc 2.3.2") == 0 && -- strstr(str, "NPTL") && -- sysconf(_SC_THREAD_THREADS_MAX) > 0) { -+ strstr(str, "NPTL")) { -+ // LinuxThreads has a hard limit on max number of threads. So -+ // sysconf(_SC_THREAD_THREADS_MAX) will return a positive value. -+ // On the other hand, NPTL does not have such a limit, sysconf() -+ // will return -1 and errno is not changed. Check if it is really -+ // NPTL: -+ if (sysconf(_SC_THREAD_THREADS_MAX) > 0) { - free(str); -- os::Linux::set_libpthread_version("linuxthreads"); -- } else { -- os::Linux::set_libpthread_version(str); -+ str = "linuxthreads"; -+ } - } -+ os::Linux::set_libpthread_version(str); - } else { - // glibc before 2.3.2 only has LinuxThreads. - os::Linux::set_libpthread_version("linuxthreads"); -@@ -2292,7 +2291,8 @@ - return ::munmap(addr, size) == 0; - } - --char* os::reserve_memory(size_t bytes, char* requested_addr) { -+char* os::reserve_memory(size_t bytes, char* requested_addr, -+ size_t alignment_hint) { - return anon_mmap(requested_addr, bytes, (requested_addr != NULL)); - } - -@@ -2378,6 +2378,13 @@ - } - } - -+ const size_t default_page_size = (size_t)Linux::page_size(); -+ if (_large_page_size > default_page_size) { -+ _page_sizes[0] = _large_page_size; -+ _page_sizes[1] = default_page_size; -+ _page_sizes[2] = 0; -+ } -+ - // Large page support is available on 2.6 or newer kernel, some vendors - // (e.g. Redhat) have backported it to their 2.4 based distributions. - // We optimistically assume the support is available. If later it turns out -@@ -2567,12 +2574,11 @@ - int os::sleep(Thread* thread, jlong millis, bool interruptible) { - assert(thread == Thread::current(), "thread consistency check"); - -- if (interruptible) { -- OSThread* osthread = thread->osthread(); -- Linux::Event* event = (Linux::Event*) osthread->interrupt_event(); -- event->reset() ; -+ ParkEvent * const slp = thread->_SleepEvent ; -+ slp->reset() ; - OrderAccess::fence() ; - -+ if (interruptible) { - jlong prevtime = javaTimeNanos(); - - for (;;) { -@@ -2606,7 +2612,7 @@ - // cleared by handle_special_suspend_equivalent_condition() or - // java_suspend_self() via check_and_wait_while_suspended() - -- event->park(millis); -+ slp->park(millis); - - // were we externally suspended while we were waiting? - jt->check_and_wait_while_suspended(); -@@ -2614,11 +2620,27 @@ - } - } else { - OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */); -- Linux::Event event; -- event.lock(); -- int rslt = event.timedwait(millis); -- event.unlock(); -- return rslt; -+ jlong prevtime = javaTimeNanos(); -+ -+ for (;;) { -+ // It'd be nice to avoid the back-to-back javaTimeNanos() calls on -+ // the 1st iteration ... -+ jlong newtime = javaTimeNanos(); -+ -+ if (newtime - prevtime < 0) { -+ // time moving backwards, should only happen if no monotonic clock -+ // not a guarantee() because JVM should not abort on kernel/glibc bugs -+ assert(!Linux::supports_monotonic_clock(), "time moving backwards"); -+ } else { -+ millis -= (newtime - prevtime) / NANOSECS_PER_MILLISECS; -+ } -+ -+ if(millis <= 0) break ; -+ -+ prevtime = newtime; -+ slp->park(millis); -+ } -+ return OS_OK ; - } - } - -@@ -2643,7 +2665,7 @@ - sched_yield(); - } - --void os::NakedYield() { sched_yield(); } -+os::YieldResult os::NakedYield() { sched_yield(); return os::YIELD_UNKNOWN ;} - - void os::yield_all(int attempts) { - // Yields to all threads, including threads with lower priorities -@@ -2914,13 +2936,13 @@ - OSThread* osthread = thread->osthread(); - - if (!osthread->interrupted()) { -- Linux::Event* event = (Linux::Event*) osthread->interrupt_event(); - osthread->set_interrupted(true); - // More than one thread can get here with the same value of osthread, - // resulting in multiple notifications. We do, however, want the store - // to interrupted() to be visible to other threads before we execute unpark(). - OrderAccess::fence(); -- event->unpark(); -+ ParkEvent * const slp = thread->_SleepEvent ; -+ if (slp != NULL) slp->unpark() ; - } - - // For JSR166. Unpark even if interrupt status already was set -@@ -2941,9 +2963,8 @@ - bool interrupted = osthread->interrupted(); - - if (interrupted && clear_interrupted) { -- Linux::Event* event = (Linux::Event*) osthread->interrupt_event(); - osthread->set_interrupted(false); -- event->reset(); -+ // consider thread->_SleepEvent->reset() ... optional optimization - } - - return interrupted; -@@ -3437,10 +3458,10 @@ - ThreadCritical::initialize(); - - Linux::set_page_size(sysconf(_SC_PAGESIZE)); -- - if (Linux::page_size() == -1) { - fatal1("os_linux.cpp: os::init: sysconf failed (%s)", strerror(errno)); - } -+ init_page_sizes((size_t) Linux::page_size()); - - Linux::initialize_system_info(); - -@@ -4029,26 +4050,6 @@ - } - } - --#ifndef PRODUCT --void os::Linux::Event::verify() { -- guarantee(!Universe::is_fully_initialized() || -- !Universe::heap()->is_in_reserved((oop)this), -- "Mutex must be in C heap only."); --} -- --void os::Linux::OSMutex::verify() { -- guarantee(!Universe::is_fully_initialized() || -- !Universe::heap()->is_in_reserved((oop)this), -- "OSMutex must be in C heap only."); --} -- --void os::Linux::OSMutex::verify_locked() { -- pthread_t my_id = pthread_self(); -- assert(_is_owned, "OSMutex should be locked"); -- assert(pthread_equal(_owner, my_id), "OSMutex should be locked by me"); --} --#endif -- - extern "C" { - - /** -@@ -4146,6 +4147,42 @@ - // It may be possible to refine (4) by checking the kernel and NTPL verisons - // and only enabling the work-around for vulnerable environments. - -+// utility to compute the abstime argument to timedwait: -+// millis is the relative timeout time -+// abstime will be the absolute timeout time -+// TODO: replace compute_abstime() with unpackTime() -+ -+static struct timespec* compute_abstime(timespec* abstime, jlong millis) { -+ if (millis < 0) millis = 0; -+ struct timeval now; -+ int status = gettimeofday(&now, NULL); -+ assert(status == 0, "gettimeofday"); -+ jlong seconds = millis / 1000; -+ millis %= 1000; -+ if (seconds > 50000000) { // see man cond_timedwait(3T) -+ seconds = 50000000; -+ } -+ abstime->tv_sec = now.tv_sec + seconds; -+ long usec = now.tv_usec + millis * 1000; -+ if (usec >= 1000000) { -+ abstime->tv_sec += 1; -+ usec -= 1000000; -+ } -+ abstime->tv_nsec = usec * 1000; -+ return abstime; -+} -+ -+ -+// Test-and-clear _Event, always leaves _Event set to 0, returns immediately. -+// Conceptually TryPark() should be equivalent to park(0). -+ -+int os::PlatformEvent::TryPark() { -+ for (;;) { -+ const int v = _Event ; -+ guarantee ((v == 0) || (v == 1), "invariant") ; -+ if (Atomic::cmpxchg (0, &_Event, v) == v) return v ; -+ } -+} - - void os::PlatformEvent::park() { // AKA "down()" - // Invariant: Only the thread associated with the Event/PlatformEvent -@@ -4195,7 +4232,7 @@ - // We do this the hard way, by blocking the thread. - // Consider enforcing a minimum timeout value. - struct timespec abst; -- os::Linux::Event::compute_abstime(&abst, millis); -+ compute_abstime(&abst, millis); - - int ret = OS_TIMEOUT; - int status = pthread_mutex_lock(_mutex); -@@ -4282,3 +4319,276 @@ - // simply re-test the condition and re-park itself. - } - -+ -+// JSR166 -+// ------------------------------------------------------- -+ -+/* -+ * The solaris and linux implementations of park/unpark are fairly -+ * conservative for now, but can be improved. They currently use a -+ * mutex/condvar pair, plus a a count. -+ * Park decrements count if > 0, else does a condvar wait. Unpark -+ * sets count to 1 and signals condvar. Only one thread ever waits -+ * on the condvar. Contention seen when trying to park implies that someone -+ * is unparking you, so don't wait. And spurious returns are fine, so there -+ * is no need to track notifications. -+ */ -+ -+ -+#define NANOSECS_PER_SEC 1000000000 -+#define NANOSECS_PER_MILLISEC 1000000 -+#define MAX_SECS 100000000 -+/* -+ * This code is common to linux and solaris and will be moved to a -+ * common place in dolphin. -+ * -+ * The passed in time value is either a relative time in nanoseconds -+ * or an absolute time in milliseconds. Either way it has to be unpacked -+ * into suitable seconds and nanoseconds components and stored in the -+ * given timespec structure. -+ * Given time is a 64-bit value and the time_t used in the timespec is only -+ * a signed-32-bit value (except on 64-bit Linux) we have to watch for -+ * overflow if times way in the future are given. Further on Solaris versions -+ * prior to 10 there is a restriction (see cond_timedwait) that the specified -+ * number of seconds, in abstime, is less than current_time + 100,000,000. -+ * As it will be 28 years before "now + 100000000" will overflow we can -+ * ignore overflow and just impose a hard-limit on seconds using the value -+ * of "now + 100,000,000". This places a limit on the timeout of about 3.17 -+ * years from "now". -+ */ -+ -+static void unpackTime(timespec* absTime, bool isAbsolute, jlong time) { -+ assert (time > 0, "convertTime"); -+ -+ struct timeval now; -+ int status = gettimeofday(&now, NULL); -+ assert(status == 0, "gettimeofday"); -+ -+ time_t max_secs = now.tv_sec + MAX_SECS; -+ -+ if (isAbsolute) { -+ jlong secs = time / 1000; -+ if (secs > max_secs) { -+ absTime->tv_sec = max_secs; -+ } -+ else { -+ absTime->tv_sec = secs; -+ } -+ absTime->tv_nsec = (time % 1000) * NANOSECS_PER_MILLISEC; -+ } -+ else { -+ jlong secs = time / NANOSECS_PER_SEC; -+ if (secs >= MAX_SECS) { -+ absTime->tv_sec = max_secs; -+ absTime->tv_nsec = 0; -+ } -+ else { -+ absTime->tv_sec = now.tv_sec + secs; -+ absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_usec*1000; -+ if (absTime->tv_nsec >= NANOSECS_PER_SEC) { -+ absTime->tv_nsec -= NANOSECS_PER_SEC; -+ ++absTime->tv_sec; // note: this must be <= max_secs -+ } -+ } -+ } -+ assert(absTime->tv_sec >= 0, "tv_sec < 0"); -+ assert(absTime->tv_sec <= max_secs, "tv_sec > max_secs"); -+ assert(absTime->tv_nsec >= 0, "tv_nsec < 0"); -+ assert(absTime->tv_nsec < NANOSECS_PER_SEC, "tv_nsec >= nanos_per_sec"); -+} -+ -+void Parker::park(bool isAbsolute, jlong time) { -+ // Optional fast-path check: -+ // Return immediately if a permit is available. -+ if (_counter > 0) { -+ _counter = 0 ; -+ return ; -+ } -+ -+ Thread* thread = Thread::current(); -+ assert(thread->is_Java_thread(), "Must be JavaThread"); -+ JavaThread *jt = (JavaThread *)thread; -+ -+ // Optional optimization -- avoid state transitions if there's an interrupt pending. -+ // Check interrupt before trying to wait -+ if (Thread::is_interrupted(thread, false)) { -+ return; -+ } -+ -+ // Next, demultiplex/decode time arguments -+ timespec absTime; -+ if (time < 0) { // don't wait at all -+ return; -+ } -+ if (time > 0) { -+ unpackTime(&absTime, isAbsolute, time); -+ } -+ -+ -+ // Enter safepoint region -+ // Beware of deadlocks such as 6317397. -+ // The per-thread Parker:: mutex is a classic leaf-lock. -+ // In particular a thread must never block on the Threads_lock while -+ // holding the Parker:: mutex. If safepoints are pending both the -+ // the ThreadBlockInVM() CTOR and DTOR may grab Threads_lock. -+ ThreadBlockInVM tbivm(jt); -+ -+ // Don't wait if cannot get lock since interference arises from -+ // unblocking. Also. check interrupt before trying wait -+ if (Thread::is_interrupted(thread, false) || pthread_mutex_trylock(_mutex) != 0) { -+ return; -+ } -+ -+ int status ; -+ if (_counter > 0) { // no wait needed -+ _counter = 0; -+ status = pthread_mutex_unlock(_mutex); -+ assert (status == 0, "invariant") ; -+ return; -+ } -+ -+#ifdef ASSERT -+ // Don't catch signals while blocked; let the running threads have the signals. -+ // (This allows a debugger to break into the running thread.) -+ sigset_t oldsigs; -+ sigset_t* allowdebug_blocked = os::Linux::allowdebug_blocked_signals(); -+ pthread_sigmask(SIG_BLOCK, allowdebug_blocked, &oldsigs); -+#endif -+ -+ OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */); -+ jt->set_suspend_equivalent(); -+ // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self() -+ -+ if (time == 0) { -+ status = pthread_cond_wait (_cond, _mutex) ; -+ } else { -+ status = os::Linux::safe_cond_timedwait (_cond, _mutex, &absTime) ; -+ if (status != 0 && WorkAroundNPTLTimedWaitHang) { -+ pthread_cond_destroy (_cond) ; -+ pthread_cond_init (_cond, NULL); -+ } -+ } -+ assert_status(status == 0 || status == EINTR || -+ status == ETIME || status == ETIMEDOUT, -+ status, "cond_timedwait"); -+ -+#ifdef ASSERT -+ pthread_sigmask(SIG_SETMASK, &oldsigs, NULL); -+#endif -+ -+ _counter = 0 ; -+ status = pthread_mutex_unlock(_mutex) ; -+ assert_status(status == 0, status, "invariant") ; -+ // If externally suspended while waiting, re-suspend -+ if (jt->handle_special_suspend_equivalent_condition()) { -+ jt->java_suspend_self(); -+ } -+ -+} -+ -+void Parker::unpark() { -+ int s, status ; -+ status = pthread_mutex_lock(_mutex); -+ assert (status == 0, "invariant") ; -+ s = _counter; -+ _counter = 1; -+ if (s < 1) { -+ if (WorkAroundNPTLTimedWaitHang) { -+ status = pthread_cond_signal (_cond) ; -+ assert (status == 0, "invariant") ; -+ status = pthread_mutex_unlock(_mutex); -+ assert (status == 0, "invariant") ; -+ } else { -+ status = pthread_mutex_unlock(_mutex); -+ assert (status == 0, "invariant") ; -+ status = pthread_cond_signal (_cond) ; -+ assert (status == 0, "invariant") ; -+ } -+ } else { -+ pthread_mutex_unlock(_mutex); -+ assert (status == 0, "invariant") ; -+ } -+} -+ -+ -+extern char** environ; -+ -+#ifndef __NR_fork -+#define __NR_fork IA32_ONLY(2) IA64_ONLY(not defined) AMD64_ONLY(57) -+#endif -+ -+#ifndef __NR_execve -+#define __NR_execve IA32_ONLY(11) IA64_ONLY(1033) AMD64_ONLY(59) -+#endif -+ -+// Run the specified command in a separate process. Return its exit value, -+// or -1 on failure (e.g. can't fork a new process). -+// Unlike system(), this function can be called from signal handler. It -+// doesn't block SIGINT et al. -+int os::fork_and_exec(char* cmd) { -+ char * argv[4]; -+ argv[0] = "sh"; -+ argv[1] = "-c"; -+ argv[2] = cmd; -+ argv[3] = NULL; -+ -+ // fork() in LinuxThreads/NPTL is not async-safe. It needs to run -+ // pthread_atfork handlers and reset pthread library. All we need is a -+ // separate process to execve. Make a direct syscall to fork process. -+ // On IA64 there's no fork syscall, we have to use fork() and hope for -+ // the best... -+ pid_t pid = NOT_IA64(syscall(__NR_fork);) -+ IA64_ONLY(fork();) -+ -+ if (pid < 0) { -+ // fork failed -+ return -1; -+ -+ } else if (pid == 0) { -+ // child process -+ -+ // execve() in LinuxThreads will call pthread_kill_other_threads_np() -+ // first to kill every thread on the thread list. Because this list is -+ // not reset by fork() (see notes above), execve() will instead kill -+ // every thread in the parent process. We know this is the only thread -+ // in the new process, so make a system call directly. -+ // IA64 should use normal execve() from glibc to match the glibc fork() -+ // above. -+ NOT_IA64(syscall(__NR_execve, "/bin/sh", argv, environ);) -+ IA64_ONLY(execve("/bin/sh", argv, environ);) -+ -+ // execve failed -+ _exit(-1); -+ -+ } else { -+ // copied from J2SE ..._waitForProcessExit() in UNIXProcess_md.c; we don't -+ // care about the actual exit code, for now. -+ -+ int status; -+ -+ // Wait for the child process to exit. This returns immediately if -+ // the child has already exited. */ -+ while (waitpid(pid, &status, 0) < 0) { -+ switch (errno) { -+ case ECHILD: return 0; -+ case EINTR: break; -+ default: return -1; -+ } -+ } -+ -+ if (WIFEXITED(status)) { -+ // The child exited normally; get its exit code. -+ return WEXITSTATUS(status); -+ } else if (WIFSIGNALED(status)) { -+ // The child exited because of a signal -+ // The best value to return is 0x80 + signal number, -+ // because that is what all Unix shells do, and because -+ // it allows callers to distinguish between process exit and -+ // process death by signal. -+ return 0x80 + WTERMSIG(status); -+ } else { -+ // Unknown exit code; pass it through -+ return status; -+ } -+ } -+} -diff -ruNb openjdk6/hotspot/src/os/linux/vm/os_linux.hpp openjdk/hotspot/src/os/linux/vm/os_linux.hpp ---- openjdk6/hotspot/src/os/linux/vm/os_linux.hpp 2008-07-10 22:04:27.000000000 +0200 -+++ openjdk/hotspot/src/os/linux/vm/os_linux.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)os_linux.hpp 1.71 08/06/16 14:16:05 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -55,8 +52,8 @@ - static address _initial_thread_stack_bottom; - static uintptr_t _initial_thread_stack_size; - -- static const char *_glibc_version; -- static const char *_libpthread_version; -+ static char *_glibc_version; -+ static char *_libpthread_version; - - static bool _is_floating_stack; - static bool _is_NPTL; -@@ -73,8 +70,8 @@ - static julong physical_memory() { return _physical_memory; } - static void initialize_system_info(); - -- static void set_glibc_version(const char *s) { _glibc_version = s; } -- static void set_libpthread_version(const char *s) { _libpthread_version = s; } -+ static void set_glibc_version(char *s) { _glibc_version = s; } -+ static void set_libpthread_version(char *s) { _libpthread_version = s; } - - static bool supports_variable_stack_size(); - -@@ -134,8 +131,8 @@ - static bool chained_handler(int sig, siginfo_t* siginfo, void* context); - - // GNU libc and libpthread version strings -- static const char *glibc_version() { return _glibc_version; } -- static const char *libpthread_version() { return _libpthread_version; } -+ static char *glibc_version() { return _glibc_version; } -+ static char *libpthread_version() { return _libpthread_version; } - - // NPTL or LinuxThreads? - static bool is_LinuxThreads() { return !_is_NPTL; } -@@ -192,252 +189,6 @@ - // LinuxThreads work-around for 6292965 - static int safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex, const struct timespec *_abstime); - -- // An event is a condition variable with associated mutex. -- // (A cond_t is only usable in combination with a mutex_t.) -- class Event : public CHeapObj { -- private: -- volatile int _count; -- volatile int _nParked ; -- double cachePad [4] ; -- pthread_mutex_t _mutex[1]; -- pthread_cond_t _cond[1]; -- -- public: -- Event * FreeNext ; // TSM free list linkage -- int Immortal ; -- -- public: -- Event() { -- verify(); -- int status; -- status = pthread_cond_init(_cond, NULL); -- assert_status(status == 0, status, "cond_init"); -- status = pthread_mutex_init(_mutex, NULL); -- assert_status(status == 0, status, "mutex_init"); -- _count = 0; -- _nParked = 0 ; -- FreeNext = NULL ; -- Immortal = 0 ; -- } -- ~Event() { -- int status; -- guarantee (Immortal == 0, "invariant") ; -- guarantee (_nParked == 0, "invariant") ; -- status = pthread_cond_destroy(_cond); -- assert_status(status == 0, status, "cond_destroy"); -- status = pthread_mutex_destroy(_mutex); -- assert_status(status == 0, status, "mutex_destroy"); -- } -- // hook to check for mutex corruption: -- void verify() PRODUCT_RETURN; -- // for use in critical sections: -- void lock() { -- verify(); -- int status = pthread_mutex_lock(_mutex); -- assert_status(status == 0, status, "mutex_lock"); -- } -- bool trylock() { -- verify(); -- int status = pthread_mutex_trylock(_mutex); -- if (status == EBUSY) { -- return false; -- } -- assert_status(status == 0, status, "mutex_lock"); -- return true; -- } -- void unlock() { -- verify(); -- int status = pthread_mutex_unlock(_mutex); -- assert_status(status == 0, status, "mutex_unlock"); -- } -- int timedwait(timespec* abstime) { -- verify(); -- ++_nParked ; -- int status = safe_cond_timedwait(_cond, _mutex, abstime); -- --_nParked ; -- if (status != 0 && _nParked == 0 && WorkAroundNPTLTimedWaitHang) { -- // Beware: if the condvar is currupted by the NPTL bug but we have -- // multiple threads parked in timedwait() -- as can happen with -- // Monitor::wait() -- then we don't have much recourse. -- // Reinitializing the condvar would likely orphan the other waiters. -- pthread_cond_destroy (_cond) ; -- pthread_cond_init (_cond, NULL) ; -- } -- assert_status(status == 0 || status == EINTR || -- status == ETIME || status == ETIMEDOUT, -- status, "cond_timedwait"); -- return status; -- } -- int timedwait(jlong millis) { -- timespec abst; -- Event::compute_abstime(&abst, millis); -- return timedwait(&abst); -- } -- int wait() { -- verify(); -- ++_nParked ; -- int status = pthread_cond_wait(_cond, _mutex); -- --_nParked ; -- // for some reason, under 2.7 lwp_cond_wait() may return ETIME ... -- // Treat this the same as if the wait was interrupted -- if(status == ETIME) { -- status = EINTR; -- } -- assert_status(status == 0 || status == EINTR, status, "cond_wait"); -- return status; -- } -- void signal() { -- verify(); -- int status = pthread_cond_signal(_cond); -- assert_status(status == 0, status, "cond_signal"); -- } -- void broadcast() { -- verify(); -- int status = pthread_cond_broadcast(_cond); -- assert_status(status == 0, status, "cond_broadcast"); -- } -- -- // TODO-FIXME: eliminate park, unpark and reset as well as interrupt_event(). -- // Convert from interrupt_interrupt() to Self->ParkEvent. -- -- // functions used to support monitor and interrupt -- // Note: park() may wake up spuriously. Use it in a loop. -- void park() { -- verify(); -- lock(); -- while (_count <= 0) { -- wait(); -- } -- _count = 0; -- unlock(); -- } -- -- int park(jlong millis) { -- verify(); -- int ret = OS_TIMEOUT; -- lock(); -- if (_count <= 0) { -- timedwait(millis); -- } -- if (_count > 0) { -- _count = 0; -- ret = OS_OK; -- } -- unlock(); -- return ret; -- } -- -- void unpark() { -- verify(); -- lock(); -- int AnyWaiters = _nParked - _count ; -- _count = 1; -- // Refer to the comments in os_solaris.hpp -- // Try to avoid the call to signal(), and, if possible, -- // call signal() after dropping the lock. -- if (AnyWaiters > 0) { -- if (Immortal && WorkAroundNPTLTimedWaitHang == 0) { -- unlock(); signal(); -- } else { -- signal(); unlock(); -- } -- } else { -- unlock(); -- } -- } -- -- void reset() { -- verify(); -- assert (_nParked == 0, "invariant") ; -- _count = 0; -- } -- -- // utility to compute the abstime argument to timedwait: -- static struct timespec* compute_abstime(timespec* abstime, jlong millis) { -- // millis is the relative timeout time -- // abstime will be the absolute timeout time -- if (millis < 0) millis = 0; -- struct timeval now; -- int status = gettimeofday(&now, NULL); -- assert(status == 0, "gettimeofday"); -- jlong seconds = millis / 1000; -- millis %= 1000; -- if (seconds > 50000000) { // see man cond_timedwait(3T) -- seconds = 50000000; -- } -- abstime->tv_sec = now.tv_sec + seconds; -- long usec = now.tv_usec + millis * 1000; -- if (usec >= 1000000) { -- abstime->tv_sec += 1; -- usec -= 1000000; -- } -- abstime->tv_nsec = usec * 1000; -- return abstime; -- } -- }; -- -- // An OSMutex is an abstraction used in the implementation of -- // ObjectMonitor; needed to abstract over the different thread -- // libraries' mutexes on Solaris. -- class OSMutex : public CHeapObj { -- private: -- #ifndef PRODUCT -- debug_only(volatile pthread_t _owner;) -- debug_only(volatile bool _is_owned;) -- #endif -- pthread_mutex_t _mutex[1]; -- -- public: -- OSMutex() { -- verify(); -- int status = pthread_mutex_init(_mutex, NULL); -- assert_status(status == 0, status, "pthread_mutex_init"); -- #ifndef PRODUCT -- debug_only(_is_owned = false;) -- #endif -- } -- ~OSMutex() { -- int status = pthread_mutex_destroy(_mutex); -- assert_status(status == 0, status, "pthread_mutex_destroy"); -- } -- // for use in critical sections: -- void lock() { -- verify(); -- int status = pthread_mutex_lock(_mutex); -- assert_status(status == 0, status, "pthread_mutex_lock"); -- #ifndef PRODUCT -- assert(_is_owned == false, "mutex_lock should not have had owner"); -- debug_only(_owner = pthread_self();) -- debug_only(_is_owned = true;) -- #endif -- } -- bool trylock() { -- verify(); -- int status = pthread_mutex_trylock(_mutex); -- if (status == EBUSY) -- return false; -- assert_status(status == 0, status, "pthread_mutex_trylock"); -- #ifndef PRODUCT -- debug_only(_owner = pthread_self();) -- debug_only(_is_owned = true;) -- #endif -- return true; -- } -- void unlock() { -- verify(); -- #ifndef PRODUCT -- debug_only(pthread_t my_id = pthread_self();) -- assert(pthread_equal(_owner, my_id), "mutex_unlock"); -- debug_only(_is_owned = false;) -- #endif -- int status = pthread_mutex_unlock(_mutex); -- assert_status(status == 0, status, "pthread_mutex_unlock"); -- } -- -- // hook to check for mutex corruption: -- void verify() PRODUCT_RETURN; -- void verify_locked() PRODUCT_RETURN; -- }; - - // Linux suspend/resume support - this helper is a shadow of its former - // self now that low-level suspension is barely used, and old workarounds -@@ -511,6 +262,7 @@ - int fired() { return _Event; } - void park () ; - void unpark () ; -+ int TryPark () ; - int park (jlong millis) ; - void SetAssociation (Thread * a) { _Assoc = a ; } - } ; -diff -ruNb openjdk6/hotspot/src/os/linux/vm/os_linux.inline.hpp openjdk/hotspot/src/os/linux/vm/os_linux.inline.hpp ---- openjdk6/hotspot/src/os/linux/vm/os_linux.inline.hpp 2008-07-10 22:04:27.000000000 +0200 -+++ openjdk/hotspot/src/os/linux/vm/os_linux.inline.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)os_linux.inline.hpp 1.30 07/05/05 17:04:36 JVM" --#endif - /* - * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/os/linux/vm/os_share_linux.hpp openjdk/hotspot/src/os/linux/vm/os_share_linux.hpp ---- openjdk6/hotspot/src/os/linux/vm/os_share_linux.hpp 2008-07-10 22:04:27.000000000 +0200 -+++ openjdk/hotspot/src/os/linux/vm/os_share_linux.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)os_share_linux.hpp 1.11 07/05/05 17:04:36 JVM" --#endif - /* - * Copyright 1999-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/os/linux/vm/perfMemory_linux.cpp openjdk/hotspot/src/os/linux/vm/perfMemory_linux.cpp ---- openjdk6/hotspot/src/os/linux/vm/perfMemory_linux.cpp 2008-07-10 22:04:27.000000000 +0200 -+++ openjdk/hotspot/src/os/linux/vm/perfMemory_linux.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)perfMemory_linux.cpp 1.30 07/05/05 17:04:35 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -942,7 +939,7 @@ - // to the specified file name no matter whether PerfDataSaveToFile is specified - // or not. In other word, -XX:PerfDataSaveFile=.. overrides flag - // -XX:+PerfDataSaveToFile. -- if (PerfDataSaveToFile || PerfDataSaveFile[0] != '\0') { -+ if (PerfDataSaveToFile || PerfDataSaveFile != NULL) { - save_memory_to_file(start(), capacity()); - } - -@@ -1012,4 +1009,3 @@ - char* PerfMemory::backing_store_filename() { - return backing_store_file_name; - } -- -diff -ruNb openjdk6/hotspot/src/os/linux/vm/stubRoutines_linux.cpp openjdk/hotspot/src/os/linux/vm/stubRoutines_linux.cpp ---- openjdk6/hotspot/src/os/linux/vm/stubRoutines_linux.cpp 2008-07-10 22:04:27.000000000 +0200 -+++ openjdk/hotspot/src/os/linux/vm/stubRoutines_linux.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)stubRoutines_linux.cpp 1.10 07/05/05 17:04:36 JVM" --#endif - /* - * Copyright 2001 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/os/linux/vm/threadCritical_linux.cpp openjdk/hotspot/src/os/linux/vm/threadCritical_linux.cpp ---- openjdk6/hotspot/src/os/linux/vm/threadCritical_linux.cpp 2008-07-10 22:04:27.000000000 +0200 -+++ openjdk/hotspot/src/os/linux/vm/threadCritical_linux.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)threadCritical_linux.cpp 1.16 07/05/05 17:04:37 JVM" --#endif - /* - * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -67,4 +64,3 @@ - guarantee(ret == 0, "fatal error with pthread_mutex_unlock()"); - } - } -- -diff -ruNb openjdk6/hotspot/src/os/linux/vm/thread_linux.inline.hpp openjdk/hotspot/src/os/linux/vm/thread_linux.inline.hpp ---- openjdk6/hotspot/src/os/linux/vm/thread_linux.inline.hpp 2008-07-10 22:04:27.000000000 +0200 -+++ openjdk/hotspot/src/os/linux/vm/thread_linux.inline.hpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_HDR --#pragma ident "@(#)thread_linux.inline.hpp 1.10 07/05/05 17:04:37 JVM" --#endif - /* - * Copyright 2002-2003 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -diff -ruNb openjdk6/hotspot/src/os/linux/vm/vmError_linux.cpp openjdk/hotspot/src/os/linux/vm/vmError_linux.cpp ---- openjdk6/hotspot/src/os/linux/vm/vmError_linux.cpp 2008-07-10 22:04:27.000000000 +0200 -+++ openjdk/hotspot/src/os/linux/vm/vmError_linux.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)vmError_linux.cpp 1.14 08/06/17 09:14:15 JVM" --#endif - /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -@@ -34,84 +31,6 @@ - #include - #include - --extern char** environ; -- --#ifndef __NR_fork --#define __NR_fork IA32_ONLY(2) IA64_ONLY(not defined) AMD64_ONLY(57) --#endif -- --#ifndef __NR_execve --#define __NR_execve IA32_ONLY(11) IA64_ONLY(1033) AMD64_ONLY(59) --#endif -- --// Run the specified command in a separate process. Return its exit value, --// or -1 on failure (e.g. can't fork a new process). --// Unlike system(), this function can be called from signal handler. It --// doesn't block SIGINT et al. --int VMError::fork_and_exec(char* cmd) { -- const char * argv[4] = {"sh", "-c", cmd, NULL}; -- -- // fork() in LinuxThreads/NPTL is not async-safe. It needs to run -- // pthread_atfork handlers and reset pthread library. All we need is a -- // separate process to execve. Make a direct syscall to fork process. -- // On IA64 there's no fork syscall, we have to use fork() and hope for -- // the best... -- pid_t pid = NOT_IA64(syscall(__NR_fork);) -- IA64_ONLY(fork();) -- -- if (pid < 0) { -- // fork failed -- return -1; -- -- } else if (pid == 0) { -- // child process -- -- // execve() in LinuxThreads will call pthread_kill_other_threads_np() -- // first to kill every thread on the thread list. Because this list is -- // not reset by fork() (see notes above), execve() will instead kill -- // every thread in the parent process. We know this is the only thread -- // in the new process, so make a system call directly. -- // IA64 should use normal execve() from glibc to match the glibc fork() -- // above. -- NOT_IA64(syscall(__NR_execve, "/bin/sh", argv, environ);) -- IA64_ONLY(execve("/bin/sh", (char* const*)argv, environ);) -- -- // execve failed -- _exit(-1); -- -- } else { -- // copied from J2SE ..._waitForProcessExit() in UNIXProcess_md.c; we don't -- // care about the actual exit code, for now. -- -- int status; -- -- // Wait for the child process to exit. This returns immediately if -- // the child has already exited. */ -- while (waitpid(pid, &status, 0) < 0) { -- switch (errno) { -- case ECHILD: return 0; -- case EINTR: break; -- default: return -1; -- } -- } -- -- if (WIFEXITED(status)) { -- // The child exited normally; get its exit code. -- return WEXITSTATUS(status); -- } else if (WIFSIGNALED(status)) { -- // The child exited because of a signal -- // The best value to return is 0x80 + signal number, -- // because that is what all Unix shells do, and because -- // it allows callers to distinguish between process exit and -- // process death by signal. -- return 0x80 + WTERMSIG(status); -- } else { -- // Unknown exit code; pass it through -- return status; -- } -- } --} -- - void VMError::show_message_box(char *buf, int buflen) { - bool yes; - do { -@@ -135,7 +54,8 @@ - jio_snprintf(buf, buflen, "gdb /proc/%d/exe %d", - os::current_process_id(), os::current_process_id()); - -- fork_and_exec(buf); -+ os::fork_and_exec(buf); -+ yes = false; - } - } while (yes); - } -diff -ruNb openjdk6/hotspot/src/os/linux/vm/vtune_linux.cpp openjdk/hotspot/src/os/linux/vm/vtune_linux.cpp ---- openjdk6/hotspot/src/os/linux/vm/vtune_linux.cpp 2008-07-10 22:04:27.000000000 +0200 -+++ openjdk/hotspot/src/os/linux/vm/vtune_linux.cpp 2007-12-14 08:57:02.000000000 +0100 -@@ -1,6 +1,3 @@ --#ifdef USE_PRAGMA_IDENT_SRC --#pragma ident "@(#)vtune_linux.cpp 1.12 07/05/05 17:04:35 JVM" --#endif - /* - * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.