1 diff -r f5603a6e5042 .hgignore
2 --- a/.hgignore Wed Nov 17 22:42:08 2010 -0800
3 +++ b/.hgignore Fri Dec 17 13:24:08 2010 +0100
8 -^src/share/tools/hsdis/build/
9 -^src/share/tools/IdealGraphVisualizer/[a-zA-Z0-9]*/build/
10 -^src/share/tools/IdealGraphVisualizer/build/
11 -^src/share/tools/IdealGraphVisualizer/dist/
21 +^src/share/tools/hsdis/build/
36 +^src/share/tools/IdealGraphVisualizer/[a-zA-Z0-9]*/build/
37 +^src/share/tools/IdealGraphVisualizer/build/
38 +^src/share/tools/IdealGraphVisualizer/dist/
39 diff -r f5603a6e5042 .hgtags
40 --- a/.hgtags Wed Nov 17 22:42:08 2010 -0800
41 +++ b/.hgtags Fri Dec 17 13:24:08 2010 +0100
43 806d0c037e6bbb88dac0699673f4ba55ee8c02da jdk7-b117
44 698b7b727e12de44139d8cca6ab9a494ead13253 jdk7-b118
45 3ef7426b4deac5dcfd4afb35cabe9ab3d666df91 hs20-b02
46 +946201493cab53f518c55272b6f27517a0ba4e0e build 0.1-b01
47 +4425fe0d7f0ec7f8583ae687f7eb1b4a3e94ea09 build 0.1-b02
48 +0c5e4a085baa8aaa9aed55b20810de4bdc2d6548 build 0.2-b01
49 +34520cf6c532e28f529340f66f71855aadf83d95 build 0.2-b02
50 diff -r f5603a6e5042 build.cmd
51 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
52 +++ b/build.cmd Fri Dec 17 13:24:08 2010 +0100
54 +set HotSpotMksHome=C:\Cygwin\bin
55 +set path=%JAVA_HOME%;C:\Cygwin\bin
56 +call "%VS_VCVARS%\vsvars32.bat"
61 +call build.bat product compiler1 %OrigPath% %JAVA_HOME%
62 +call build.bat fastdebug compiler1 %OrigPath% %JAVA_HOME%
66 diff -r f5603a6e5042 create.cmd
67 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
68 +++ b/create.cmd Fri Dec 17 13:24:08 2010 +0100
70 +set HotSpotMksHome=C:\Cygwin\bin
71 +set path=%JAVA_HOME%\bin;C:\Cygwin\bin
72 +call "%VS_VCVARS%\vsvars32.bat"
77 +mkdir %OrigPath%\work
78 +call create.bat %OrigPath% %OrigPath%\work %OrigPath%\java
82 diff -r f5603a6e5042 create64.cmd
83 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
84 +++ b/create64.cmd Fri Dec 17 13:24:08 2010 +0100
86 +set HotSpotMksHome=C:\cygwin\bin
87 +set JAVA_HOME=%cd%\java64
89 +set path=%JAVA_HOME%\bin;%path%;C:\cygwin\bin
94 +mkdir %OrigPath%\work64
95 +call create.bat %OrigPath% %OrigPath%\work64 %OrigPath%\java64
100 diff -r f5603a6e5042 create_installers.cmd
101 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
102 +++ b/create_installers.cmd Fri Dec 17 13:24:08 2010 +0100
104 +copy hotswapinstaller\Installer\dist\Installer.jar dcevm-mac.jar
105 +jar uvf dcevm-mac.jar -C hotswapbinaries\mac\ .
106 +jar uvf dcevm-mac.jar -C hotswapinstaller\Installer\dist data\dcevm.jar
108 +copy hotswapinstaller\Installer\dist\Installer.jar dcevm-win.jar
109 +jar uvf dcevm-win.jar -C hotswapbinaries\win\ .
110 +jar uvf dcevm-win.jar -C hotswapinstaller\Installer\dist data\dcevm.jar
112 +copy hotswapinstaller\Installer\dist\Installer.jar dcevm-linux.jar
113 +jar uvf dcevm-linux.jar -C hotswapbinaries\linux\ .
114 +jar uvf dcevm-linux.jar -C hotswapinstaller\Installer\dist data\dcevm.jar
115 \ No newline at end of file
116 diff -r f5603a6e5042 create_installers.sh
117 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
118 +++ b/create_installers.sh Fri Dec 17 13:24:08 2010 +0100
120 +cp hotswapinstaller/Installer/dist/Installer.jar dcevm-mac.jar
121 +jar uvf dcevm-mac.jar -C hotswapbinaries/mac/ .
122 +jar uvf dcevm-mac.jar -C hotswapinstaller/Installer/dist data/dcevm.jar
124 +cp hotswapinstaller/Installer/dist/Installer.jar dcevm-win.jar
125 +jar uvf dcevm-win.jar -C hotswapbinaries/win/ .
126 +jar uvf dcevm-win.jar -C hotswapinstaller/Installer/dist data/dcevm.jar
128 +cp hotswapinstaller/Installer/dist/Installer.jar dcevm-linux.jar
129 +jar uvf dcevm-linux.jar -C hotswapbinaries/linux/ .
130 +jar uvf dcevm-linux.jar -C hotswapinstaller/Installer/dist data/dcevm.jar
131 diff -r f5603a6e5042 hotswapbinaries/README
132 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
133 +++ b/hotswapbinaries/README Fri Dec 17 13:24:08 2010 +0100
135 +The binary files are not stored in the mercurial repository, because they would bloat the repository size. The expected files in this subdirectory are:
137 +==========================================
139 +win/data/64/bin/server/jvm.dll
140 +win/data/bin/client/jvm.dll
141 +win/data/bin/server/jvm.dll
143 +==========================================
145 +mac/data/lib/i386/client/libjvm.dylib
146 +mac/data/lib/i386/server/libjvm.dylib
148 +==========================================
150 +linux/data/64/lib/amd64/server/libjvm.so
151 +linux/data/lib/i386/client/libjvm.so
152 +linux/data/lib/i386/server/libjvm.so
153 diff -r f5603a6e5042 make/windows/build_vm_def.sh
154 --- a/make/windows/build_vm_def.sh Wed Nov 17 22:42:08 2010 -0800
155 +++ b/make/windows/build_vm_def.sh Fri Dec 17 13:24:08 2010 +0100
157 CAT="$MKS_HOME/cat.exe"
158 RM="$MKS_HOME/rm.exe"
159 DUMPBIN="link.exe /dump"
160 +export VS_UNICODE_OUTPUT=
162 # When called from IDE the first param should contain the link version, otherwise may be nill
163 if [ "x$1" != "x" ]; then
164 diff -r f5603a6e5042 make/windows/create.bat
165 --- a/make/windows/create.bat Wed Nov 17 22:42:08 2010 -0800
166 +++ b/make/windows/create.bat Fri Dec 17 13:24:08 2010 +0100
168 REM Note: Running this batch file from the Windows command shell requires
169 REM that "grep" be accessible on the PATH. An MKS install does this.
171 +cl 2>&1 | grep "x64" >NUL
172 +if %errorlevel% == 0 goto amd64
173 cl 2>&1 | grep "IA-64" >NUL
174 if %errorlevel% == 0 goto isia64
175 cl 2>&1 | grep "AMD64" >NUL
176 diff -r f5603a6e5042 src/cpu/x86/vm/interp_masm_x86_32.cpp
177 --- a/src/cpu/x86/vm/interp_masm_x86_32.cpp Wed Nov 17 22:42:08 2010 -0800
178 +++ b/src/cpu/x86/vm/interp_masm_x86_32.cpp Fri Dec 17 13:24:08 2010 +0100
179 @@ -1352,7 +1352,7 @@
182 // RedefineClasses() tracing support for obsolete method entry
183 - if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) {
188 diff -r f5603a6e5042 src/cpu/x86/vm/interp_masm_x86_64.cpp
189 --- a/src/cpu/x86/vm/interp_masm_x86_64.cpp Wed Nov 17 22:42:08 2010 -0800
190 +++ b/src/cpu/x86/vm/interp_masm_x86_64.cpp Fri Dec 17 13:24:08 2010 +0100
191 @@ -1438,7 +1438,7 @@
194 // RedefineClasses() tracing support for obsolete method entry
195 - if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) {
199 CAST_FROM_FN_PTR(address, SharedRuntime::rc_trace_method_entry),
200 diff -r f5603a6e5042 src/cpu/x86/vm/sharedRuntime_x86_32.cpp
201 --- a/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Wed Nov 17 22:42:08 2010 -0800
202 +++ b/src/cpu/x86/vm/sharedRuntime_x86_32.cpp Fri Dec 17 13:24:08 2010 +0100
203 @@ -1494,7 +1494,7 @@
206 // RedefineClasses() tracing support for obsolete method entry
207 - if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) {
209 __ movoop(rax, JNIHandles::make_local(method()));
211 CAST_FROM_FN_PTR(address, SharedRuntime::rc_trace_method_entry),
212 diff -r f5603a6e5042 src/cpu/x86/vm/sharedRuntime_x86_64.cpp
213 --- a/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Wed Nov 17 22:42:08 2010 -0800
214 +++ b/src/cpu/x86/vm/sharedRuntime_x86_64.cpp Fri Dec 17 13:24:08 2010 +0100
215 @@ -1490,7 +1490,7 @@
218 // RedefineClasses() tracing support for obsolete method entry
219 - if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) {
221 // protect the args we've loaded
222 save_args(masm, total_c_args, c_arg, out_regs);
223 __ movoop(c_rarg1, JNIHandles::make_local(method()));
224 diff -r f5603a6e5042 src/cpu/x86/vm/templateTable_x86_32.cpp
225 --- a/src/cpu/x86/vm/templateTable_x86_32.cpp Wed Nov 17 22:42:08 2010 -0800
226 +++ b/src/cpu/x86/vm/templateTable_x86_32.cpp Fri Dec 17 13:24:08 2010 +0100
227 @@ -2110,6 +2110,22 @@
228 // resolve first time through
230 switch (bytecode()) {
231 + case Bytecodes::_fast_agetfield : // fall through
232 + case Bytecodes::_fast_bgetfield : // fall through
233 + case Bytecodes::_fast_cgetfield : // fall through
234 + case Bytecodes::_fast_dgetfield : // fall through
235 + case Bytecodes::_fast_fgetfield : // fall through
236 + case Bytecodes::_fast_igetfield : // fall through
237 + case Bytecodes::_fast_lgetfield : // fall through
238 + case Bytecodes::_fast_sgetfield : // fall through
239 + case Bytecodes::_fast_aputfield : // fall through
240 + case Bytecodes::_fast_bputfield : // fall through
241 + case Bytecodes::_fast_cputfield : // fall through
242 + case Bytecodes::_fast_dputfield : // fall through
243 + case Bytecodes::_fast_fputfield : // fall through
244 + case Bytecodes::_fast_iputfield : // fall through
245 + case Bytecodes::_fast_lputfield : // fall through
246 + case Bytecodes::_fast_sputfield : // fall through
247 case Bytecodes::_getstatic : // fall through
248 case Bytecodes::_putstatic : // fall through
249 case Bytecodes::_getfield : // fall through
250 @@ -2204,6 +2220,7 @@
251 // Correct values of the cache and index registers are preserved.
252 void TemplateTable::jvmti_post_field_access(Register cache,
257 if (JvmtiExport::can_post_field_access()) {
258 @@ -2230,7 +2247,11 @@
259 // cache: cache entry pointer
260 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_access),
262 - __ get_cache_and_index_at_bcp(cache, index, 1);
264 + // (tw) Redefinition might have occured => reresolve the cp entry.
266 + resolve_cache_and_index(byte_no, noreg, cache, index, sizeof(u2));
271 @@ -2251,7 +2272,7 @@
272 const Register flags = rax;
274 resolve_cache_and_index(byte_no, noreg, cache, index, sizeof(u2));
275 - jvmti_post_field_access(cache, index, is_static, false);
276 + jvmti_post_field_access(cache, index, byte_no, is_static, false);
277 load_field_cp_cache_entry(obj, cache, index, off, flags, is_static);
279 if (!is_static) pop_and_check_object(obj);
280 @@ -2386,7 +2407,7 @@
282 // The registers cache and index expected to be set before call.
283 // The function may destroy various registers, just not the cache and index registers.
284 -void TemplateTable::jvmti_post_field_mod(Register cache, Register index, bool is_static) {
285 +void TemplateTable::jvmti_post_field_mod(Register cache, Register index, int byte_no, bool is_static) {
287 ByteSize cp_base_offset = constantPoolCacheOopDesc::base_offset();
289 @@ -2444,7 +2465,11 @@
290 // rcx: jvalue object on the stack
291 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_modification),
293 - __ get_cache_and_index_at_bcp(cache, index, 1);
295 + // (tw) Redefinition might have occured => reresolve the cp entry.
297 + resolve_cache_and_index(byte_no, noreg, cache, index, sizeof(u2));
302 @@ -2460,7 +2485,7 @@
303 const Register flags = rax;
305 resolve_cache_and_index(byte_no, noreg, cache, index, sizeof(u2));
306 - jvmti_post_field_mod(cache, index, is_static);
307 + jvmti_post_field_mod(cache, index, byte_no, is_static);
308 load_field_cp_cache_entry(obj, cache, index, off, flags, is_static);
310 // Doug Lea believes this is not needed with current Sparcs (TSO) and Intel (PSO).
311 @@ -2683,6 +2708,11 @@
312 // rax,: cache entry pointer
313 // rcx: jvalue object on the stack
314 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_modification), rbx, rax, rcx);
316 + // (tw) Redefinition might have occured => reresolve the cp entry.
318 + resolve_cache_and_index(2, noreg, rax, rcx, sizeof(u2));
320 if (bytecode() == Bytecodes::_fast_lputfield) __ pop(rdx); // restore high value
321 __ pop(rax); // restore lower value
322 __ addptr(rsp, sizeof(jvalue)); // release jvalue object space
323 @@ -2803,6 +2833,11 @@
324 // rcx: cache entry pointer
325 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_access), rax, rcx);
326 __ pop_ptr(rax); // restore object pointer
328 + // (tw) Redefinition might have occured => reresolve the cp entry.
330 + resolve_cache_and_index(1, noreg, rax, rcx, sizeof(u2));
335 diff -r f5603a6e5042 src/cpu/x86/vm/templateTable_x86_64.cpp
336 --- a/src/cpu/x86/vm/templateTable_x86_64.cpp Wed Nov 17 22:42:08 2010 -0800
337 +++ b/src/cpu/x86/vm/templateTable_x86_64.cpp Fri Dec 17 13:24:08 2010 +0100
338 @@ -2113,6 +2113,22 @@
339 // resolve first time through
341 switch (bytecode()) {
342 + case Bytecodes::_fast_agetfield : // fall through
343 + case Bytecodes::_fast_bgetfield : // fall through
344 + case Bytecodes::_fast_cgetfield : // fall through
345 + case Bytecodes::_fast_dgetfield : // fall through
346 + case Bytecodes::_fast_fgetfield : // fall through
347 + case Bytecodes::_fast_igetfield : // fall through
348 + case Bytecodes::_fast_lgetfield : // fall through
349 + case Bytecodes::_fast_sgetfield : // fall through
350 + case Bytecodes::_fast_aputfield : // fall through
351 + case Bytecodes::_fast_bputfield : // fall through
352 + case Bytecodes::_fast_cputfield : // fall through
353 + case Bytecodes::_fast_dputfield : // fall through
354 + case Bytecodes::_fast_fputfield : // fall through
355 + case Bytecodes::_fast_iputfield : // fall through
356 + case Bytecodes::_fast_lputfield : // fall through
357 + case Bytecodes::_fast_sputfield : // fall through
358 case Bytecodes::_getstatic:
359 case Bytecodes::_putstatic:
360 case Bytecodes::_getfield:
361 @@ -2219,7 +2235,7 @@
362 // The registers cache and index expected to be set before call.
363 // Correct values of the cache and index registers are preserved.
364 void TemplateTable::jvmti_post_field_access(Register cache, Register index,
365 - bool is_static, bool has_tos) {
366 + int byte_no, bool is_static, bool has_tos) {
367 // do the JVMTI work here to avoid disturbing the register state below
368 // We use c_rarg registers here because we want to use the register used in
369 // the call to the VM
370 @@ -2250,7 +2266,11 @@
371 __ call_VM(noreg, CAST_FROM_FN_PTR(address,
372 InterpreterRuntime::post_field_access),
373 c_rarg1, c_rarg2, c_rarg3);
374 - __ get_cache_and_index_at_bcp(cache, index, 1);
376 + // (tw) Redefinition might have occured => reresolve the cp entry.
378 + resolve_cache_and_index(byte_no, noreg, cache, index, sizeof(u2));
383 @@ -2272,7 +2292,7 @@
384 const Register bc = c_rarg3; // uses same reg as obj, so don't mix them
386 resolve_cache_and_index(byte_no, noreg, cache, index, sizeof(u2));
387 - jvmti_post_field_access(cache, index, is_static, false);
388 + jvmti_post_field_access(cache, index, byte_no, is_static, false);
389 load_field_cp_cache_entry(obj, cache, index, off, flags, is_static);
392 @@ -2406,7 +2426,7 @@
394 // The registers cache and index expected to be set before call.
395 // The function may destroy various registers, just not the cache and index registers.
396 -void TemplateTable::jvmti_post_field_mod(Register cache, Register index, bool is_static) {
397 +void TemplateTable::jvmti_post_field_mod(Register cache, Register index, int byte_no, bool is_static) {
398 transition(vtos, vtos);
400 ByteSize cp_base_offset = constantPoolCacheOopDesc::base_offset();
401 @@ -2459,7 +2479,11 @@
402 CAST_FROM_FN_PTR(address,
403 InterpreterRuntime::post_field_modification),
404 c_rarg1, c_rarg2, c_rarg3);
405 - __ get_cache_and_index_at_bcp(cache, index, 1);
407 + // (tw) Redefinition might have occured => reresolve the cp entry.
409 + resolve_cache_and_index(byte_no, noreg, cache, index, sizeof(u2));
414 @@ -2475,7 +2499,7 @@
415 const Register bc = c_rarg3;
417 resolve_cache_and_index(byte_no, noreg, cache, index, sizeof(u2));
418 - jvmti_post_field_mod(cache, index, is_static);
419 + jvmti_post_field_mod(cache, index, byte_no, is_static);
420 load_field_cp_cache_entry(obj, cache, index, off, flags, is_static);
422 // [jk] not needed currently
423 @@ -2661,6 +2685,11 @@
424 CAST_FROM_FN_PTR(address,
425 InterpreterRuntime::post_field_modification),
426 rbx, c_rarg2, c_rarg3);
428 + // (tw) Redefinition might have occured => reresolve the cp entry.
430 + resolve_cache_and_index(2, noreg, rax, rcx, sizeof(u2));
432 __ pop(rax); // restore lower value
433 __ addptr(rsp, sizeof(jvalue)); // release jvalue object space
435 @@ -2762,6 +2791,11 @@
437 __ mov(rax, r12); // restore object pointer
438 __ reinit_heapbase();
440 + // (tw) Redefinition might have occured => reresolve the cp entry.
442 + resolve_cache_and_index(1, noreg, rax, rcx, sizeof(u2));
447 diff -r f5603a6e5042 src/share/tools/MakeDeps/BuildConfig.java
448 --- a/src/share/tools/MakeDeps/BuildConfig.java Wed Nov 17 22:42:08 2010 -0800
449 +++ b/src/share/tools/MakeDeps/BuildConfig.java Fri Dec 17 13:24:08 2010 +0100
452 void initDefaultDefines(Vector defines) {
453 Vector sysDefines = new Vector();
454 - sysDefines.add("WIN32");
456 + if( Util.os().equals("Win32")) {
457 + sysDefines.add("WIN32");
458 + sysDefines.add("HOTSPOT_LIB_ARCH=\\\"i386\\\"");
460 + sysDefines.add("_AMD64_");
461 + sysDefines.add("AMD64");
462 + sysDefines.add("_WIN64");
463 + sysDefines.add("_LP64");
464 + if (System.getenv("MSC_VER") != null)
465 + sysDefines.add("MSC_VER=" + System.getenv("MSC_VER"));
466 + sysDefines.add("HOTSPOT_LIB_ARCH=\\\"amd64\\\"");
469 sysDefines.add("_WINDOWS");
470 sysDefines.add("HOTSPOT_BUILD_USER="+System.getProperty("user.name"));
471 sysDefines.add("HOTSPOT_BUILD_TARGET=\\\""+get("Build")+"\\\"");
472 diff -r f5603a6e5042 src/share/tools/MakeDeps/Util.java
473 --- a/src/share/tools/MakeDeps/Util.java Wed Nov 17 22:42:08 2010 -0800
474 +++ b/src/share/tools/MakeDeps/Util.java Fri Dec 17 13:24:08 2010 +0100
478 static String sep = File.separator;
479 - static String os = "Win32"; //System.getProperty("os.name");
481 + private static String _os;
483 + static String os() {
486 + for(Map.Entry<String, String> entry: System.getenv().entrySet())
487 + if("PLATFORM_ARCH_MODEL".equals(entry.getKey().toUpperCase())) {
488 + String archModel = entry.getValue();
489 + if("x86_32".equals(archModel))
491 + else if("x86_64".equals(archModel))
494 + throw new RuntimeException("Unsupported PLATFORM_ARCH_MODEL " + archModel);
497 + throw new RuntimeException("PLATFORM_ARCH_MODEL not specified");
503 diff -r f5603a6e5042 src/share/tools/MakeDeps/WinGammaPlatformVC6.java
504 --- a/src/share/tools/MakeDeps/WinGammaPlatformVC6.java Wed Nov 17 22:42:08 2010 -0800
505 +++ b/src/share/tools/MakeDeps/WinGammaPlatformVC6.java Fri Dec 17 13:24:08 2010 +0100
507 " /nologo /base:\"0x8000000\" /subsystem:windows /dll" +
508 " /export:JNI_GetDefaultJavaVMInitArgs /export:JNI_CreateJavaVM /export:JNI_GetCreatedJavaVMs "+
509 " /export:jio_snprintf /export:jio_printf /export:jio_fprintf /export:jio_vfprintf "+
510 - " /export:jio_vsnprintf ");
511 + " /export:jio_vsnprintf /export:JVM_GetVersionInfo /export:JVM_GetThreadStateNames /export:JVM_GetThreadStateValues /export:JVM_InitAgentProperties /export:JVM_FindClassFromBootLoader");
512 rv.add("SUBTRACT LINK32 /pdb:none /map");
518 String makeCfgName(String flavourBuild) {
519 - return "vm - "+ Util.os + " " + flavourBuild;
520 + return "vm - "+ "Win32" + " " + flavourBuild;
523 diff -r f5603a6e5042 src/share/tools/MakeDeps/WinGammaPlatformVC7.java
524 --- a/src/share/tools/MakeDeps/WinGammaPlatformVC7.java Wed Nov 17 22:42:08 2010 -0800
525 +++ b/src/share/tools/MakeDeps/WinGammaPlatformVC7.java Fri Dec 17 13:24:08 2010 +0100
529 startTag("Platforms", null);
530 - tag("Platform", new String[] {"Name", Util.os});
531 + tag("Platform", new String[] {"Name", Util.os()});
534 startTag("Configurations", null);
536 "PreprocessorDefinitions", "NDEBUG",
537 "MkTypLibCompatible", "TRUE",
538 "SuppressStartupBanner", "TRUE",
539 - "TargetEnvironment", "1",
540 + "TargetEnvironment", Util.os().equals("Win32") ? "1" : "3",
541 "TypeLibraryName", cfg.get("OutputDir") + Util.sep + "vm.tlb",
545 "/export:JNI_GetCreatedJavaVMs "+
546 "/export:jio_snprintf /export:jio_printf "+
547 "/export:jio_fprintf /export:jio_vfprintf "+
548 - "/export:jio_vsnprintf ");
549 + "/export:jio_vsnprintf /export:JVM_GetVersionInfo /export:JVM_GetThreadStateNames /export:JVM_GetThreadStateValues /export:JVM_InitAgentProperties /export:JVM_FindClassFromBootLoader");
550 addAttr(rv, "AdditionalDependencies", "Wsock32.lib winmm.lib");
551 addAttr(rv, "OutputFile", outDll);
552 // Set /INCREMENTAL option. 1 is linkIncrementalNo
554 addAttr(rv, "BaseAddress", "0x8000000");
555 addAttr(rv, "ImportLibrary", outDir+Util.sep+"jvm.lib");
556 // Set /MACHINE option. 1 is machineX86
557 - addAttr(rv, "TargetMachine", "1");
558 + addAttr(rv, "TargetMachine", Util.os().equals("Win32") ? "1" : "17");
565 String makeCfgName(String flavourBuild) {
566 - return flavourBuild + "|" + Util.os;
567 + return flavourBuild + "|" + Util.os();
570 diff -r f5603a6e5042 src/share/tools/MakeDeps/WinGammaPlatformVC8.java
571 --- a/src/share/tools/MakeDeps/WinGammaPlatformVC8.java Wed Nov 17 22:42:08 2010 -0800
572 +++ b/src/share/tools/MakeDeps/WinGammaPlatformVC8.java Fri Dec 17 13:24:08 2010 +0100
574 addAttr(rv, "UsePrecompiledHeader", "2");
575 // Set /EHsc- option. 0 is cppExceptionHandlingNo
576 addAttr(rv, "ExceptionHandling", "0");
577 + // Parallel compilation
578 + addAttr(rv, "AdditionalOptions", "/MP");
583 diff -r f5603a6e5042 src/share/vm/c1/c1_Compilation.hpp
584 --- a/src/share/vm/c1/c1_Compilation.hpp Wed Nov 17 22:42:08 2010 -0800
585 +++ b/src/share/vm/c1/c1_Compilation.hpp Fri Dec 17 13:24:08 2010 +0100
587 #define BAILOUT(msg) { bailout(msg); return; }
588 #define BAILOUT_(msg, res) { bailout(msg); return res; }
590 -#define CHECK_BAILOUT() { if (bailed_out()) return; }
591 -#define CHECK_BAILOUT_(res) { if (bailed_out()) return res; }
592 +#define CHECK_BAILOUT() { if (((CompilerThread *)Thread::current())->should_bailout()) bailout("Aborted externally"); if (bailed_out()) return; }
593 +#define CHECK_BAILOUT_(res) { if (((CompilerThread *)Thread::current())->should_bailout()) bailout("Aborted externally"); if (bailed_out()) return res; }
596 class InstructionMark: public StackObj {
597 diff -r f5603a6e5042 src/share/vm/c1/c1_LIRGenerator.cpp
598 --- a/src/share/vm/c1/c1_LIRGenerator.cpp Wed Nov 17 22:42:08 2010 -0800
599 +++ b/src/share/vm/c1/c1_LIRGenerator.cpp Fri Dec 17 13:24:08 2010 +0100
600 @@ -2498,7 +2498,7 @@
602 // Load CallSite object from constant pool cache.
603 __ oop2reg(cpcache->constant_encoding(), tmp);
604 - __ load(new LIR_Address(tmp, call_site_offset, T_OBJECT), tmp);
605 + __ load(new LIR_Address(tmp, (int)call_site_offset, T_OBJECT), tmp);
607 // Load target MethodHandle from CallSite object.
608 __ load(new LIR_Address(tmp, java_dyn_CallSite::target_offset_in_bytes(), T_OBJECT), receiver);
609 diff -r f5603a6e5042 src/share/vm/ci/ciEnv.cpp
610 --- a/src/share/vm/ci/ciEnv.cpp Wed Nov 17 22:42:08 2010 -0800
611 +++ b/src/share/vm/ci/ciEnv.cpp Fri Dec 17 13:24:08 2010 +0100
612 @@ -1075,3 +1075,11 @@
613 // If memory is low, we stop compiling methods.
614 record_method_not_compilable("out of memory");
617 +// (tw) Called after class redefinition to clean up possibly invalidated state.
618 +void ciEnv::cleanup_after_redefinition() {
620 + if (_factory != NULL) {
621 + _factory->cleanup_after_redefinition();
624 \ No newline at end of file
625 diff -r f5603a6e5042 src/share/vm/ci/ciEnv.hpp
626 --- a/src/share/vm/ci/ciEnv.hpp Wed Nov 17 22:42:08 2010 -0800
627 +++ b/src/share/vm/ci/ciEnv.hpp Fri Dec 17 13:24:08 2010 +0100
629 void record_failure(const char* reason);
630 void record_method_not_compilable(const char* reason, bool all_tiers = true);
631 void record_out_of_memory_failure();
633 + void cleanup_after_redefinition();
635 diff -r f5603a6e5042 src/share/vm/ci/ciObjectFactory.cpp
636 --- a/src/share/vm/ci/ciObjectFactory.cpp Wed Nov 17 22:42:08 2010 -0800
637 +++ b/src/share/vm/ci/ciObjectFactory.cpp Fri Dec 17 13:24:08 2010 +0100
639 // into the table. We need to recompute our index.
640 index = find(keyHandle(), _ci_objects);
643 + if (is_found_at(index, keyHandle(), _ci_objects)) {
644 + // (tw) Check if this is an error? Can occur when redefining classes.
645 + return _ci_objects->at(index);
647 assert(!is_found_at(index, keyHandle(), _ci_objects), "no double insert");
648 insert(index, new_object, _ci_objects);
651 _unloaded_instances->length(),
652 _unloaded_klasses->length());
655 +// (tw) Resoring the ciObject arrays after class redefinition
656 +void ciObjectFactory::sort_ci_objects(GrowableArray<ciObject*>* objects) {
658 + // Resort the _ci_objects array. The order of two class pointers can be changed during class redefinition.
660 + for (int j = 0; j< objects->length(); j++) {
661 + oop o = objects->at(j)->get_oop();
663 + int cur_last_index = j - 1;
664 + oop cur_last = last;
665 + while (cur_last >= o) {
667 + // Swap the two objects to guarantee ordering
668 + ciObject *tmp = objects->at(cur_last_index);
669 + objects->at_put(cur_last_index, objects->at(cur_last_index + 1));
670 + objects->at_put(cur_last_index + 1, tmp);
672 + // Decrement index to move one step to the left
674 + if (cur_last_index < 0) {
677 + cur_last =objects->at(cur_last_index)->get_oop();
680 + assert(last < o, "out of order");
686 + if (CIObjectFactoryVerify) {
688 + for (int j = 0; j< objects->length(); j++) {
689 + oop o = objects->at(j)->get_oop();
690 + assert(last < o, "out of order");
697 +// (tw) Called after class redefinition to clean up possibly invalidated state.
698 +void ciObjectFactory::cleanup_after_redefinition() {
699 + sort_ci_objects(_ci_objects);
701 \ No newline at end of file
702 diff -r f5603a6e5042 src/share/vm/ci/ciObjectFactory.hpp
703 --- a/src/share/vm/ci/ciObjectFactory.hpp Wed Nov 17 22:42:08 2010 -0800
704 +++ b/src/share/vm/ci/ciObjectFactory.hpp Fri Dec 17 13:24:08 2010 +0100
706 // which ensures that for each oop, at most one ciObject is created.
707 // This invariant allows efficient implementation of ciObject.
708 class ciObjectFactory : public ResourceObj {
710 + friend class ciEnv;
711 + friend class CompileBroker;
714 static volatile bool _initialized;
715 static GrowableArray<ciObject*>* _shared_ci_objects;
718 void print_contents();
723 + static void sort_ci_objects(GrowableArray<ciObject*>* objects);
724 + void cleanup_after_redefinition();
726 diff -r f5603a6e5042 src/share/vm/classfile/classFileParser.cpp
727 --- a/src/share/vm/classfile/classFileParser.cpp Wed Nov 17 22:42:08 2010 -0800
728 +++ b/src/share/vm/classfile/classFileParser.cpp Fri Dec 17 13:24:08 2010 +0100
731 Handle protection_domain,
732 symbolHandle class_name,
733 + KlassHandle old_klass,
735 ClassFileStream* cfs = stream();
736 assert(length > 0, "only called for length>0");
738 interface_index, CHECK_(nullHandle));
739 if (cp->tag_at(interface_index).is_klass()) {
740 interf = KlassHandle(THREAD, cp->resolved_klass_at(interface_index));
741 + if (!old_klass.is_null() && !interf->is_newest_version()) {
742 + interf = KlassHandle(THREAD, interf->newest_version());
745 symbolHandle unresolved_klass (THREAD, cp->klass_name_at(interface_index));
748 klassOop k = SystemDictionary::resolve_super_or_fail(class_name,
749 unresolved_klass, class_loader, protection_domain,
750 false, CHECK_(nullHandle));
751 + if (!old_klass.is_null()) {
752 + k = k->klass_part()->newest_version();
754 interf = KlassHandle(THREAD, k);
756 if (LinkWellKnownClasses) // my super type is well known to me
757 @@ -1805,7 +1812,6 @@
758 // Parse and compress line number table
759 parse_linenumber_table(code_attribute_length, code_length,
760 &linenumber_table, CHECK_(nullHandle));
762 } else if (LoadLocalVariableTables &&
763 cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_local_variable_table()) {
764 // Parse local variable table
765 @@ -2549,7 +2555,7 @@
769 -static void initialize_static_field(fieldDescriptor* fd, TRAPS) {
770 +void ClassFileParser::initialize_static_field(fieldDescriptor* fd, TRAPS) {
771 KlassHandle h_k (THREAD, fd->field_holder());
772 assert(h_k.not_null() && fd->is_static(), "just checking");
773 if (fd->has_initial_value()) {
774 @@ -2746,6 +2752,123 @@
775 (*next_nonstatic_oop_offset_ptr) += (extra * heapOopSize);
778 +// (tw) Finds the super symbols by reading the bytes of the class and returns
779 +// them in a growable array.
780 +void ClassFileParser::findSuperSymbols(symbolHandle name,
781 + Handle class_loader,
782 + Handle protection_domain,
783 + KlassHandle old_klass,
784 + GrowableArray<symbolHandle> &handles,
787 + _cp_patches = NULL;
788 + // So that JVMTI can cache class file in the state before retransformable agents
789 + // have modified it
790 + unsigned char *cached_class_file_bytes = NULL;
792 + ClassFileStream* cfs = stream();
794 + _has_finalizer = _has_empty_finalizer = _has_vanilla_constructor = false;
796 + instanceKlassHandle nullHandle;
798 + // Save the class file name for easier error message printing.
799 + _class_name = name.not_null()? name : vmSymbolHandles::unknown_class_name();
801 + cfs->guarantee_more(8, CHECK); // magic, major, minor
803 + u4 magic = cfs->get_u4_fast();
804 + if (magic != JAVA_CLASSFILE_MAGIC) {
805 + // Invalid class file!
810 + u2 minor_version = cfs->get_u2_fast();
811 + u2 major_version = cfs->get_u2_fast();
813 + // Check version numbers - we check this even with verifier off
814 + if (!is_supported_version(major_version, minor_version)) {
816 + // Unsupported version!
820 + _major_version = major_version;
821 + _minor_version = minor_version;
824 + // Check if verification needs to be relaxed for this class file
825 + // Do not restrict it to jdk1.0 or jdk1.1 to maintain backward compatibility (4982376)
826 + _relax_verify = Verifier::relax_verify_for(class_loader());
827 + _need_verify = false;
830 + constantPoolHandle cp = parse_constant_pool(CHECK);
831 + int cp_size = cp->length();
833 + cfs->guarantee_more(8, CHECK); // flags, this_class, super_class, infs_len
836 + AccessFlags access_flags;
837 + jint flags = cfs->get_u2_fast() & JVM_RECOGNIZED_CLASS_MODIFIERS;
839 + if ((flags & JVM_ACC_INTERFACE) && _major_version < JAVA_6_VERSION) {
840 + // Set abstract bit for old class files for backward compatibility
841 + flags |= JVM_ACC_ABSTRACT;
843 + access_flags.set_flags(flags);
845 + // This class and superclass
846 + instanceKlassHandle super_klass;
847 + u2 this_class_index = cfs->get_u2_fast();
849 + valid_cp_range(this_class_index, cp_size) &&
850 + cp->tag_at(this_class_index).is_unresolved_klass(),
851 + "Invalid this class index %u in constant pool in class file %s",
852 + this_class_index, CHECK);
854 + symbolHandle class_name (THREAD, cp->unresolved_klass_at(this_class_index));
855 + assert(class_name.not_null(), "class_name can't be null");
857 + // Update _class_name which could be null previously to be class_name
858 + _class_name = class_name;
860 + // (tw) DO NOT release all handles when parsing is done
861 + {// HandleMark hm(THREAD);
863 + // Checks if name in class file matches requested name
864 + if (name.not_null() && class_name() != name()) {
868 + u2 super_class_index = cfs->get_u2_fast();
870 + if (super_class_index != 0) {
871 + symbolHandle super_class (THREAD, cp->klass_name_at(super_class_index));
872 + handles.append(super_class);
874 + // (tw) This redefinition must be for the Object class.
878 + u2 itfs_len = cfs->get_u2_fast();
879 + objArrayHandle local_interfaces;
880 + if (itfs_len == 0) {
881 + local_interfaces = objArrayHandle(THREAD, Universe::the_empty_system_obj_array());
883 + local_interfaces = parse_interfaces(cp, itfs_len, class_loader, protection_domain, _class_name, old_klass, CHECK);
886 + for (int i=0; i<local_interfaces->length(); i++) {
887 + oop o = local_interfaces->obj_at(i);
888 + symbolHandle interface_handle (THREAD, ((klassOop)o)->klass_part()->name());
889 + handles.append(interface_handle);
896 // Force MethodHandle.vmentry to be an unmanaged pointer.
897 // There is no way for a classfile to express this, so we must help it.
898 @@ -2819,6 +2942,7 @@
899 instanceKlassHandle ClassFileParser::parseClassFile(symbolHandle name,
901 Handle protection_domain,
902 + KlassHandle old_klass,
903 KlassHandle host_klass,
904 GrowableArray<Handle>* cp_patches,
905 symbolHandle& parsed_name,
906 @@ -2847,10 +2971,13 @@
907 unsigned char* ptr = cfs->buffer();
908 unsigned char* end_ptr = cfs->buffer() + cfs->length();
910 + bool pretend_new_universe = Thread::current()->pretend_new_universe();
911 + Thread::current()->set_pretend_new_universe(false);
912 JvmtiExport::post_class_file_load_hook(name, class_loader, protection_domain,
914 &cached_class_file_bytes,
915 &cached_class_file_length);
916 + Thread::current()->set_pretend_new_universe(pretend_new_universe);
918 if (ptr != cfs->buffer()) {
919 // JVMTI agent has modified class file data.
920 @@ -3001,7 +3128,11 @@
921 // However, make sure it is not an array type.
922 bool is_array = false;
923 if (cp->tag_at(super_class_index).is_klass()) {
924 - super_klass = instanceKlassHandle(THREAD, cp->resolved_klass_at(super_class_index));
925 + klassOop resolved_klass = cp->resolved_klass_at(super_class_index);
926 + if (!old_klass.is_null()) {
927 + resolved_klass = resolved_klass->klass_part()->newest_version();
929 + super_klass = instanceKlassHandle(THREAD, resolved_klass);
931 is_array = super_klass->oop_is_array();
932 } else if (_need_verify) {
933 @@ -3019,7 +3150,7 @@
935 local_interfaces = objArrayHandle(THREAD, Universe::the_empty_system_obj_array());
937 - local_interfaces = parse_interfaces(cp, itfs_len, class_loader, protection_domain, _class_name, CHECK_(nullHandle));
938 + local_interfaces = parse_interfaces(cp, itfs_len, class_loader, protection_domain, _class_name, old_klass, CHECK_(nullHandle));
941 // Fields (offsets are filled in later)
942 @@ -3063,7 +3194,9 @@
947 + if (!old_klass.is_null()) {
948 + k = k->klass_part()->newest_version();
950 KlassHandle kh (THREAD, k);
951 super_klass = instanceKlassHandle(THREAD, kh());
952 if (LinkWellKnownClasses) // my super class is well known to me
953 @@ -3490,6 +3623,19 @@
956 rt = super_klass->reference_type();
958 + // (tw) With class redefinition, it can also happen that special classes are loaded.
959 + if (name() == vmSymbols::java_lang_ref_Reference()) {
961 + } else if (name() == vmSymbols::java_lang_ref_SoftReference()) {
963 + } else if (name() == vmSymbols::java_lang_ref_WeakReference()) {
965 + } else if (name() == vmSymbols::java_lang_ref_FinalReference()) {
967 + } else if (name() == vmSymbols::java_lang_ref_PhantomReference()) {
972 // We can now create the basic klassOop for this klass
973 @@ -3591,7 +3737,7 @@
974 // Do final class setup
975 fill_oop_maps(this_klass, nonstatic_oop_map_count, nonstatic_oop_offsets, nonstatic_oop_counts);
977 - set_precomputed_flags(this_klass);
978 + set_precomputed_flags(this_klass, old_klass);
980 // reinitialize modifiers, using the InnerClasses attribute
981 int computed_modifiers = this_klass->compute_modifier_flags(CHECK_(nullHandle));
982 @@ -3611,6 +3757,10 @@
983 check_illegal_static_method(this_klass, CHECK_(nullHandle));
986 + if (rt == REF_OTHER) {
987 + instanceRefKlass::update_nonstatic_oop_maps(ik);
990 ClassLoadingService::notify_class_loaded(instanceKlass::cast(this_klass()),
991 false /* not shared class */);
993 @@ -3753,7 +3903,7 @@
997 -void ClassFileParser::set_precomputed_flags(instanceKlassHandle k) {
998 +void ClassFileParser::set_precomputed_flags(instanceKlassHandle k, KlassHandle old_klass) {
999 klassOop super = k->super();
1001 // Check if this klass has an empty finalize method (i.e. one with return bytecode only),
1002 @@ -3761,7 +3911,9 @@
1003 if (!_has_empty_finalizer) {
1004 if (_has_finalizer ||
1005 (super != NULL && super->klass_part()->has_finalizer())) {
1006 - k->set_has_finalizer();
1007 + if (old_klass.is_null() || old_klass->has_finalizer()) {
1008 + k->set_has_finalizer();
1013 @@ -3777,7 +3929,7 @@
1015 // Check if this klass supports the java.lang.Cloneable interface
1016 if (SystemDictionary::Cloneable_klass_loaded()) {
1017 - if (k->is_subtype_of(SystemDictionary::Cloneable_klass())) {
1018 + if (k->is_subtype_of(SystemDictionary::Cloneable_klass()) || k->is_subtype_of(SystemDictionary::Cloneable_klass()->klass_part()->newest_version())) {
1019 k->set_is_cloneable();
1022 diff -r f5603a6e5042 src/share/vm/classfile/classFileParser.hpp
1023 --- a/src/share/vm/classfile/classFileParser.hpp Wed Nov 17 22:42:08 2010 -0800
1024 +++ b/src/share/vm/classfile/classFileParser.hpp Fri Dec 17 13:24:08 2010 +0100
1026 Handle class_loader,
1027 Handle protection_domain,
1028 symbolHandle class_name,
1029 + KlassHandle old_klass,
1034 unsigned int nonstatic_oop_map_count,
1035 int* nonstatic_oop_offsets,
1036 unsigned int* nonstatic_oop_counts);
1037 - void set_precomputed_flags(instanceKlassHandle k);
1038 + void set_precomputed_flags(instanceKlassHandle k, KlassHandle old_klass);
1039 objArrayHandle compute_transitive_interfaces(instanceKlassHandle super,
1040 objArrayHandle local_ifs, TRAPS);
1042 @@ -265,21 +266,33 @@
1043 instanceKlassHandle parseClassFile(symbolHandle name,
1044 Handle class_loader,
1045 Handle protection_domain,
1046 + KlassHandle old_klass,
1047 symbolHandle& parsed_name,
1050 KlassHandle no_host_klass;
1051 - return parseClassFile(name, class_loader, protection_domain, no_host_klass, NULL, parsed_name, verify, THREAD);
1052 + return parseClassFile(name, class_loader, protection_domain, old_klass, no_host_klass, NULL, parsed_name, verify, THREAD);
1054 instanceKlassHandle parseClassFile(symbolHandle name,
1055 Handle class_loader,
1056 Handle protection_domain,
1057 + KlassHandle old_klass,
1058 KlassHandle host_klass,
1059 GrowableArray<Handle>* cp_patches,
1060 symbolHandle& parsed_name,
1064 + static void initialize_static_field(fieldDescriptor* fd, TRAPS);
1066 + // (tw) Creates symbol handles for the super class and the interfaces
1067 + void findSuperSymbols(symbolHandle name,
1068 + Handle class_loader,
1069 + Handle protection_domain,
1070 + KlassHandle old_klass,
1071 + GrowableArray<symbolHandle> &handles,
1075 static void check_super_class_access(instanceKlassHandle this_klass, TRAPS);
1076 static void check_super_interface_access(instanceKlassHandle this_klass, TRAPS);
1077 diff -r f5603a6e5042 src/share/vm/classfile/classLoader.cpp
1078 --- a/src/share/vm/classfile/classLoader.cpp Wed Nov 17 22:42:08 2010 -0800
1079 +++ b/src/share/vm/classfile/classLoader.cpp Fri Dec 17 13:24:08 2010 +0100
1081 if (file_handle != -1) {
1082 // read contents into resource array
1083 u1* buffer = NEW_RESOURCE_ARRAY(u1, st.st_size);
1084 - size_t num_read = os::read(file_handle, (char*) buffer, st.st_size);
1085 + size_t num_read = hpi::read(file_handle, (char*) buffer, st.st_size);
1087 hpi::close(file_handle);
1088 // construct ClassFileStream
1090 instanceKlassHandle result = parser.parseClassFile(h_name,
1097 diff -r f5603a6e5042 src/share/vm/classfile/dictionary.cpp
1098 --- a/src/share/vm/classfile/dictionary.cpp Wed Nov 17 22:42:08 2010 -0800
1099 +++ b/src/share/vm/classfile/dictionary.cpp Fri Dec 17 13:24:08 2010 +0100
1103 // RC_TRACE macro has an embedded ResourceMark
1104 - RC_TRACE(0x00000200, ("unload: %s: previous version length=%d",
1105 - ik->external_name(), ik->previous_versions()->length()));
1106 + TRACE_RC4("unload: %s: previous version length=%d",
1107 + ik->external_name(), ik->previous_versions()->length());
1109 for (int i = ik->previous_versions()->length() - 1; i >= 0; i--) {
1110 // check the previous versions array for GC'ed weak refs
1115 - RC_TRACE(0x00000200, ("unload: previous version @%d is alive", i));
1116 + TRACE_RC4("unload: previous version @%d is alive", i);
1117 if (is_alive->do_object_b(pvcp)) {
1122 GrowableArray<jweak>* method_refs = pv_node->prev_EMCP_methods();
1123 if (method_refs != NULL) {
1124 - RC_TRACE(0x00000200, ("unload: previous methods length=%d",
1125 - method_refs->length()));
1126 + TRACE_RC4("unload: previous methods length=%d", method_refs->length());
1127 for (int j = method_refs->length() - 1; j >= 0; j--) {
1128 jweak method_ref = method_refs->at(j);
1129 assert(method_ref != NULL, "weak method ref was unexpectedly cleared");
1130 @@ -203,19 +202,14 @@
1131 JNIHandles::destroy_weak_global(method_ref);
1132 method_refs->remove_at(j);
1134 - // RC_TRACE macro has an embedded ResourceMark
1135 - RC_TRACE(0x00000200,
1136 - ("unload: %s(%s): prev method @%d in version @%d is alive",
1137 - method->name()->as_C_string(),
1138 - method->signature()->as_C_string(), j, i));
1139 + TRACE_RC4("unload: %s(%s): prev method @%d in version @%d is alive", method->name()->as_C_string(),
1140 + method->signature()->as_C_string(), j, i);
1145 assert(ik->previous_versions()->length() == live_count, "sanity check");
1146 - RC_TRACE(0x00000200,
1147 - ("unload: previous version stats: live=%d, GC'ed=%d", live_count,
1149 + TRACE_RC4("unload: previous version stats: live=%d, GC'ed=%d", live_count, gc_count);
1152 // Non-unloadable classes were handled in always_strong_oops_do
1153 @@ -321,6 +315,21 @@
1158 +// (tw) Just the classes from defining class loaders
1159 +void Dictionary::classes_do(ObjectClosure *closure) {
1160 + for (int index = 0; index < table_size(); index++) {
1161 + for (DictionaryEntry* probe = bucket(index);
1163 + probe = probe->next()) {
1164 + klassOop k = probe->klass();
1165 + if (probe->loader() == instanceKlass::cast(k)->class_loader()) {
1166 + closure->do_object(k);
1172 // Added for initialize_itable_for_klass to handle exceptions
1173 // Just the classes from defining class loaders
1174 void Dictionary::classes_do(void f(klassOop, TRAPS), TRAPS) {
1175 @@ -428,6 +437,33 @@
1176 add_entry(index, entry);
1179 +// (tw) Updates the klass entry to point to the new klassOop. Necessary only for class redefinition.
1180 +bool Dictionary::update_klass(int index, unsigned int hash, symbolHandle name, Handle loader, KlassHandle k, KlassHandle old_class) {
1182 + // There are several entries for the same class in the dictionary: One extra entry for each parent classloader of the classloader of the class.
1183 + bool found = false;
1184 + for (int index = 0; index < table_size(); index++) {
1185 + for (DictionaryEntry* entry = bucket(index); entry != NULL; entry = entry->next()) {
1186 + if (entry->klass() == old_class()) {
1187 + entry->set_literal(k());
1196 +// (tw) Undo previous updates to the system dictionary
1197 +void Dictionary::rollback_redefinition() {
1198 + for (int index = 0; index < table_size(); index++) {
1199 + for (DictionaryEntry* entry = bucket(index); entry != NULL; entry = entry->next()) {
1200 + if (entry->klass()->klass_part()->is_redefining()) {
1201 + entry->set_literal(entry->klass()->klass_part()->old_version());
1207 // This routine does not lock the system dictionary.
1209 @@ -455,12 +491,21 @@
1213 +klassOop Dictionary::intercept_for_version(klassOop k) {
1214 + if (k == NULL) return k;
1216 + if (k->klass_part()->is_redefining() && !Thread::current()->pretend_new_universe()) {
1217 + return k->klass_part()->old_version();
1223 klassOop Dictionary::find(int index, unsigned int hash, symbolHandle name,
1224 Handle loader, Handle protection_domain, TRAPS) {
1225 DictionaryEntry* entry = get_entry(index, hash, name, loader);
1226 if (entry != NULL && entry->is_valid_protection_domain(protection_domain)) {
1227 - return entry->klass();
1228 + return intercept_for_version(entry->klass());
1233 assert (index == index_for(name, loader), "incorrect index?");
1235 DictionaryEntry* entry = get_entry(index, hash, name, loader);
1236 - return (entry != NULL) ? entry->klass() : (klassOop)NULL;
1237 + return intercept_for_version((entry != NULL) ? entry->klass() : (klassOop)NULL);
1242 assert (index == index_for(name, Handle()), "incorrect index?");
1244 DictionaryEntry* entry = get_entry(index, hash, name, Handle());
1245 - return (entry != NULL) ? entry->klass() : (klassOop)NULL;
1246 + return intercept_for_version((entry != NULL) ? entry->klass() : (klassOop)NULL);
1250 diff -r f5603a6e5042 src/share/vm/classfile/dictionary.hpp
1251 --- a/src/share/vm/classfile/dictionary.hpp Wed Nov 17 22:42:08 2010 -0800
1252 +++ b/src/share/vm/classfile/dictionary.hpp Fri Dec 17 13:24:08 2010 +0100
1255 void add_klass(symbolHandle class_name, Handle class_loader,KlassHandle obj);
1257 + bool update_klass(int index, unsigned int hash, symbolHandle name, Handle loader, KlassHandle k, KlassHandle old_class);
1259 + void rollback_redefinition();
1261 klassOop find_class(int index, unsigned int hash,
1262 symbolHandle name, Handle loader);
1265 void classes_do(void f(klassOop, TRAPS), TRAPS);
1266 void classes_do(void f(klassOop, oop));
1267 void classes_do(void f(klassOop, oop, TRAPS), TRAPS);
1268 + void classes_do(ObjectClosure *closure);
1270 void methods_do(void f(methodOop));
1273 bool do_unloading(BoolObjectClosure* is_alive);
1275 // Protection domains
1276 + static klassOop intercept_for_version(klassOop k);
1277 klassOop find(int index, unsigned int hash, symbolHandle name,
1278 Handle loader, Handle protection_domain, TRAPS);
1279 bool is_valid_protection_domain(int index, unsigned int hash,
1280 diff -r f5603a6e5042 src/share/vm/classfile/javaClasses.cpp
1281 --- a/src/share/vm/classfile/javaClasses.cpp Wed Nov 17 22:42:08 2010 -0800
1282 +++ b/src/share/vm/classfile/javaClasses.cpp Fri Dec 17 13:24:08 2010 +0100
1283 @@ -1537,7 +1537,7 @@
1284 klassOop klass = SystemDictionary::reflect_Method_klass();
1285 // This class is eagerly initialized during VM initialization, since we keep a refence
1286 // to one of the methods
1287 - assert(instanceKlass::cast(klass)->is_initialized(), "must be initialized");
1288 + assert(instanceKlass::cast(klass)->is_initialized() || klass->klass_part()->old_version() != NULL, "must be initialized");
1289 return instanceKlass::cast(klass)->allocate_instance_handle(CHECK_NH);
1292 diff -r f5603a6e5042 src/share/vm/classfile/javaClasses.hpp
1293 --- a/src/share/vm/classfile/javaClasses.hpp Wed Nov 17 22:42:08 2010 -0800
1294 +++ b/src/share/vm/classfile/javaClasses.hpp Fri Dec 17 13:24:08 2010 +0100
1297 class java_lang_Class : AllStatic {
1298 friend class VMStructs;
1299 + friend class VM_RedefineClasses;
1301 // The fake offsets are added by the class loader when java.lang.Class is loaded
1303 diff -r f5603a6e5042 src/share/vm/classfile/loaderConstraints.cpp
1304 --- a/src/share/vm/classfile/loaderConstraints.cpp Wed Nov 17 22:42:08 2010 -0800
1305 +++ b/src/share/vm/classfile/loaderConstraints.cpp Fri Dec 17 13:24:08 2010 +0100
1308 // We found the class in the system dictionary, so we should
1309 // make sure that the klassOop matches what we already have.
1310 - guarantee(k == probe->klass(), "klass should be in dictionary");
1311 + guarantee(k == probe->klass()->klass_part()->newest_version(), "klass should be in dictionary");
1313 // If we don't find the class in the system dictionary, it
1314 // has to be in the placeholders table.
1315 diff -r f5603a6e5042 src/share/vm/classfile/loaderConstraints.hpp
1316 --- a/src/share/vm/classfile/loaderConstraints.hpp Wed Nov 17 22:42:08 2010 -0800
1317 +++ b/src/share/vm/classfile/loaderConstraints.hpp Fri Dec 17 13:24:08 2010 +0100
1320 klassOop klass() { return (klassOop)literal(); }
1321 klassOop* klass_addr() { return (klassOop*)literal_addr(); }
1322 - void set_klass(klassOop k) { set_literal(k); }
1323 + void set_klass(klassOop k) { set_literal(k); assert(k == NULL || !k->klass_part()->is_redefining(), "just checking"); }
1325 LoaderConstraintEntry* next() {
1326 return (LoaderConstraintEntry*)HashtableEntry::next();
1327 diff -r f5603a6e5042 src/share/vm/classfile/systemDictionary.cpp
1328 --- a/src/share/vm/classfile/systemDictionary.cpp Wed Nov 17 22:42:08 2010 -0800
1329 +++ b/src/share/vm/classfile/systemDictionary.cpp Fri Dec 17 13:24:08 2010 +0100
1331 // can return a null klass
1332 klass = handle_resolution_exception(class_name, class_loader, protection_domain, throw_error, k_h, THREAD);
1334 + assert(klass == NULL || klass->klass_part()->is_newest_version() || klass->klass_part()->newest_version()->klass_part()->is_redefining(), "must be");
1339 // Forwards to resolve_instance_class_or_null
1341 klassOop SystemDictionary::resolve_or_null(symbolHandle class_name, Handle class_loader, Handle protection_domain, TRAPS) {
1342 - assert(!THREAD->is_Compiler_thread(), "Can not load classes with the Compiler thread");
1343 + // (tw) Check if this relaxing of the condition is correct? Test case hs203t004 failing otherwise.
1344 + assert(!THREAD->is_Compiler_thread() || JvmtiThreadState::state_for(JavaThread::current())->get_class_being_redefined() != NULL, "Can not load classes with the Compiler thread");
1345 if (FieldType::is_array(class_name())) {
1346 return resolve_array_class_or_null(class_name, class_loader, protection_domain, CHECK_NULL);
1349 instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name,
1356 @@ -1036,8 +1039,15 @@
1357 Handle protection_domain,
1358 ClassFileStream* st,
1360 + KlassHandle old_class,
1363 + bool redefine_classes_locked = false;
1364 + if (!Thread::current()->redefine_classes_mutex()->owned_by_self()) {
1365 + Thread::current()->redefine_classes_mutex()->lock();
1366 + redefine_classes_locked = true;
1369 // Classloaders that support parallelism, e.g. bootstrap classloader,
1370 // or all classloaders with UnsyncloadClass do not acquire lock here
1371 bool DoObjectLock = true;
1372 @@ -1065,9 +1075,14 @@
1373 instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name,
1380 + if (!old_class.is_null() && !k.is_null()) {
1381 + k->set_redefining(true);
1382 + k->set_old_version(old_class());
1385 const char* pkg = "java/";
1386 if (!HAS_PENDING_EXCEPTION &&
1387 @@ -1103,13 +1118,18 @@
1388 // Add class just loaded
1389 // If a class loader supports parallel classloading handle parallel define requests
1390 // find_or_define_instance_class may return a different instanceKlass
1391 - if (is_parallelCapable(class_loader)) {
1392 + // (tw) TODO: for class redefinition the parallel version does not work, check if this is a problem?
1393 + if (is_parallelCapable(class_loader) && old_class.is_null()) {
1394 k = find_or_define_instance_class(class_name, class_loader, k, THREAD);
1396 - define_instance_class(k, THREAD);
1397 + define_instance_class(k, old_class, THREAD);
1401 + if (redefine_classes_locked) {
1402 + Thread::current()->redefine_classes_mutex()->unlock();
1405 // If parsing the class file or define_instance_class failed, we
1406 // need to remove the placeholder added on our behalf. But we
1407 // must make sure parsed_name is valid first (it won't be if we had
1408 @@ -1138,7 +1158,7 @@
1409 MutexLocker mu(SystemDictionary_lock, THREAD);
1411 oop check = find_class_or_placeholder(parsed_name, class_loader);
1412 - assert(check == k(), "should be present in the dictionary");
1413 + assert((check == k() && !k->is_redefining()) || (k->is_redefining() && check == k->old_version()), "should be present in the dictionary");
1415 oop check2 = find_class_or_placeholder(h_name, h_loader);
1416 assert(check == check2, "name inconsistancy in SystemDictionary");
1417 @@ -1424,7 +1444,11 @@
1421 -void SystemDictionary::define_instance_class(instanceKlassHandle k, TRAPS) {
1422 +void SystemDictionary::rollback_redefinition() {
1423 + dictionary()->rollback_redefinition();
1426 +void SystemDictionary::define_instance_class(instanceKlassHandle k, KlassHandle old_class, TRAPS) {
1428 Handle class_loader_h(THREAD, k->class_loader());
1430 @@ -1451,13 +1475,23 @@
1431 symbolHandle name_h(THREAD, k->name());
1432 unsigned int d_hash = dictionary()->compute_hash(name_h, class_loader_h);
1433 int d_index = dictionary()->hash_to_index(d_hash);
1434 - check_constraints(d_index, d_hash, k, class_loader_h, true, CHECK);
1436 + // (tw) Update version of the klassOop in the system dictionary
1437 + // TODO: Check for thread safety!
1438 + if (!old_class.is_null()) {
1439 + bool ok = dictionary()->update_klass(d_index, d_hash, name_h, class_loader_h, k, old_class);
1440 + assert (ok, "must have found old class and updated!");
1442 + check_constraints(d_index, d_hash, k, class_loader_h, old_class.is_null(), CHECK);
1444 + if(!old_class.is_null() && TraceRedefineClasses >= 3){ tty->print_cr("Class has been updated!"); }
1446 // Register class just loaded with class loader (placed in Vector)
1447 // Note we do this before updating the dictionary, as this can
1448 // fail with an OutOfMemoryError (if it does, we will *not* put this
1449 // class in the dictionary and will not update the class hierarchy).
1450 - if (k->class_loader() != NULL) {
1451 + // (tw) Only register if not redefining a class.
1452 + if (k->class_loader() != NULL && old_class.is_null()) {
1453 methodHandle m(THREAD, Universe::loader_addClass_method());
1454 JavaValue result(T_VOID);
1455 JavaCallArguments args(class_loader_h);
1456 @@ -1483,8 +1517,9 @@
1458 k->eager_initialize(THREAD);
1460 + // (tw) Only notify jvmti if not redefining a class.
1462 - if (JvmtiExport::should_post_class_load()) {
1463 + if (JvmtiExport::should_post_class_load() && old_class.is_null()) {
1464 assert(THREAD->is_Java_thread(), "thread->is_Java_thread()");
1465 JvmtiExport::post_class_load((JavaThread *) THREAD, k());
1467 @@ -1558,7 +1593,7 @@
1471 - define_instance_class(k, THREAD);
1472 + define_instance_class(k, KlassHandle(), THREAD);
1474 Handle linkage_exception = Handle(); // null handle
1476 @@ -1698,6 +1733,14 @@
1477 Universe::flush_dependents_on(k);
1480 +// (tw) Remove from hierarchy - Undo add_to_hierarchy.
1481 +void SystemDictionary::remove_from_hierarchy(instanceKlassHandle k) {
1482 + assert(k.not_null(), "just checking");
1484 + k->remove_from_sibling_list();
1486 + // TODO: Remove from interfaces.
1489 // ----------------------------------------------------------------------------
1491 @@ -1778,10 +1821,8 @@
1495 -void SystemDictionary::preloaded_oops_do(OopClosure* f) {
1496 - f->do_oop((oop*) &wk_klass_name_limits[0]);
1497 - f->do_oop((oop*) &wk_klass_name_limits[1]);
1499 +// (tw) Iterate over all pre-loaded classes in the dictionary.
1500 +void SystemDictionary::preloaded_classes_do(OopClosure *f) {
1501 for (int k = (int)FIRST_WKID; k < (int)WKID_LIMIT; k++) {
1502 f->do_oop((oop*) &_well_known_klasses[k]);
1504 @@ -1795,6 +1836,26 @@
1508 + // TODO: Check if we need to call FilterFieldsMap
1511 +void SystemDictionary::preloaded_oops_do(OopClosure* f) {
1512 + f->do_oop((oop*) &wk_klass_name_limits[0]);
1513 + f->do_oop((oop*) &wk_klass_name_limits[1]);
1515 + for (int k = (int)FIRST_WKID; k < (int)WKID_LIMIT; k++) {
1516 + f->do_oop((oop*) &_well_known_klasses[k]);
1520 + for (int i = 0; i < T_VOID+1; i++) {
1521 + if (_box_klasses[i] != NULL) {
1522 + assert(i >= T_BOOLEAN, "checking");
1523 + f->do_oop((oop*) &_box_klasses[i]);
1528 // The basic type mirrors would have already been processed in
1529 // Universe::oops_do(), via a call to shared_oops_do(), so should
1530 // not be processed again.
1531 @@ -1813,6 +1874,11 @@
1532 dictionary()->classes_do(f);
1535 +// (tw) Iterate over all classes in the dictionary.
1536 +void SystemDictionary::classes_do(ObjectClosure *closure) {
1537 + dictionary()->classes_do(closure);
1540 // Added for initialize_itable_for_klass
1541 // Just the classes from defining class loaders
1542 // Don't iterate over placeholders
1543 @@ -1962,7 +2028,9 @@
1545 // Preload ref klasses and set reference types
1546 instanceKlass::cast(WK_KLASS(Reference_klass))->set_reference_type(REF_OTHER);
1547 - instanceRefKlass::update_nonstatic_oop_maps(WK_KLASS(Reference_klass));
1549 + // (tw) This is now done in parseClassFile in order to support class redefinition
1550 + // instanceRefKlass::update_nonstatic_oop_maps(WK_KLASS(Reference_klass));
1552 initialize_wk_klasses_through(WK_KLASS_ENUM_NAME(PhantomReference_klass), scan, CHECK);
1553 instanceKlass::cast(WK_KLASS(SoftReference_klass))->set_reference_type(REF_SOFT);
1554 @@ -2064,7 +2132,11 @@
1555 // also holds array classes
1557 assert(check->klass_part()->oop_is_instance(), "noninstance in systemdictionary");
1558 - if ((defining == true) || (k() != check)) {
1559 + if ((defining == true) && ((k() != check) && k->old_version() != check)) {
1560 + ResourceMark rm(Thread::current());
1561 + tty->print_cr("(%d / %d) (%s/%s)", k->revision_number(), check->klass_part()->revision_number(), k->name()->as_C_string(), check->klass_part()->name()->as_C_string());
1564 linkage_error = "loader (instance of %s): attempted duplicate class "
1565 "definition for name: \"%s\"";
1567 @@ -2718,8 +2790,9 @@
1568 if (probe == NULL) {
1569 probe = SystemDictionary::find_shared_class(class_name);
1571 + // (tw) Relaxed assertion to allow different class versions. Also allow redefining classes lie around (because of rollback).
1572 guarantee(probe != NULL &&
1573 - (!probe->is_klass() || probe == obj()),
1574 + (!probe->is_klass() || (!((klassOop)(obj()))->klass_part()->is_redefining()) || ((klassOop)probe)->klass_part()->is_same_or_older_version((klassOop)(obj()))) || ((klassOop)(obj()))->klass_part()->is_redefining(),
1575 "Loaded klasses should be in SystemDictionary");
1578 diff -r f5603a6e5042 src/share/vm/classfile/systemDictionary.hpp
1579 --- a/src/share/vm/classfile/systemDictionary.hpp Wed Nov 17 22:42:08 2010 -0800
1580 +++ b/src/share/vm/classfile/systemDictionary.hpp Fri Dec 17 13:24:08 2010 +0100
1582 // Resolve from stream (called by jni_DefineClass and JVM_DefineClass)
1583 static klassOop resolve_from_stream(symbolHandle class_name, Handle class_loader,
1584 Handle protection_domain,
1585 - ClassFileStream* st, bool verify, TRAPS);
1586 + ClassFileStream* st, bool verify, KlassHandle old_class, TRAPS);
1588 // Lookup an already loaded class. If not found NULL is returned.
1589 static klassOop find(symbolHandle class_name, Handle class_loader, Handle protection_domain, TRAPS);
1591 // Iterate over all klasses in dictionary
1592 // Just the classes from defining class loaders
1593 static void classes_do(void f(klassOop));
1594 + static void classes_do(ObjectClosure *closure);
1595 + static void preloaded_classes_do(OopClosure *closure);
1596 // Added for initialize_itable_for_klass to handle exceptions
1597 static void classes_do(void f(klassOop, TRAPS), TRAPS);
1598 // All classes, and their class loaders
1600 initialize_wk_klasses_until((WKID) limit, start_id, THREAD);
1603 + static void rollback_redefinition();
1606 #define WK_KLASS_DECLARE(name, ignore_symbol, option) \
1607 static klassOop name() { return check_klass_##option(_well_known_klasses[WK_KLASS_ENUM_NAME(name)]); }
1609 // after waiting, but before reentering SystemDictionary_lock
1610 // to preserve lock order semantics.
1611 static void double_lock_wait(Handle lockObject, TRAPS);
1612 - static void define_instance_class(instanceKlassHandle k, TRAPS);
1613 + static void define_instance_class(instanceKlassHandle k, KlassHandle old_class, TRAPS);
1614 static instanceKlassHandle find_or_define_instance_class(symbolHandle class_name,
1615 Handle class_loader,
1616 instanceKlassHandle k, TRAPS);
1617 @@ -595,6 +599,11 @@
1618 // Setup link to hierarchy
1619 static void add_to_hierarchy(instanceKlassHandle k, TRAPS);
1623 + // Remove link to hierarchy
1624 + static void remove_from_hierarchy(instanceKlassHandle k);
1627 // We pass in the hashtable index so we can calculate it outside of
1628 // the SystemDictionary_lock.
1629 diff -r f5603a6e5042 src/share/vm/classfile/verifier.cpp
1630 --- a/src/share/vm/classfile/verifier.cpp Wed Nov 17 22:42:08 2010 -0800
1631 +++ b/src/share/vm/classfile/verifier.cpp Fri Dec 17 13:24:08 2010 +0100
1633 return !need_verify;
1636 -bool Verifier::verify(instanceKlassHandle klass, Verifier::Mode mode, bool should_verify_class, TRAPS) {
1637 +bool Verifier::verify(instanceKlassHandle klass, Verifier::Mode mode, bool should_verify_class, bool may_use_old_verifier, TRAPS) {
1638 ResourceMark rm(THREAD);
1642 split_verifier.verify_class(THREAD);
1643 exception_name = split_verifier.result();
1644 if (klass->major_version() < NOFAILOVER_MAJOR_VERSION &&
1645 - FailOverToOldVerifier && !HAS_PENDING_EXCEPTION &&
1646 + FailOverToOldVerifier && may_use_old_verifier && !HAS_PENDING_EXCEPTION &&
1647 (exception_name == vmSymbols::java_lang_VerifyError() ||
1648 exception_name == vmSymbols::java_lang_ClassFormatError())) {
1649 if (TraceClassInitialization) {
1651 "Fail over class verification to old verifier for: %s", klassName);
1653 + assert(may_use_old_verifier, "");
1654 exception_name = inference_verify(
1655 klass, message_buffer, message_buffer_len, THREAD);
1658 + assert(may_use_old_verifier, "");
1659 exception_name = inference_verify(
1660 klass, message_buffer, message_buffer_len, THREAD);
1664 tty->print_cr("End class verification for: %s", klassName);
1666 + } else if (TraceClassInitialization) {
1667 + // (tw) Output not verified classes
1668 + tty->print_cr("Class %s was not verified", klassName);
1671 if (HAS_PENDING_EXCEPTION) {
1673 // NOTE: this is called too early in the bootstrapping process to be
1674 // guarded by Universe::is_gte_jdk14x_version()/UseNewReflection.
1675 (refl_magic_klass == NULL ||
1676 - !klass->is_subtype_of(refl_magic_klass) ||
1677 + !(klass->is_subtype_of(refl_magic_klass) || klass->is_subtype_of(refl_magic_klass->klass_part()->newest_version())) ||
1678 VerifyReflectionBytecodes)
1682 ClassVerifier::ClassVerifier(
1683 instanceKlassHandle klass, char* msg, size_t msg_len, TRAPS)
1684 : _thread(THREAD), _exception_type(symbolHandle()), _message(msg),
1685 - _message_buffer_len(msg_len), _klass(klass) {
1686 + _message_buffer_len(msg_len), _klass(klass->newest_version()), _klass_to_verify(klass) {
1687 _this_type = VerificationType::reference_type(klass->name());
1691 _klass->external_name());
1694 - objArrayHandle methods(THREAD, _klass->methods());
1695 + objArrayHandle methods(THREAD, _klass_to_verify->methods());
1696 int num_methods = methods->length();
1698 for (int index = 0; index < num_methods; index++) {
1699 @@ -2043,7 +2048,10 @@
1700 VerificationType stack_object_type =
1701 current_frame->pop_stack(ref_class_type, CHECK_VERIFY(this));
1702 if (current_type() != stack_object_type) {
1703 - assert(cp->cache() == NULL, "not rewritten yet");
1705 + // (tw) TODO: Check if relaxing the following assertion is correct. For class redefinition we might call the verifier twice.
1706 + //assert(cp->cache() == NULL, "not rewritten yet");
1708 symbolHandle ref_class_name = symbolHandle(THREAD,
1709 cp->klass_name_at(cp->klass_ref_index_at(index)));
1710 // See the comments in verify_field_instructions() for
1711 diff -r f5603a6e5042 src/share/vm/classfile/verifier.hpp
1712 --- a/src/share/vm/classfile/verifier.hpp Wed Nov 17 22:42:08 2010 -0800
1713 +++ b/src/share/vm/classfile/verifier.hpp Fri Dec 17 13:24:08 2010 +0100
1715 * Otherwise, no exception is thrown and the return indicates the
1718 - static bool verify(instanceKlassHandle klass, Mode mode, bool should_verify_class, TRAPS);
1719 + static bool verify(instanceKlassHandle klass, Mode mode, bool should_verify_class, bool may_use_old_verifier, TRAPS);
1721 // Return false if the class is loaded by the bootstrap loader,
1722 // or if defineClass was called requesting skipping verification
1725 size_t _message_buffer_len;
1728 void verify_method(methodHandle method, TRAPS);
1731 char* generate_code_data(methodHandle m, u4 code_length, TRAPS);
1732 void verify_exception_handler_table(u4 code_length, char* code_data, int& min, int& max, TRAPS);
1733 void verify_local_variable_table(u4 code_length, char* code_data, TRAPS);
1736 bool name_in_supers(symbolOop ref_name, instanceKlassHandle current);
1738 + instanceKlassHandle _klass_to_verify;
1739 instanceKlassHandle _klass; // the class being verified
1740 methodHandle _method; // current method being verified
1741 VerificationType _this_type; // the verification type of the current class
1742 diff -r f5603a6e5042 src/share/vm/classfile/vmSymbols.hpp
1743 --- a/src/share/vm/classfile/vmSymbols.hpp Wed Nov 17 22:42:08 2010 -0800
1744 +++ b/src/share/vm/classfile/vmSymbols.hpp Fri Dec 17 13:24:08 2010 +0100
1746 template(erasedType_name, "erasedType") \
1747 template(genericInvoker_name, "genericInvoker") \
1748 template(append_name, "append") \
1749 + /* mutator in case of class redefinition */ \
1750 + template(static_transformer_name, "$staticTransformer") \
1751 + template(transformer_name, "$transformer") \
1753 /* non-intrinsic name/signature pairs: */ \
1754 template(register_method_name, "register") \
1755 diff -r f5603a6e5042 src/share/vm/code/nmethod.cpp
1756 --- a/src/share/vm/code/nmethod.cpp Wed Nov 17 22:42:08 2010 -0800
1757 +++ b/src/share/vm/code/nmethod.cpp Fri Dec 17 13:24:08 2010 +0100
1758 @@ -2055,15 +2055,14 @@
1759 methodOop method = deps.method_argument(0);
1760 for (int j = 0; j < dependee_methods->length(); j++) {
1761 if ((methodOop) dependee_methods->obj_at(j) == method) {
1762 - // RC_TRACE macro has an embedded ResourceMark
1763 - RC_TRACE(0x01000000,
1764 - ("Found evol dependency of nmethod %s.%s(%s) compile_id=%d on method %s.%s(%s)",
1765 + ResourceMark rm(Thread::current());
1766 + TRACE_RC3("Found evol dependency of nmethod %s.%s(%s) compile_id=%d on method %s.%s(%s)",
1767 _method->method_holder()->klass_part()->external_name(),
1768 _method->name()->as_C_string(),
1769 _method->signature()->as_C_string(), compile_id(),
1770 method->method_holder()->klass_part()->external_name(),
1771 method->name()->as_C_string(),
1772 - method->signature()->as_C_string()));
1773 + method->signature()->as_C_string());
1774 if (TraceDependencies || LogCompilation)
1775 deps.log_dependency(dependee);
1777 diff -r f5603a6e5042 src/share/vm/compiler/compileBroker.cpp
1778 --- a/src/share/vm/compiler/compileBroker.cpp Wed Nov 17 22:42:08 2010 -0800
1779 +++ b/src/share/vm/compiler/compileBroker.cpp Fri Dec 17 13:24:08 2010 +0100
1780 @@ -1027,6 +1027,7 @@
1783 // RedefineClasses() has replaced this method; just return
1784 + // (tw) This is important for the new version of hotswapping: Old code will only execute properly in the interpreter!
1785 if (method->is_old()) {
1788 @@ -1352,6 +1353,8 @@
1790 // Never compile a method if breakpoints are present in it
1791 if (method()->number_of_breakpoints() == 0) {
1792 + thread->compilation_mutex()->lock();
1793 + thread->set_should_bailout(false);
1794 // Compile the method.
1795 if ((UseCompiler || AlwaysCompileLoopMethods) && CompileBroker::should_compile_new_jobs()) {
1797 @@ -1375,6 +1378,7 @@
1798 // After compilation is disabled, remove remaining methods from queue
1799 method->clear_queued_for_compilation();
1801 + thread->compilation_mutex()->unlock();
1805 @@ -1535,7 +1539,11 @@
1806 //assert(false, "compiler should always document failure");
1807 // The compiler elected, without comment, not to register a result.
1808 // Do not attempt further compilations of this method.
1809 - ci_env.record_method_not_compilable("compile failed");
1810 + if (((CompilerThread *)Thread::current())->should_bailout()) {
1811 + ci_env.record_failure("compile externally aborted");
1813 + ci_env.record_method_not_compilable("compile failed");
1817 if (ci_env.failing()) {
1818 @@ -1882,3 +1890,15 @@
1823 +// (tw) Clean up compiler interface after a class redefinition step
1824 +void CompileBroker::cleanup_after_redefinition() {
1825 + int num_threads = _method_threads->length();
1827 + ciObjectFactory::sort_ci_objects(ciObjectFactory::_shared_ci_objects);
1828 + for (int i=0; i<num_threads; i++) {
1829 + if (_method_threads->at(i)->env() != NULL && _method_threads->at(i)->env() != (ciEnv *)badAddress) {
1830 + _method_threads->at(i)->env()->cleanup_after_redefinition();
1834 \ No newline at end of file
1835 diff -r f5603a6e5042 src/share/vm/compiler/compileBroker.hpp
1836 --- a/src/share/vm/compiler/compileBroker.hpp Wed Nov 17 22:42:08 2010 -0800
1837 +++ b/src/share/vm/compiler/compileBroker.hpp Fri Dec 17 13:24:08 2010 +0100
1839 static void print_last_compile();
1841 static void print_compiler_threads_on(outputStream* st);
1843 + static void cleanup_after_redefinition();
1845 diff -r f5603a6e5042 src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
1846 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Wed Nov 17 22:42:08 2010 -0800
1847 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp Fri Dec 17 13:24:08 2010 +0100
1848 @@ -140,6 +140,13 @@
1853 +HeapWord* CompactibleFreeListSpace::forward_compact_top(size_t size,
1854 + CompactPoint* cp, HeapWord* compact_top) {
1855 + ShouldNotReachHere();
1859 // Like CompactibleSpace forward() but always calls cross_threshold() to
1860 // update the block offset table. Removed initialize_threshold call because
1861 // CFLS does not use a block offset array for contiguous spaces.
1862 diff -r f5603a6e5042 src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp
1863 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp Wed Nov 17 22:42:08 2010 -0800
1864 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp Fri Dec 17 13:24:08 2010 +0100
1867 // Support for compacting cms
1868 HeapWord* cross_threshold(HeapWord* start, HeapWord* end);
1869 + HeapWord* forward_compact_top(size_t size, CompactPoint* cp, HeapWord* compact_top);
1870 HeapWord* forward(oop q, size_t size, CompactPoint* cp, HeapWord* compact_top);
1872 // Initialization helpers.
1873 diff -r f5603a6e5042 src/share/vm/gc_implementation/includeDB_gc_g1
1874 --- a/src/share/vm/gc_implementation/includeDB_gc_g1 Wed Nov 17 22:42:08 2010 -0800
1875 +++ b/src/share/vm/gc_implementation/includeDB_gc_g1 Fri Dec 17 13:24:08 2010 +0100
1877 ptrQueue.hpp allocation.hpp
1878 ptrQueue.hpp sizes.hpp
1880 -ptrQueue.inline.hpp ptrQueue.hpp
1882 satbQueue.cpp allocation.inline.hpp
1883 satbQueue.cpp mutexLocker.hpp
1884 satbQueue.cpp satbQueue.hpp
1885 diff -r f5603a6e5042 src/share/vm/gc_implementation/shared/markSweep.cpp
1886 --- a/src/share/vm/gc_implementation/shared/markSweep.cpp Wed Nov 17 22:42:08 2010 -0800
1887 +++ b/src/share/vm/gc_implementation/shared/markSweep.cpp Fri Dec 17 13:24:08 2010 +0100
1889 #include "incls/_precompiled.incl"
1890 #include "incls/_markSweep.cpp.incl"
1892 +GrowableArray<oop>* MarkSweep::_rescued_oops = NULL;
1894 Stack<oop> MarkSweep::_marking_stack;
1895 Stack<DataLayout*> MarkSweep::_revisit_mdo_stack;
1896 Stack<Klass*> MarkSweep::_revisit_klass_stack;
1897 @@ -345,3 +347,86 @@
1902 +// (tw) Copy the rescued objects to their destination address after compaction.
1903 +void MarkSweep::copy_rescued_objects_back() {
1905 + if (_rescued_oops != NULL) {
1907 + for (int i=0; i<_rescued_oops->length(); i++) {
1908 + oop rescued_obj = _rescued_oops->at(i);
1910 + int size = rescued_obj->size();
1911 + oop new_obj = rescued_obj->forwardee();
1913 + if (rescued_obj->blueprint()->new_version() != NULL) {
1914 + MarkSweep::update_fields(rescued_obj, new_obj);
1916 + Copy::aligned_disjoint_words((HeapWord*)rescued_obj, (HeapWord*)new_obj, size);
1919 + FREE_RESOURCE_ARRAY(HeapWord, rescued_obj, size);
1921 + new_obj->init_mark();
1922 + assert(new_obj->is_oop(), "must be a valid oop");
1924 + _rescued_oops->clear();
1925 + _rescued_oops = NULL;
1929 +// (tw) Update instances of a class whose fields changed.
1930 +void MarkSweep::update_fields(oop q, oop new_location) {
1932 + assert(q->blueprint()->new_version() != NULL, "class of old object must have new version");
1934 + klassOop old_klass_oop = q->klass();
1935 + klassOop new_klass_oop = q->blueprint()->new_version();
1937 + instanceKlass *old_klass = instanceKlass::cast(old_klass_oop);
1938 + instanceKlass *new_klass = instanceKlass::cast(new_klass_oop);
1940 + int size = q->size_given_klass(old_klass);
1941 + int new_size = q->size_given_klass(new_klass);
1945 + if (new_klass_oop->klass_part()->is_copying_backwards()) {
1946 + if (((HeapWord *)q >= (HeapWord *)new_location && (HeapWord *)q < (HeapWord *)new_location + new_size) ||
1947 + ((HeapWord *)new_location >= (HeapWord *)q && (HeapWord *)new_location < (HeapWord *)q + size)) {
1948 + tmp_obj = (oop)resource_allocate_bytes(size * HeapWordSize);
1949 + Copy::aligned_disjoint_words((HeapWord*)q, (HeapWord*)tmp_obj, size);
1953 + int *cur = new_klass_oop->klass_part()->update_information();
1955 + tmp_obj->set_klass_no_check(new_klass_oop);
1957 + if (cur == NULL) {
1958 + assert(size == new_size, "just checking");
1959 + Copy::conjoint_words(((HeapWord *)tmp_obj), ((HeapWord *)new_location), size);
1961 + int destOffset = 0;
1962 + while (*cur != 0) {
1966 + int offset = *cur;
1967 + Copy::conjoint_jbytes(((char *)tmp_obj) + offset, ((char *)new_location) + destOffset, size);
1968 + destOffset += size;
1971 + assert(*cur < 0, "");
1973 + Copy::fill_to_bytes(((char*)new_location) + destOffset, skip, 0);
1974 + destOffset += skip;
1980 + if (tmp_obj != q) {
1981 + FREE_RESOURCE_ARRAY(HeapWord, tmp_obj, size);
1984 diff -r f5603a6e5042 src/share/vm/gc_implementation/shared/markSweep.hpp
1985 --- a/src/share/vm/gc_implementation/shared/markSweep.hpp Wed Nov 17 22:42:08 2010 -0800
1986 +++ b/src/share/vm/gc_implementation/shared/markSweep.hpp Fri Dec 17 13:24:08 2010 +0100
1987 @@ -103,8 +103,12 @@
1988 friend class AdjustPointerClosure;
1989 friend class KeepAliveClosure;
1990 friend class VM_MarkSweep;
1991 + friend class GenMarkSweep;
1992 friend void marksweep_init();
1995 + static GrowableArray<oop>* _rescued_oops;
2001 template <class T> static inline void mark_and_push(T* p);
2002 static inline void push_objarray(oop obj, size_t index);
2004 + static void copy_rescued_objects_back();
2005 + static void update_fields(oop q, oop new_location);
2006 static void follow_stack(); // Empty marking stack.
2008 static void preserve_mark(oop p, markOop mark);
2009 diff -r f5603a6e5042 src/share/vm/includeDB_core
2010 --- a/src/share/vm/includeDB_core Wed Nov 17 22:42:08 2010 -0800
2011 +++ b/src/share/vm/includeDB_core Fri Dec 17 13:24:08 2010 +0100
2012 @@ -1782,6 +1782,7 @@
2013 genMarkSweep.cpp thread_<os_family>.inline.hpp
2014 genMarkSweep.cpp vmSymbols.hpp
2015 genMarkSweep.cpp vmThread.hpp
2016 +genMarkSweep.cpp jvmtiRedefineClassesTrace.hpp
2018 genMarkSweep.hpp markSweep.hpp
2020 @@ -2625,6 +2626,7 @@
2021 klassVtable.hpp handles.hpp
2022 klassVtable.hpp oopsHierarchy.hpp
2024 +linkResolver.cpp jvmtiRedefineClassesTrace.hpp
2025 linkResolver.cpp bytecode.hpp
2026 linkResolver.cpp collectedHeap.inline.hpp
2027 linkResolver.cpp compilationPolicy.hpp
2028 @@ -3860,6 +3862,7 @@
2029 space.cpp systemDictionary.hpp
2030 space.cpp universe.inline.hpp
2031 space.cpp vmSymbols.hpp
2032 +space.cpp jvmtiRedefineClassesTrace.hpp
2034 space.hpp allocation.hpp
2035 space.hpp blockOffsetTable.hpp
2036 diff -r f5603a6e5042 src/share/vm/includeDB_jvmti
2037 --- a/src/share/vm/includeDB_jvmti Wed Nov 17 22:42:08 2010 -0800
2038 +++ b/src/share/vm/includeDB_jvmti Fri Dec 17 13:24:08 2010 +0100
2039 @@ -231,7 +231,10 @@
2040 jvmtiRedefineClasses.cpp systemDictionary.hpp
2041 jvmtiRedefineClasses.cpp universe.inline.hpp
2042 jvmtiRedefineClasses.cpp verifier.hpp
2043 +jvmtiRedefineClasses.cpp jvmtiClassFileReconstituter.hpp
2044 +jvmtiRedefineClasses.cpp compileBroker.hpp
2046 +jvmtiRedefineClasses.hpp vmGCOperations.hpp
2047 jvmtiRedefineClasses.hpp jvmtiEnv.hpp
2048 jvmtiRedefineClasses.hpp jvmtiRedefineClassesTrace.hpp
2049 jvmtiRedefineClasses.hpp objArrayKlass.hpp
2050 diff -r f5603a6e5042 src/share/vm/interpreter/interpreterRuntime.cpp
2051 --- a/src/share/vm/interpreter/interpreterRuntime.cpp Wed Nov 17 22:42:08 2010 -0800
2052 +++ b/src/share/vm/interpreter/interpreterRuntime.cpp Fri Dec 17 13:24:08 2010 +0100
2054 assert(h_exception.not_null(), "NULL exceptions should be handled by athrow");
2055 assert(h_exception->is_oop(), "just checking");
2056 // Check that exception is a subclass of Throwable, otherwise we have a VerifyError
2057 - if (!(h_exception->is_a(SystemDictionary::Throwable_klass()))) {
2058 + if (!(h_exception->is_a(SystemDictionary::Throwable_klass()->klass_part()->newest_version())) && !(h_exception->is_a(SystemDictionary::Throwable_klass()))) {
2059 if (ExitVMOnVerifyError) vm_exit(-1);
2060 ShouldNotReachHere();
2062 diff -r f5603a6e5042 src/share/vm/interpreter/linkResolver.cpp
2063 --- a/src/share/vm/interpreter/linkResolver.cpp Wed Nov 17 22:42:08 2010 -0800
2064 +++ b/src/share/vm/interpreter/linkResolver.cpp Fri Dec 17 13:24:08 2010 +0100
2068 void LinkResolver::check_klass_accessability(KlassHandle ref_klass, KlassHandle sel_klass, TRAPS) {
2069 - if (!Reflection::verify_class_access(ref_klass->as_klassOop(),
2070 - sel_klass->as_klassOop(),
2071 + if (!Reflection::verify_class_access(ref_klass->as_klassOop()->klass_part()->newest_version(),
2072 + sel_klass->as_klassOop()->klass_part()->newest_version(),
2074 ResourceMark rm(THREAD);
2077 // We'll check for the method name first, as that's most likely
2078 // to be false (so we'll short-circuit out of these tests).
2079 if (sel_method->name() == vmSymbols::clone_name() &&
2080 - sel_klass() == SystemDictionary::Object_klass() &&
2081 + sel_klass()->klass_part()->newest_version() == SystemDictionary::Object_klass()->klass_part()->newest_version() &&
2082 resolved_klass->oop_is_array()) {
2083 // We need to change "protected" to "public".
2084 assert(flags.is_protected(), "clone not protected?");
2088 // Final fields can only be accessed from its own class.
2089 - if (is_put && fd.access_flags().is_final() && sel_klass() != pool->pool_holder()) {
2090 + if (is_put && fd.access_flags().is_final() && sel_klass() != pool->pool_holder()->klass_part()->active_version() && sel_klass() != pool->pool_holder()) {
2091 THROW(vmSymbols::java_lang_IllegalAccessError());
2095 bool check_access, bool check_null_and_abstract, TRAPS) {
2096 methodHandle resolved_method;
2097 linktime_resolve_virtual_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
2098 - runtime_resolve_virtual_method(result, resolved_method, resolved_klass, recv, receiver_klass, check_null_and_abstract, CHECK);
2099 + runtime_resolve_virtual_method(result, resolved_method, resolved_klass, recv, receiver_klass, current_klass, check_null_and_abstract, CHECK);
2102 // throws linktime exceptions
2104 KlassHandle resolved_klass,
2106 KlassHandle recv_klass,
2107 + KlassHandle current_klass,
2108 bool check_null_and_abstract,
2111 @@ -792,7 +793,31 @@
2112 // recv_klass might be an arrayKlassOop but all vtables start at
2113 // the same place. The cast is to avoid virtual call and assertion.
2114 instanceKlass* inst = (instanceKlass*)recv_klass()->klass_part();
2116 + // (tw) The type of the virtual method call and the type of the receiver do not need to
2117 + // have anything in common, as the receiver type could've been hotswapped.
2118 + // Does not always work (method could be resolved with correct dynamic type and later
2119 + // be called at the same place with a wrong dynamic type).
2120 + // (tw) TODO: Need to handle the static type vs dynamic type issue more generally.
2122 + // The vTable must be based on the view of the world of the resolved method
2123 + klassOop method_holder = resolved_method->method_holder();
2125 + if (inst->is_subtype_of(method_holder)) {
2126 selected_method = methodHandle(THREAD, inst->method_at_vtable(vtable_index));
2129 + tty->print_cr("Failure:");
2130 + inst->as_klassOop()->print();
2131 + inst->super()->print();
2132 + juint off = inst->super_check_offset();
2133 + klassOop sup = *(klassOop*)( (address)inst->as_klassOop() + off );
2135 + method_holder->print();
2137 + bool b = inst->is_subtype_of(method_holder);
2138 + THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(), "(tw) A virtual method was called, but the type of the receiver is not related with the type of the class of the called method!");
2143 diff -r f5603a6e5042 src/share/vm/interpreter/linkResolver.hpp
2144 --- a/src/share/vm/interpreter/linkResolver.hpp Wed Nov 17 22:42:08 2010 -0800
2145 +++ b/src/share/vm/interpreter/linkResolver.hpp Fri Dec 17 13:24:08 2010 +0100
2146 @@ -100,7 +100,11 @@
2147 // It does all necessary link-time checks & throws exceptions if necessary.
2149 class LinkResolver: AllStatic {
2152 + static void lookup_method (methodHandle& result, KlassHandle resolved_klass, symbolHandle name, symbolHandle signature, bool is_interface, KlassHandle current_klass, TRAPS);
2153 + static void lookup_correct_field (fieldDescriptor &fd, KlassHandle &sel_klass, KlassHandle resolved_klass, KlassHandle current_klass, symbolOop field_name, symbolOop field_sig, bool is_static);
2154 + static void lookup_correct_method (methodHandle& result, KlassHandle resolved_klass, KlassHandle current_klass, symbolHandle name, symbolHandle signature, bool is_interface, TRAPS);
2155 + static void find_correct_resolved_klass (KlassHandle &resolved_klass, KlassHandle ¤t_klass);
2156 static void lookup_method_in_klasses (methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS);
2157 static void lookup_instance_method_in_klasses (methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS);
2158 static void lookup_method_in_interfaces (methodHandle& result, KlassHandle klass, symbolHandle name, symbolHandle signature, TRAPS);
2160 static void linktime_resolve_interface_method (methodHandle& resolved_method, KlassHandle resolved_klass, symbolHandle method_name, symbolHandle method_signature, KlassHandle current_klass, bool check_access, TRAPS);
2162 static void runtime_resolve_special_method (CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, KlassHandle current_klass, bool check_access, TRAPS);
2163 - static void runtime_resolve_virtual_method (CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, Handle recv, KlassHandle recv_klass, bool check_null_and_abstract, TRAPS);
2164 + static void runtime_resolve_virtual_method (CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, Handle recv, KlassHandle recv_klass, KlassHandle current_klass, bool check_null_and_abstract, TRAPS);
2165 static void runtime_resolve_interface_method (CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, Handle recv, KlassHandle recv_klass, bool check_null_and_abstract, TRAPS);
2167 static void check_field_accessability (KlassHandle ref_klass, KlassHandle resolved_klass, KlassHandle sel_klass, fieldDescriptor& fd, TRAPS);
2168 diff -r f5603a6e5042 src/share/vm/interpreter/oopMapCache.cpp
2169 --- a/src/share/vm/interpreter/oopMapCache.cpp Wed Nov 17 22:42:08 2010 -0800
2170 +++ b/src/share/vm/interpreter/oopMapCache.cpp Fri Dec 17 13:24:08 2010 +0100
2172 if (!_array[i].is_empty() && _array[i].method()->is_old()) {
2173 // Cache entry is occupied by an old redefined method and we don't want
2174 // to pin it down so flush the entry.
2175 - RC_TRACE(0x08000000, ("flush: %s(%s): cached entry @%d",
2176 + TRACE_RC3("flush: %s(%s): cached entry @%d",
2177 _array[i].method()->name()->as_C_string(),
2178 - _array[i].method()->signature()->as_C_string(), i));
2179 + _array[i].method()->signature()->as_C_string(), i);
2183 diff -r f5603a6e5042 src/share/vm/interpreter/templateTable.hpp
2184 --- a/src/share/vm/interpreter/templateTable.hpp Wed Nov 17 22:42:08 2010 -0800
2185 +++ b/src/share/vm/interpreter/templateTable.hpp Fri Dec 17 13:24:08 2010 +0100
2187 static void shouldnotreachhere();
2190 - static void jvmti_post_field_access(Register cache, Register index, bool is_static, bool has_tos);
2191 - static void jvmti_post_field_mod(Register cache, Register index, bool is_static);
2192 + static void jvmti_post_field_access(Register cache, Register index, int byte_no, bool is_static, bool has_tos);
2193 + static void jvmti_post_field_mod(Register cache, Register index, int byte_no, bool is_static);
2194 static void jvmti_post_fast_field_mod();
2196 // debugging of TemplateGenerator
2197 diff -r f5603a6e5042 src/share/vm/memory/genMarkSweep.cpp
2198 --- a/src/share/vm/memory/genMarkSweep.cpp Wed Nov 17 22:42:08 2010 -0800
2199 +++ b/src/share/vm/memory/genMarkSweep.cpp Fri Dec 17 13:24:08 2010 +0100
2201 // in the same order in phase2, phase3 and phase4. We don't quite do that
2202 // here (perm_gen first rather than last), so we tell the validate code
2203 // to use a higher index (saved from phase2) when verifying perm_gen.
2204 + assert(_rescued_oops == NULL, "must be empty before processing");
2205 GenCollectedHeap* gch = GenCollectedHeap::heap();
2206 Generation* pg = gch->perm_gen();
2208 @@ -385,10 +386,14 @@
2210 VALIDATE_MARK_SWEEP_ONLY(reset_live_oop_tracking(false));
2212 + MarkSweep::copy_rescued_objects_back();
2214 GenCompactClosure blk;
2215 gch->generation_iterate(&blk, true);
2217 VALIDATE_MARK_SWEEP_ONLY(compaction_complete());
2219 + MarkSweep::copy_rescued_objects_back();
2221 pg->post_compact(); // Shared spaces verification.
2223 diff -r f5603a6e5042 src/share/vm/memory/permGen.cpp
2224 --- a/src/share/vm/memory/permGen.cpp Wed Nov 17 22:42:08 2010 -0800
2225 +++ b/src/share/vm/memory/permGen.cpp Fri Dec 17 13:24:08 2010 +0100
2230 - MutexLocker ml(Heap_lock);
2231 + // (tw) Only lock when not at a safepoint (necessary to use the split verifier from the VmThread)
2232 + Monitor *lock = Heap_lock;
2233 + if (SafepointSynchronize::is_at_safepoint()) {
2236 + MutexLockerEx ml(lock);
2237 if ((obj = gen->allocate(size, false)) != NULL) {
2240 diff -r f5603a6e5042 src/share/vm/memory/space.cpp
2241 --- a/src/share/vm/memory/space.cpp Wed Nov 17 22:42:08 2010 -0800
2242 +++ b/src/share/vm/memory/space.cpp Fri Dec 17 13:24:08 2010 +0100
2243 @@ -359,6 +359,31 @@
2244 _compaction_top = bottom();
2247 +// (tw) Calculates the compact_top that will be used for placing the next object with the giving size on the heap.
2248 +HeapWord* CompactibleSpace::forward_compact_top(size_t size,
2249 +CompactPoint* cp, HeapWord* compact_top) {
2250 + // First check if we should switch compaction space
2251 + assert(this == cp->space, "'this' should be current compaction space.");
2252 + size_t compaction_max_size = pointer_delta(end(), compact_top);
2253 + while (size > compaction_max_size) {
2254 + // switch to next compaction space
2255 + cp->space->set_compaction_top(compact_top);
2256 + cp->space = cp->space->next_compaction_space();
2257 + if (cp->space == NULL) {
2258 + cp->gen = GenCollectedHeap::heap()->prev_gen(cp->gen);
2259 + assert(cp->gen != NULL, "compaction must succeed");
2260 + cp->space = cp->gen->first_compaction_space();
2261 + assert(cp->space != NULL, "generation must have a first compaction space");
2263 + compact_top = cp->space->bottom();
2264 + cp->space->set_compaction_top(compact_top);
2265 + cp->threshold = cp->space->initialize_threshold();
2266 + compaction_max_size = pointer_delta(cp->space->end(), compact_top);
2269 + return compact_top;
2272 HeapWord* CompactibleSpace::forward(oop q, size_t size,
2273 CompactPoint* cp, HeapWord* compact_top) {
2278 // store the forwarding pointer into the mark word
2279 - if ((HeapWord*)q != compact_top) {
2280 + if ((HeapWord*)q != compact_top || (size_t)q->size() != size) {
2281 q->forward_to(oop(compact_top));
2282 assert(q->is_gc_marked(), "encoding the pointer should preserve the mark");
2284 @@ -430,7 +455,204 @@
2286 // Faster object search.
2287 void ContiguousSpace::prepare_for_compaction(CompactPoint* cp) {
2288 - SCAN_AND_FORWARD(cp, top, block_is_always_obj, obj_size);
2289 + if (!Universe::is_redefining_gc_run()) {
2290 + SCAN_AND_FORWARD(cp, top, block_is_always_obj, obj_size);
2294 + /* Compute the new addresses for the live objects and store it in the mark
2295 + * Used by universe::mark_sweep_phase2()
2297 + HeapWord* compact_top; /* This is where we are currently compacting to. */
2299 + /* We're sure to be here before any objects are compacted into this
2300 + * space, so this is a good time to initialize this:
2302 + set_compaction_top(bottom());
2304 + if (cp->space == NULL) {
2305 + assert(cp->gen != NULL, "need a generation");
2306 + assert(cp->threshold == NULL, "just checking");
2307 + assert(cp->gen->first_compaction_space() == this, "just checking");
2308 + cp->space = cp->gen->first_compaction_space();
2309 + compact_top = cp->space->bottom();
2310 + cp->space->set_compaction_top(compact_top);
2311 + cp->threshold = cp->space->initialize_threshold();
2313 + compact_top = cp->space->compaction_top();
2316 + /* We allow some amount of garbage towards the bottom of the space, so
2317 + * we don't start compacting before there is a significant gain to be made.
2318 + * Occasionally, we want to ensure a full compaction, which is determined
2319 + * by the MarkSweepAlwaysCompactCount parameter.
2321 + int invocations = SharedHeap::heap()->perm_gen()->stat_record()->invocations;
2322 + bool skip_dead = ((invocations % MarkSweepAlwaysCompactCount) != 0);
2324 + size_t allowed_deadspace = 0;
2326 + int ratio = (int)allowed_dead_ratio();
2327 + allowed_deadspace = (capacity() * ratio / 100) / HeapWordSize;
2330 + HeapWord* q = bottom();
2331 + HeapWord* t = end();
2333 + HeapWord* end_of_live= q; /* One byte beyond the last byte of the last
2335 + HeapWord* first_dead = end();/* The first dead object. */
2336 + LiveRange* liveRange = NULL; /* The current live range, recorded in the
2337 + first header of preceding free area. */
2338 + _first_dead = first_dead;
2340 + const intx interval = PrefetchScanIntervalInBytes;
2343 + assert(!block_is_obj(q) ||
2344 + oop(q)->mark()->is_marked() || oop(q)->mark()->is_unlocked() ||
2345 + oop(q)->mark()->has_bias_pattern(),
2346 + "these are the only valid states during a mark sweep");
2347 + if (block_is_obj(q) && oop(q)->is_gc_marked()) {
2348 + /* prefetch beyond q */
2349 + Prefetch::write(q, interval);
2350 + /* size_t size = oop(q)->size(); changing this for cms for perm gen */
2351 + size_t size = block_size(q);
2353 + size_t forward_size = size;
2355 + //////////////////////////////////////////////////////////////////////////
2356 + // Compute the forward sizes and leave out objects whose position could
2357 + // possibly overlap other objects.
2359 + // (tw) There is a new version of the class of q => different size
2360 + if (oop(q)->blueprint()->new_version() != NULL && oop(q)->blueprint()->new_version()->klass_part()->update_information() != NULL) {
2362 + size_t new_size = oop(q)->size_given_klass(oop(q)->blueprint()->new_version()->klass_part());
2363 + assert(size != new_size || oop(q)->is_perm(), "instances without changed size have to be updated prior to GC run");
2364 + forward_size = new_size;
2367 + compact_top = cp->space->forward_compact_top(forward_size, cp, compact_top);
2369 + bool rescueing = false;
2370 + if (rescueing = must_rescue(oop(q), oop(compact_top))) {
2371 + if (MarkSweep::_rescued_oops == NULL) {
2372 + MarkSweep::_rescued_oops = new GrowableArray<oop>(128);
2374 + TRACE_RC5("rescue obj %d klass=%s", MarkSweep::_rescued_oops->length(), oop(q)->klass()->klass_part()->name()->as_C_string());
2375 + MarkSweep::_rescued_oops->append(oop(q));
2377 + compact_top = cp->space->forward(oop(q), forward_size, cp, compact_top);
2380 + if ((size != forward_size || rescueing) && q < first_dead) {
2381 + // (tw) This object moves => first_dead must be set to here!
2384 + //////////////////////////////////////////////////////////////////////////
2386 + end_of_live = q + size; //forward_size;
2389 + /* run over all the contiguous dead objects */
2390 + HeapWord* end = q;
2392 + /* prefetch beyond end */
2393 + Prefetch::write(end, interval);
2394 + end += block_size(end);
2395 + } while (end < t && (!block_is_obj(end) || !oop(end)->is_gc_marked()));
2397 + /* see if we might want to pretend this object is alive so that
2398 + * we don't have to compact quite as often.
2400 + if (allowed_deadspace > 0 && q == compact_top) {
2401 + size_t sz = pointer_delta(end, q);
2402 + if (insert_deadspace(allowed_deadspace, q, sz)) {
2403 + compact_top = cp->space->forward(oop(q), sz, cp, compact_top);
2405 + end_of_live = end;
2410 + /* otherwise, it really is a free region. */
2412 + /* for the previous LiveRange, record the end of the live objects. */
2414 + liveRange->set_end(q);
2417 + /* record the current LiveRange object.
2418 + * liveRange->start() is overlaid on the mark word.
2420 + liveRange = (LiveRange*)q;
2421 + liveRange->set_start(end);
2422 + liveRange->set_end(end);
2424 + /* see if this is the first dead region. */
2425 + if (q < first_dead) {
2429 + /* move on to the next object */
2434 + //////////////////////////////////////////////////////////////////////////
2435 + // Compute the forwarding addresses for the objects that need to be
2437 + // TODO: empty the _rescued_oops after ALL spaces are compacted!
2438 + if (MarkSweep::_rescued_oops != NULL) {
2439 + TRACE_RC2("Calculating new forward sizes for %d objects!", MarkSweep::_rescued_oops->length());
2441 + for (int i=0; i<MarkSweep::_rescued_oops->length(); i++) {
2442 + oop q = MarkSweep::_rescued_oops->at(i);
2444 + /* size_t size = oop(q)->size(); changing this for cms for perm gen */
2445 + size_t size = block_size((HeapWord*)q);
2447 + size_t forward_size = size;
2449 + // (tw) There is a new version of the class of q => different size
2450 + if (oop(q)->blueprint()->new_version() != NULL) {
2452 + size_t new_size = oop(q)->size_given_klass(oop(q)->blueprint()->new_version()->klass_part());
2453 + assert(size != new_size || oop(q)->is_perm(), "instances without changed size have to be updated prior to GC run");
2454 + forward_size = new_size;
2457 + compact_top = cp->space->forward(oop(q), forward_size, cp, compact_top);
2458 + assert(compact_top <= t, "must not write over end of space!");
2460 + MarkSweep::_rescued_oops->clear();
2461 + MarkSweep::_rescued_oops = NULL;
2463 + //////////////////////////////////////////////////////////////////////////
2465 + assert(q == t, "just checking");
2466 + if (liveRange != NULL) {
2467 + liveRange->set_end(q);
2469 + _end_of_live = end_of_live;
2470 + if (end_of_live < first_dead) {
2471 + first_dead = end_of_live;
2473 + _first_dead = first_dead;
2475 + if (_first_dead > top()) {
2476 + _first_dead = top();
2479 + if (_end_of_live > top()) {
2480 + _end_of_live = top();
2482 + assert(_first_dead <= top(), "Must be smaller equal");
2483 + assert(_end_of_live <= top(), "Must be smaller equal");
2485 + /* save the compaction_top of the compaction space. */
2486 + cp->space->set_compaction_top(compact_top);
2489 void Space::adjust_pointers() {
2490 @@ -471,17 +693,322 @@
2491 assert(q == t, "just checking");
2497 +int CompactibleSpace::space_index(oop obj) {
2498 + GenCollectedHeap* heap = GenCollectedHeap::heap();
2500 + if (heap->is_in_permanent(obj)) {
2505 + for (int i = heap->n_gens() - 1; i >= 0; i--) {
2506 + Generation* gen = heap->get_gen(i);
2507 + CompactibleSpace* space = gen->first_compaction_space();
2508 + while (space != NULL) {
2509 + if (space->is_in_reserved(obj)) {
2512 + space = space->next_compaction_space();
2517 + tty->print_cr("could not compute space_index for %08xh", obj);
2519 + for (int i = heap->n_gens() - 1; i >= 0; i--) {
2520 + Generation* gen = heap->get_gen(i);
2521 + tty->print_cr(" generation %s: %08xh - %08xh", gen->name(), gen->reserved().start(), gen->reserved().end());
2523 + CompactibleSpace* space = gen->first_compaction_space();
2524 + while (space != NULL) {
2525 + tty->print_cr(" %2d space %08xh - %08xh", index, space->bottom(), space->end());
2526 + space = space->next_compaction_space();
2531 + ShouldNotReachHere();
2536 +bool CompactibleSpace::must_rescue(oop old_obj, oop new_obj) {
2538 + assert(is_in_reserved(old_obj), "old_obj must be in this space");
2540 + if (old_obj->is_perm()) {
2541 + // This object is in perm gen; check for invariant obj->klass() <= obj
2542 + if (oop(old_obj)->blueprint()->new_version() != NULL) {
2547 + int size = old_obj->size();
2548 + int original_size = size;
2549 + if (oop(old_obj)->blueprint()->is_redefining()) {
2550 + assert(oop(old_obj)->blueprint()->old_version() != NULL, "must not be null");
2551 + original_size = oop(old_obj)->size_given_klass(oop(old_obj)->blueprint()->old_version()->klass_part());
2552 + } else if (oop(old_obj)->blueprint()->new_version() != NULL) {
2553 + size = oop(old_obj)->size_given_klass(oop(old_obj)->blueprint()->new_version()->klass_part());
2556 + bool normalComparison = (old_obj + original_size < new_obj + size);
2558 + if (is_in_reserved(new_obj)) {
2559 + // Old and new address are in same space, so just compare the address.
2560 + // Must rescue if object moves towards the top of the space.
2561 + assert(space_index(old_obj) == space_index(new_obj), "old_obj and new_obj must be in same space");
2562 + return normalComparison;
2566 + assert(space_index(old_obj) != space_index(new_obj), "old_obj and new_obj must be in different spaces");
2568 + Generation* tenured_gen = GenCollectedHeap::heap()->get_gen(1);
2569 + if (tenured_gen->is_in_reserved(new_obj)) {
2570 + // Must never rescue when moving from the new into the old generation.
2571 + assert(GenCollectedHeap::heap()->get_gen(0)->is_in_reserved(old_obj), "old_obj must be in DefNewGeneration");
2572 + assert(space_index(old_obj) > space_index(new_obj), "must be");
2575 + } else if (tenured_gen->is_in_reserved(old_obj)) {
2576 + // Must always rescue when moving from the old into the new generation.
2577 + assert(GenCollectedHeap::heap()->get_gen(0)->is_in_reserved(new_obj), "new_obj must be in DefNewGeneration");
2578 + assert(space_index(old_obj) < space_index(new_obj), "must be");
2582 + // In the new generation, eden is located before the from space, so a
2583 + // simple pointer comparison is sufficient.
2584 + assert(GenCollectedHeap::heap()->get_gen(0)->is_in_reserved(old_obj), "old_obj must be in DefNewGeneration");
2585 + assert(GenCollectedHeap::heap()->get_gen(0)->is_in_reserved(new_obj), "new_obj must be in DefNewGeneration");
2586 + assert((normalComparison) == (space_index(old_obj) < space_index(new_obj)), "slow and fast computation must yield same result");
2587 + return normalComparison;
2592 +oop CompactibleSpace::rescue(oop old_obj) {
2593 + assert(must_rescue(old_obj, old_obj->forwardee()), "do not call otherwise");
2595 + int size = old_obj->size();
2596 + oop rescued_obj = (oop)resource_allocate_bytes(size * HeapWordSize);
2597 + Copy::aligned_disjoint_words((HeapWord*)old_obj, (HeapWord*)rescued_obj, size);
2599 + if (MarkSweep::_rescued_oops == NULL) {
2600 + MarkSweep::_rescued_oops = new GrowableArray<oop>(128);
2603 + MarkSweep::_rescued_oops->append(rescued_obj);
2604 + return rescued_obj;
2607 void CompactibleSpace::adjust_pointers() {
2608 // Check first is there is any work to do.
2610 return; // Nothing to do.
2612 + /* adjust all the interior pointers to point at the new locations of objects
2613 + * Used by MarkSweep::mark_sweep_phase3() */
2615 - SCAN_AND_ADJUST_POINTERS(adjust_obj_size);
2616 + HeapWord* q = bottom();
2617 + HeapWord* t = _end_of_live; /* Established by "prepare_for_compaction". */
2619 + assert(_first_dead <= _end_of_live, "Stands to reason, no?");
2621 + debug_only(HeapWord* prev_q = NULL);
2622 + debug_only(HeapWord* prev_prev_q = NULL);
2623 + debug_only(HeapWord* prev_prev_prev_q = NULL);
2624 + if (q < t && _first_dead > q &&
2625 + !oop(q)->is_gc_marked()) {
2626 + /* we have a chunk of the space which hasn't moved and we've
2627 + * reinitialized the mark word during the previous pass, so we can't
2628 + * use is_gc_marked for the traversal. */
2629 + HeapWord* end = _first_dead;
2632 + /* I originally tried to conjoin "block_start(q) == q" to the
2633 + * assertion below, but that doesn't work, because you can't
2634 + * accurately traverse previous objects to get to the current one
2635 + * after their pointers (including pointers into permGen) have been
2636 + * updated, until the actual compaction is done. dld, 4/00 */
2637 + assert(block_is_obj(q),
2638 + "should be at block boundaries, and should be looking at objs");
2640 + VALIDATE_MARK_SWEEP_ONLY(MarkSweep::track_interior_pointers(oop(q)));
2642 + /* point all the oops to the new location */
2643 + size_t size = oop(q)->adjust_pointers();
2644 + size = adjust_obj_size(size);
2646 + VALIDATE_MARK_SWEEP_ONLY(MarkSweep::check_interior_pointers());
2647 + VALIDATE_MARK_SWEEP_ONLY(MarkSweep::validate_live_oop(oop(q), size));
2649 + debug_only(prev_prev_prev_q = prev_prev_q);
2650 + debug_only(prev_prev_q = prev_q);
2651 + debug_only(prev_q = q);
2655 + // (tw) first_dead can be live object!
2658 +// if (_first_dead == t) {
2661 +// /* $$$ This is funky. Using this to read the previously written
2662 +// * LiveRange. See also use below. */
2663 +// q = (HeapWord*)oop(_first_dead)->mark()->decode_pointer();
2667 + const intx interval = PrefetchScanIntervalInBytes;
2669 + debug_only(prev_q = NULL);
2670 + debug_only(prev_prev_q = NULL);
2671 + debug_only(prev_prev_prev_q = NULL);
2673 + /* prefetch beyond q */
2674 + Prefetch::write(q, interval);
2675 + if (oop(q)->is_gc_marked()) {
2677 + VALIDATE_MARK_SWEEP_ONLY(MarkSweep::track_interior_pointers(oop(q)));
2678 + /* point all the oops to the new location */
2679 + size_t size = oop(q)->adjust_pointers();
2680 + size = adjust_obj_size(size);
2681 + VALIDATE_MARK_SWEEP_ONLY(MarkSweep::check_interior_pointers());
2682 + VALIDATE_MARK_SWEEP_ONLY(MarkSweep::validate_live_oop(oop(q), size));
2683 + debug_only(prev_prev_prev_q = prev_prev_q);
2684 + debug_only(prev_prev_q = prev_q);
2685 + debug_only(prev_q = q);
2688 + /* q is not a live object, so its mark should point at the next
2690 + debug_only(prev_prev_prev_q = prev_prev_q);
2691 + debug_only(prev_prev_q = prev_q);
2692 + debug_only(prev_q = q);
2693 + q = (HeapWord*) oop(q)->mark()->decode_pointer();
2694 + assert(q > prev_q, "we should be moving forward through memory");
2698 + assert(q == t, "just checking");
2701 void CompactibleSpace::compact() {
2702 - SCAN_AND_COMPACT(obj_size);
2704 + if(!Universe::is_redefining_gc_run()) {
2705 + SCAN_AND_COMPACT(obj_size);
2709 + /* Copy all live objects to their new location
2710 + * Used by MarkSweep::mark_sweep_phase4() */
2712 + HeapWord* q = bottom();
2713 + HeapWord* const t = _end_of_live;
2714 + debug_only(HeapWord* prev_q = NULL);
2715 + debug_only(HeapWord* prev_prev_q = NULL);
2716 + debug_only(HeapWord* prev_compaction_top = NULL);
2717 + debug_only(int old_size = 0);
2719 + if (q < t && _first_dead > q &&
2720 + !oop(q)->is_gc_marked()) {
2721 + /* we have a chunk of the space which hasn't moved and we've reinitialized
2722 + * the mark word during the previous pass, so we can't use is_gc_marked for
2723 + * the traversal. */
2724 + HeapWord* const end = _first_dead;
2728 + size_t size = oop(q)->size();
2729 + assert(!oop(q)->is_gc_marked(),
2730 + "should be unmarked (special dense prefix handling)");
2731 + VALIDATE_MARK_SWEEP_ONLY(MarkSweep::live_oop_moved_to(q, size, q));
2732 + debug_only(prev_prev_q = prev_q);
2733 + debug_only(prev_q = q);
2737 + // (tw) first_dead can be live object!
2740 + //if (_first_dead == t) {
2744 + //q = (HeapWord*) oop(_first_dead)->mark()->decode_pointer();
2748 + const intx scan_interval = PrefetchScanIntervalInBytes;
2749 + const intx copy_interval = PrefetchCopyIntervalInBytes;
2751 + if (!oop(q)->is_gc_marked()) {
2752 + /* mark is pointer to next marked oop */
2753 + debug_only(prev_prev_q = prev_q);
2754 + debug_only(prev_q = q);
2755 + q = (HeapWord*) oop(q)->mark()->decode_pointer();
2756 + assert(q > prev_q, "we should be moving forward through memory");
2758 + /* prefetch beyond q */
2759 + Prefetch::read(q, scan_interval);
2761 + /* size and destination */
2762 + size_t size = obj_size(q);
2763 + HeapWord* compaction_top = (HeapWord*)oop(q)->forwardee();
2765 + size_t original_size = size;
2767 + if (must_rescue(oop(q), oop(q)->forwardee())) {
2768 + oop dest_obj = rescue(oop(q));
2769 + debug_only(Copy::fill_to_words(q, original_size, 0));
2772 + /* prefetch beyond compaction_top */
2773 + Prefetch::write(compaction_top, copy_interval);
2775 + /* copy object and reinit its mark */
2776 + VALIDATE_MARK_SWEEP_ONLY(MarkSweep::live_oop_moved_to(q, size,
2778 + assert(q != compaction_top || oop(q)->blueprint()->new_version() != NULL, "everything in this pass should be moving");
2780 + if (oop(q)->blueprint()->new_version() != NULL) {
2781 + MarkSweep::update_fields(oop(q), oop(compaction_top));
2783 + Copy::aligned_conjoint_words(q, compaction_top, size);
2785 + oop(compaction_top)->init_mark();
2786 + assert(oop(compaction_top)->klass() != NULL, "should have a class");
2789 + debug_only(prev_compaction_top = compaction_top);
2790 + debug_only(prev_prev_q = prev_q);
2791 + debug_only(prev_q = q);
2792 + debug_only(old_size = (int)size);
2793 + q += original_size;
2797 + /* Reset space after compaction is complete */
2798 + reset_after_compaction();
2799 + /* We do this clear, below, since it has overloaded meanings for some */
2800 + /* space subtypes. For example, OffsetTableContigSpace's that were */
2801 + /* compacted into will have had their offset table thresholds updated */
2802 + /* continuously, but those that weren't need to have their thresholds */
2803 + /* re-initialized. Also mangles unused area for debugging. */
2805 + clear(SpaceDecorator::Mangle);
2807 + if (ZapUnusedHeapArea) mangle_unused_area();
2811 + //SCAN_AND_COMPACT(obj_size);
2814 void Space::print_short() const { print_short_on(tty); }
2815 diff -r f5603a6e5042 src/share/vm/memory/space.hpp
2816 --- a/src/share/vm/memory/space.hpp Wed Nov 17 22:42:08 2010 -0800
2817 +++ b/src/share/vm/memory/space.hpp Fri Dec 17 13:24:08 2010 +0100
2819 // indicates when the next such action should be taken.
2820 virtual void prepare_for_compaction(CompactPoint* cp);
2821 // MarkSweep support phase3
2822 + DEBUG_ONLY(int space_index(oop obj));
2823 + bool must_rescue(oop old_obj, oop new_obj);
2824 + oop rescue(oop old_obj);
2825 virtual void adjust_pointers();
2826 // MarkSweep support phase4
2827 virtual void compact();
2828 @@ -449,6 +452,10 @@
2829 virtual HeapWord* forward(oop q, size_t size, CompactPoint* cp,
2830 HeapWord* compact_top);
2833 + virtual HeapWord* forward_compact_top(size_t size, CompactPoint* cp,
2834 + HeapWord* compact_top);
2836 // Return a size with adjusments as required of the space.
2837 virtual size_t adjust_object_size_v(size_t size) const { return size; }
2839 diff -r f5603a6e5042 src/share/vm/memory/universe.cpp
2840 --- a/src/share/vm/memory/universe.cpp Wed Nov 17 22:42:08 2010 -0800
2841 +++ b/src/share/vm/memory/universe.cpp Fri Dec 17 13:24:08 2010 +0100
2843 # include "incls/_precompiled.incl"
2844 # include "incls/_universe.cpp.incl"
2846 +bool Universe::_is_redefining_gc_run = false;
2849 klassOop Universe::_boolArrayKlassObj = NULL;
2850 klassOop Universe::_byteArrayKlassObj = NULL;
2851 @@ -131,6 +133,43 @@
2852 f(systemObjArrayKlassObj());
2855 +// (tw) This method should iterate all pointers that are not within heap objects.
2856 +void Universe::root_oops_do(OopClosure *oopClosure) {
2858 + class AlwaysTrueClosure: public BoolObjectClosure {
2860 + void do_object(oop p) { ShouldNotReachHere(); }
2861 + bool do_object_b(oop p) { return true; }
2863 + AlwaysTrueClosure always_true;
2865 + Universe::oops_do(oopClosure);
2866 + ReferenceProcessor::oops_do(oopClosure);
2867 + JNIHandles::oops_do(oopClosure); // Global (strong) JNI handles
2868 + Threads::oops_do(oopClosure, NULL);
2869 + ObjectSynchronizer::oops_do(oopClosure);
2870 + FlatProfiler::oops_do(oopClosure);
2871 + JvmtiExport::oops_do(oopClosure);
2873 + SystemDictionary::oops_do(oopClosure);
2874 + vmSymbols::oops_do(oopClosure);
2876 + // Now adjust pointers in remaining weak roots. (All of which should
2877 + // have been cleared if they pointed to non-surviving objects.)
2878 + // Global (weak) JNI handles
2879 + JNIHandles::weak_oops_do(&always_true, oopClosure);
2881 + CodeCache::oops_do(oopClosure);
2882 + SymbolTable::oops_do(oopClosure);
2883 + StringTable::oops_do(oopClosure);
2885 + // (tw) TODO: Check if this is correct?
2886 + //CodeCache::scavenge_root_nmethods_oops_do(oopClosure);
2887 + //Management::oops_do(oopClosure);
2888 + //ref_processor()->weak_oops_do(&oopClosure);
2889 + //PSScavenge::reference_processor()->weak_oops_do(&oopClosure);
2892 void Universe::oops_do(OopClosure* f, bool do_all) {
2894 f->do_oop((oop*) &_int_mirror);
2895 @@ -1424,10 +1463,9 @@
2898 // RC_TRACE macro has an embedded ResourceMark
2899 - RC_TRACE(0x00000100,
2900 - ("add: %s(%s): adding prev version ref for cached method @%d",
2901 + TRACE_RC2("add: %s(%s): adding prev version ref for cached method @%d",
2902 method->name()->as_C_string(), method->signature()->as_C_string(),
2903 - _prev_methods->length()));
2904 + _prev_methods->length());
2906 methodHandle method_h(method);
2907 jweak method_ref = JNIHandles::make_weak_global(method_h);
2908 @@ -1454,9 +1492,8 @@
2909 JNIHandles::destroy_weak_global(method_ref);
2910 _prev_methods->remove_at(i);
2912 - // RC_TRACE macro has an embedded ResourceMark
2913 - RC_TRACE(0x00000400, ("add: %s(%s): previous cached method @%d is alive",
2914 - m->name()->as_C_string(), m->signature()->as_C_string(), i));
2915 + TRACE_RC2("add: %s(%s): previous cached method @%d is alive",
2916 + m->name()->as_C_string(), m->signature()->as_C_string(), i);
2919 } // end add_previous_version()
2920 diff -r f5603a6e5042 src/share/vm/memory/universe.hpp
2921 --- a/src/share/vm/memory/universe.hpp Wed Nov 17 22:42:08 2010 -0800
2922 +++ b/src/share/vm/memory/universe.hpp Fri Dec 17 13:24:08 2010 +0100
2924 friend class SystemDictionary;
2925 friend class VMStructs;
2926 friend class CompactingPermGenGen;
2927 + friend class Space;
2928 + friend class ContiguousSpace;
2929 friend class VM_PopulateDumpSharedSpace;
2931 friend jint universe_init();
2932 @@ -246,7 +248,18 @@
2934 static void compute_verify_oop_data();
2936 + static bool _is_redefining_gc_run;
2940 + static bool is_redefining_gc_run() {
2941 + return _is_redefining_gc_run;
2944 + static void set_redefining_gc_run(bool b) {
2945 + _is_redefining_gc_run = b;
2948 // Known classes in the VM
2949 static klassOop boolArrayKlassObj() { return _boolArrayKlassObj; }
2950 static klassOop byteArrayKlassObj() { return _byteArrayKlassObj; }
2955 + static void root_oops_do(OopClosure *f);
2957 // Apply "f" to the addresses of all the direct heap pointers maintained
2958 // as static fields of "Universe".
2959 static void oops_do(OopClosure* f, bool do_all = false);
2963 static bool verify_in_progress() { return _verify_in_progress; }
2964 + static void set_verify_in_progress(bool b) { _verify_in_progress = b; }
2965 static void verify(bool allow_dirty = true, bool silent = false, bool option = true);
2966 static int verify_count() { return _verify_count; }
2967 static void print();
2968 diff -r f5603a6e5042 src/share/vm/oops/arrayKlass.cpp
2969 --- a/src/share/vm/oops/arrayKlass.cpp Wed Nov 17 22:42:08 2010 -0800
2970 +++ b/src/share/vm/oops/arrayKlass.cpp Fri Dec 17 13:24:08 2010 +0100
2973 bool arrayKlass::compute_is_subtype_of(klassOop k) {
2974 // An array is a subtype of Serializable, Clonable, and Object
2975 - return k == SystemDictionary::Object_klass()
2976 - || k == SystemDictionary::Cloneable_klass()
2977 - || k == SystemDictionary::Serializable_klass();
2978 + return k->klass_part()->newest_version() == SystemDictionary::Object_klass()->klass_part()->newest_version()
2979 + || k->klass_part()->newest_version() == SystemDictionary::Cloneable_klass()->klass_part()->newest_version()
2980 + || k->klass_part()->newest_version() == SystemDictionary::Serializable_klass()->klass_part()->newest_version();
2984 diff -r f5603a6e5042 src/share/vm/oops/cpCacheOop.cpp
2985 --- a/src/share/vm/oops/cpCacheOop.cpp Wed Nov 17 22:42:08 2010 -0800
2986 +++ b/src/share/vm/oops/cpCacheOop.cpp Fri Dec 17 13:24:08 2010 +0100
2989 // Implememtation of ConstantPoolCacheEntry
2991 +void ConstantPoolCacheEntry::copy_from(ConstantPoolCacheEntry *other) {
2992 + _flags = other->_flags; // flags
2995 void ConstantPoolCacheEntry::initialize_entry(int index) {
2996 assert(0 < index && index < 0x10000, "sanity check");
3000 assert(constant_pool_index() == index, "");
3005 assert(!is_secondary_entry(), "");
3006 assert(method->interpreter_entry() != NULL, "should have been set at this point");
3007 - assert(!method->is_obsolete(), "attempt to write obsolete method to cpCache");
3008 + // (tw) No longer valid assert
3009 + //assert(!method->is_obsolete(), "attempt to write obsolete method to cpCache");
3010 bool change_to_virtual = (invoke_code == Bytecodes::_invokeinterface);
3015 assert(vtable_index >= 0, "valid index");
3016 set_f2(vtable_index);
3018 + // (tw) save method holder in f1 for virtual calls
3023 @@ -376,26 +386,13 @@
3024 // If this constantPoolCacheEntry refers to old_method then update it
3025 // to refer to new_method.
3026 bool ConstantPoolCacheEntry::adjust_method_entry(methodOop old_method,
3027 - methodOop new_method, bool * trace_name_printed) {
3028 + methodOop new_method) {
3032 // virtual and final so f2() contains method ptr instead of vtable index
3033 - if (f2() == (intptr_t)old_method) {
3034 - // match old_method so need an update
3035 - _f2 = (intptr_t)new_method;
3036 - if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
3037 - if (!(*trace_name_printed)) {
3038 - // RC_TRACE_MESG macro has an embedded ResourceMark
3039 - RC_TRACE_MESG(("adjust: name=%s",
3040 - Klass::cast(old_method->method_holder())->external_name()));
3041 - *trace_name_printed = true;
3043 - // RC_TRACE macro has an embedded ResourceMark
3044 - RC_TRACE(0x00400000, ("cpc vf-entry update: %s(%s)",
3045 - new_method->name()->as_C_string(),
3046 - new_method->signature()->as_C_string()));
3049 + if((methodOop)f2() != NULL && ((methodOop)f2())->method_holder()->klass_part()->new_version()) {
3050 + initialize_entry(constant_pool_index());
3054 @@ -403,65 +400,28 @@
3058 - if ((oop)_f1 == NULL) {
3059 - // NULL f1() means this is a virtual entry so bail out
3060 - // We are assuming that the vtable index does not need change.
3061 + // (tw) check how to update interface methods!
3062 + if (bytecode_1() == Bytecodes::_invokevirtual || bytecode_2() == Bytecodes::_invokevirtual) {
3064 + if(((methodOop)f1())->method_holder()->klass_part()->new_version()) {
3065 + initialize_entry(constant_pool_index());
3072 if ((oop)_f1 == old_method) {
3074 - if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
3075 - if (!(*trace_name_printed)) {
3076 - // RC_TRACE_MESG macro has an embedded ResourceMark
3077 - RC_TRACE_MESG(("adjust: name=%s",
3078 - Klass::cast(old_method->method_holder())->external_name()));
3079 - *trace_name_printed = true;
3081 - // RC_TRACE macro has an embedded ResourceMark
3082 - RC_TRACE(0x00400000, ("cpc entry update: %s(%s)",
3083 - new_method->name()->as_C_string(),
3084 - new_method->signature()->as_C_string()));
3088 + } else if(_f1 != NULL && (bytecode_1() != Bytecodes::_invokeinterface && ((methodOop)f1())->method_holder()->klass_part()->new_version())) {
3089 + initialize_entry(constant_pool_index());
3096 -bool ConstantPoolCacheEntry::is_interesting_method_entry(klassOop k) {
3097 - if (!is_method_entry()) {
3098 - // not a method entry so not interesting by default
3102 - methodOop m = NULL;
3103 - if (is_vfinal()) {
3104 - // virtual and final so _f2 contains method ptr instead of vtable index
3105 - m = (methodOop)_f2;
3106 - } else if ((oop)_f1 == NULL) {
3107 - // NULL _f1 means this is a virtual entry so also not interesting
3110 - if (!((oop)_f1)->is_method()) {
3111 - // _f1 can also contain a klassOop for an interface
3114 - m = (methodOop)_f1;
3117 - assert(m != NULL && m->is_method(), "sanity check");
3118 - if (m == NULL || !m->is_method() || m->method_holder() != k) {
3119 - // robustness for above sanity checks or method is not in
3120 - // the interesting class
3124 - // the method is in the interesting class so the entry is interesting
3128 void ConstantPoolCacheEntry::print(outputStream* st, int index) const {
3130 if (index == 0) tty->print_cr(" -------------");
3131 @@ -502,38 +462,18 @@
3132 // RedefineClasses() API support:
3133 // If any entry of this constantPoolCache points to any of
3134 // old_methods, replace it with the corresponding new_method.
3135 -void constantPoolCacheOopDesc::adjust_method_entries(methodOop* old_methods, methodOop* new_methods,
3136 - int methods_length, bool * trace_name_printed) {
3138 - if (methods_length == 0) {
3139 - // nothing to do if there are no methods
3143 - // get shorthand for the interesting class
3144 - klassOop old_holder = old_methods[0]->method_holder();
3145 +void constantPoolCacheOopDesc::adjust_entries(methodOop* old_methods, methodOop* new_methods,
3146 + int methods_length) {
3148 for (int i = 0; i < length(); i++) {
3149 - if (!entry_at(i)->is_interesting_method_entry(old_holder)) {
3150 - // skip uninteresting methods
3153 + if (entry_at(i)->is_field_entry()) {
3155 - // The constantPoolCache contains entries for several different
3156 - // things, but we only care about methods. In fact, we only care
3157 - // about methods in the same class as the one that contains the
3158 - // old_methods. At this point, we have an interesting entry.
3160 - for (int j = 0; j < methods_length; j++) {
3161 - methodOop old_method = old_methods[j];
3162 - methodOop new_method = new_methods[j];
3164 - if (entry_at(i)->adjust_method_entry(old_method, new_method,
3165 - trace_name_printed)) {
3166 - // current old_method matched this entry and we updated it so
3167 - // break out and get to the next interesting entry if there one
3170 + // (tw) TODO: Update only field offsets and modify only constant pool entries that
3171 + // point to changed fields
3172 + entry_at(i)->initialize_entry(entry_at(i)->constant_pool_index());
3174 + } else if(entry_at(i)->is_method_entry()) {
3175 + entry_at(i)->adjust_method_entry(NULL, NULL);
3179 diff -r f5603a6e5042 src/share/vm/oops/cpCacheOop.hpp
3180 --- a/src/share/vm/oops/cpCacheOop.hpp Wed Nov 17 22:42:08 2010 -0800
3181 +++ b/src/share/vm/oops/cpCacheOop.hpp Fri Dec 17 13:24:08 2010 +0100
3182 @@ -127,11 +127,15 @@
3183 void set_bytecode_2(Bytecodes::Code code);
3184 void set_f1(oop f1) {
3185 oop existing_f1 = _f1; // read once
3186 - assert(existing_f1 == NULL || existing_f1 == f1, "illegal field change");
3187 + // (tw) need to relax assertion for redefinition
3188 + // assert(existing_f1 == NULL || existing_f1 == f1, "illegal field change");
3189 oop_store(&_f1, f1);
3191 void set_f1_if_null_atomic(oop f1);
3192 - void set_f2(intx f2) { assert(_f2 == 0 || _f2 == f2, "illegal field change"); _f2 = f2; }
3193 + void set_f2(intx f2) {
3194 + // (tw) need to relax assertion for redefinition
3195 + // assert(_f2 == 0 || _f2 == f2, "illegal field change");
3197 int as_flags(TosState state, bool is_final, bool is_vfinal, bool is_volatile,
3198 bool is_method_interface, bool is_method);
3199 void set_flags(intx flags) { _flags = flags; }
3201 void initialize_entry(int original_index); // initialize primary entry
3202 void initialize_secondary_entry(int main_index); // initialize secondary entry
3204 + void copy_from(ConstantPoolCacheEntry *other);
3206 void set_field( // sets entry to resolved field state
3207 Bytecodes::Code get_code, // the bytecode used for reading the field
3208 Bytecodes::Code put_code, // the bytecode used for writing the field
3210 // trace_name_printed is set to true if the current call has
3211 // printed the klass name so that other routines in the adjust_*
3212 // group don't print the klass name.
3213 - bool adjust_method_entry(methodOop old_method, methodOop new_method,
3214 - bool * trace_name_printed);
3215 - bool is_interesting_method_entry(klassOop k);
3216 + bool adjust_method_entry(methodOop old_method, methodOop new_method);
3217 bool is_field_entry() const { return (_flags & (1 << hotSwapBit)) == 0; }
3218 bool is_method_entry() const { return (_flags & (1 << hotSwapBit)) != 0; }
3220 @@ -397,12 +401,7 @@
3221 return (base_offset() + ConstantPoolCacheEntry::size_in_bytes() * index);
3224 - // RedefineClasses() API support:
3225 - // If any entry of this constantPoolCache points to any of
3226 - // old_methods, replace it with the corresponding new_method.
3227 - // trace_name_printed is set to true if the current call has
3228 - // printed the klass name so that other routines in the adjust_*
3229 - // group don't print the klass name.
3230 - void adjust_method_entries(methodOop* old_methods, methodOop* new_methods,
3231 - int methods_length, bool * trace_name_printed);
3232 + // (tw) Update method and field references
3233 + void adjust_entries(methodOop* old_methods, methodOop* new_methods,
3234 + int methods_length);
3236 diff -r f5603a6e5042 src/share/vm/oops/instanceKlass.cpp
3237 --- a/src/share/vm/oops/instanceKlass.cpp Wed Nov 17 22:42:08 2010 -0800
3238 +++ b/src/share/vm/oops/instanceKlass.cpp Fri Dec 17 13:24:08 2010 +0100
3239 @@ -157,12 +157,116 @@
3243 +void instanceKlass::initialize_redefined_class() {
3245 + TRACE_RC3("initializing redefined class %s", name()->as_C_string());
3247 + assert(!is_initialized(), "");
3248 + assert(this->old_version() != NULL, "");
3249 + assert(is_linked(), "must be linked before");
3252 + instanceKlassHandle this_oop(Thread::current(), this->as_klassOop());
3253 + class UpdateStaticFieldClosure : public FieldClosure {
3256 + instanceKlassHandle this_oop;
3259 + UpdateStaticFieldClosure(instanceKlassHandle this_oop) {
3260 + this->this_oop = this_oop;
3263 + virtual void do_field(fieldDescriptor* fd) {
3264 + fieldDescriptor result;
3265 + bool found = ((instanceKlass *)(this_oop->old_version()->klass_part()))->find_local_field(fd->name(), fd->signature(), &result);
3267 + if (found && result.is_static()) {
3268 + int old_offset = result.offset();
3269 + assert(result.field_type() == fd->field_type(), "");
3271 + oop new_location = this_oop();
3272 + oop old_location = this_oop->old_version();
3273 + int offset = fd->offset();
3274 + TRACE_RC3("Copying static field value for field %s old_offset=%d new_offset=%d", fd->name()->as_C_string(), old_offset, offset);
3278 + switch(result.field_type()) {
3280 + // Found static field with same name and type in the old klass => copy value from old to new klass
3283 + new_location->bool_field_put(offset, old_location->bool_field(old_offset));
3284 + DEBUG_ONLY(old_location->byte_field_put(old_offset, 0));
3288 + new_location->char_field_put(offset, old_location->char_field(old_offset));
3289 + DEBUG_ONLY(old_location->char_field_put(old_offset, 0));
3293 + new_location->float_field_put(offset, old_location->float_field(old_offset));
3294 + DEBUG_ONLY(old_location->float_field_put(old_offset, 0));
3298 + new_location->double_field_put(offset, old_location->double_field(old_offset));
3299 + DEBUG_ONLY(old_location->double_field_put(old_offset, 0));
3303 + new_location->byte_field_put(offset, old_location->byte_field(old_offset));
3304 + DEBUG_ONLY(old_location->byte_field_put(old_offset, 0));
3308 + new_location->short_field_put(offset, old_location->short_field(old_offset));
3309 + DEBUG_ONLY(old_location->short_field_put(old_offset, 0));
3313 + new_location->int_field_put(offset, old_location->int_field(old_offset));
3314 + DEBUG_ONLY(old_location->int_field_put(old_offset, 0));
3318 + new_location->long_field_put(offset, old_location->long_field(old_offset));
3319 + DEBUG_ONLY(old_location->long_field_put(old_offset, 0));
3324 + cur_oop = old_location->obj_field(old_offset);
3325 + new_location->obj_field_raw_put(offset, cur_oop);
3326 + old_location->obj_field_raw_put(old_offset, NULL);
3330 + ShouldNotReachHere();
3334 + TRACE_RC2("New static field %s has_initial_value=%d", fd->name()->as_C_string(), (int)(fd->has_initial_value()));
3335 + // field not found
3336 + // (tw) TODO: Probably this call is not necessary here!
3337 + ClassFileParser::initialize_static_field(fd, Thread::current());
3342 + UpdateStaticFieldClosure cl(this_oop);
3343 + this->do_local_static_fields(&cl);
3347 bool instanceKlass::verify_code(
3348 instanceKlassHandle this_oop, bool throw_verifyerror, TRAPS) {
3349 // 1) Verify the bytecodes
3350 Verifier::Mode mode =
3351 throw_verifyerror ? Verifier::ThrowException : Verifier::NoException;
3352 - return Verifier::verify(this_oop, mode, this_oop->should_verify_class(), CHECK_false);
3353 + return Verifier::verify(this_oop, mode, this_oop->should_verify_class(), true, CHECK_false);
3357 @@ -269,7 +373,13 @@
3358 jt->get_thread_stat()->perf_recursion_counts_addr(),
3359 jt->get_thread_stat()->perf_timers_addr(),
3360 PerfClassTraceTime::CLASS_VERIFY);
3361 - bool verify_ok = verify_code(this_oop, throw_verifyerror, THREAD);
3362 + if (this_oop->is_redefining()) {
3363 + Thread::current()->set_pretend_new_universe(true);
3365 + bool verify_ok = verify_code(this_oop, throw_verifyerror, THREAD);
3366 + if (this_oop->is_redefining()) {
3367 + Thread::current()->set_pretend_new_universe(false);
3375 this_oop->set_init_state(linked);
3376 - if (JvmtiExport::should_post_class_prepare()) {
3377 + // (tw) Must check for old version in order to prevent infinite loops.
3378 + if (JvmtiExport::should_post_class_prepare() && this_oop->old_version() == NULL /* JVMTI deadlock otherwise */) {
3379 Thread *thread = THREAD;
3380 assert(thread->is_Java_thread(), "thread->is_Java_thread()");
3381 JvmtiExport::post_class_prepare((JavaThread *) thread, this_oop());
3382 @@ -571,6 +682,18 @@
3386 +bool instanceKlass::implements_interface_any_version(klassOop k) const {
3387 + k = k->klass_part()->newest_version();
3388 + if (this->newest_version() == k) return true;
3389 + assert(Klass::cast(k)->is_interface(), "should be an interface class");
3390 + for (int i = 0; i < transitive_interfaces()->length(); i++) {
3391 + if (((klassOop)transitive_interfaces()->obj_at(i))->klass_part()->newest_version() == k) {
3398 objArrayOop instanceKlass::allocate_objArray(int n, int length, TRAPS) {
3399 if (length < 0) THROW_0(vmSymbols::java_lang_NegativeArraySizeException());
3400 if (length > arrayOopDesc::max_array_length(T_OBJECT)) {
3401 @@ -691,7 +814,25 @@
3404 void instanceKlass::call_class_initializer_impl(instanceKlassHandle this_oop, TRAPS) {
3406 + ResourceMark rm(THREAD);
3407 methodHandle h_method(THREAD, this_oop->class_initializer());
3409 + if (this_oop->revision_number() != -1){
3410 + methodOop m = NULL;
3411 + if (AllowAdvancedClassRedefinition) {
3412 + m = this_oop->find_method(vmSymbols::static_transformer_name(), vmSymbols::void_method_signature());
3414 + methodHandle method(m);
3415 + if (method() != NULL && method()->is_static()) {
3416 + TRACE_RC2("Calling static transformer instead of static initializer");
3417 + h_method = method;
3418 + } else if (!((instanceKlass*)this_oop->old_version()->klass_part())->is_not_initialized()) {
3419 + // Only execute the static initializer, if it was not yet executed for the old version of the class.
3424 assert(!this_oop->is_initialized(), "we cannot initialize twice");
3425 if (TraceClassInitialization) {
3426 tty->print("%d Initializing ", call_class_initializer_impl_counter++);
3427 @@ -843,6 +984,138 @@
3431 +void instanceKlass::store_update_information(GrowableArray<int> &values) {
3432 + int *arr = NEW_C_HEAP_ARRAY(int, values.length());
3433 + for (int i=0; i<values.length(); i++) {
3434 + arr[i] = values.at(i);
3436 + set_update_information(arr);
3439 +void instanceKlass::clear_update_information() {
3440 + FREE_C_HEAP_ARRAY(int, update_information());
3441 + set_update_information(NULL);
3444 +void instanceKlass::do_fields_evolution(FieldEvolutionClosure* cl) {
3446 + assert (old_version() != NULL, "must have old version!");
3448 + klassOop old_klass_oop = old_version();
3449 + instanceKlass *old_klass = instanceKlass::cast(old_klass_oop);
3450 + instanceKlass *new_klass = this;
3452 + fieldDescriptor fd;
3453 + fieldDescriptor old_fd;
3455 + instanceKlass *cur_new_klass = new_klass;
3456 + klassOop cur_new_klass_oop = this->as_klassOop();
3458 + if (_fields_not_changed) {
3460 + class MyFieldClosure : public FieldClosure {
3462 + FieldEvolutionClosure *_cl;
3464 + MyFieldClosure(FieldEvolutionClosure *cl) {_cl = cl; }
3465 + virtual void do_field(fieldDescriptor* fd) {
3466 + _cl->do_changed_field(fd, fd);
3470 + MyFieldClosure mfc(cl);
3471 + do_nonstatic_fields(&mfc);
3474 + _fields_not_changed = true;
3477 + GrowableArray<fieldDescriptor> fds;
3482 + for (int i=0; i<cur_new_klass->fields()->length(); i+=instanceKlass::next_offset) {
3484 + fd.initialize(cur_new_klass_oop, i);
3486 + if (fd.is_static()) {
3493 + if (cur_new_klass->super() != NULL) {
3494 + cur_new_klass_oop = cur_new_klass->super();
3495 + cur_new_klass = instanceKlass::cast(cur_new_klass_oop);
3501 + GrowableArray<fieldDescriptor> sortedFds;
3503 + while (fds.length() > 0) {
3505 + int minOffset = 0x7fffffff;
3506 + int minIndex = -1;
3507 + for (int i=0; i<fds.length(); i++) {
3508 + int curOffset = fds.adr_at(i)->offset();
3509 + if (curOffset < minOffset) {
3510 + minOffset = curOffset;
3515 + sortedFds.append(fds.at(minIndex));
3516 + fds.remove_at(minIndex);
3520 + for (int i=0; i<sortedFds.length(); i++) {
3522 + fieldDescriptor &fd = *sortedFds.adr_at(i);
3525 + instanceKlass *cur_old_klass = old_klass;
3526 + klassOop cur_old_klass_oop = old_klass_oop;
3528 + for (int j=0; j<cur_old_klass->fields()->length(); j+=instanceKlass::next_offset) {
3530 + old_fd.initialize(cur_old_klass_oop, j);
3532 + if (old_fd.is_static()) {
3536 + if (old_fd.name() == fd.name() && old_fd.signature() == fd.signature()) {
3542 + if (!found && cur_old_klass->super()) {
3543 + cur_old_klass_oop = cur_old_klass->super();
3544 + cur_old_klass = instanceKlass::cast(cur_old_klass_oop);
3551 + if (old_fd.offset() != fd.offset()) {
3552 + _fields_not_changed = false;
3554 + cl->do_changed_field(&old_fd, &fd);
3556 + _fields_not_changed = false;
3557 + cl->do_new_field(&fd);
3563 void instanceKlass::do_local_static_fields(FieldClosure* cl) {
3565 int length = fields()->length();
3566 @@ -1229,6 +1502,20 @@
3570 +bool instanceKlass::update_jmethod_id(methodOop method, jmethodID newMethodID) {
3571 + size_t idnum = (size_t)method->method_idnum();
3572 + jmethodID* jmeths = methods_jmethod_ids_acquire();
3573 + size_t length; // length assigned as debugging crumb
3574 + jmethodID id = NULL;
3575 + if (jmeths != NULL && // If there is a cache
3576 + (length = (size_t)jmeths[0]) > idnum) { // and if it is long enough,
3577 + jmeths[idnum+1] = newMethodID; // Set the id (may be NULL)
3585 // Cache an itable index
3586 void instanceKlass::set_cached_itable_index(size_t idnum, int index) {
3587 @@ -1419,6 +1706,13 @@
3592 + // (tw) Hack as dependencies get wrong version of klassOop
3593 + if(this->old_version() != NULL) {
3594 + ((instanceKlass *)this->old_version()->klass_part())->remove_dependent_nmethod(nm);
3599 tty->print_cr("### %s can't find dependent nmethod:", this->external_name());
3601 @@ -2552,9 +2846,8 @@
3602 GrowableArray<PreviousVersionNode *>(2, true);
3605 - // RC_TRACE macro has an embedded ResourceMark
3606 - RC_TRACE(0x00000100, ("adding previous version ref for %s @%d, EMCP_cnt=%d",
3607 - ikh->external_name(), _previous_versions->length(), emcp_method_count));
3608 + TRACE_RC3("adding previous version ref for %s @%d, EMCP_cnt=%d",
3609 + ikh->external_name(), _previous_versions->length(), emcp_method_count);
3610 constantPoolHandle cp_h(ikh->constants());
3612 if (cp_h->is_shared()) {
3613 @@ -2570,8 +2863,7 @@
3614 if (emcp_method_count == 0) {
3615 // non-shared ConstantPool gets a weak reference
3616 pv_node = new PreviousVersionNode(cp_ref, !cp_h->is_shared(), NULL);
3617 - RC_TRACE(0x00000400,
3618 - ("add: all methods are obsolete; flushing any EMCP weak refs"));
3619 + TRACE_RC3("add: all methods are obsolete; flushing any EMCP weak refs");
3621 int local_count = 0;
3622 GrowableArray<jweak>* method_refs = new (ResourceObj::C_HEAP)
3623 @@ -2600,8 +2892,7 @@
3624 // caller is the VMThread and we are at a safepoint, this is a good
3625 // time to clear out unused weak references.
3627 - RC_TRACE(0x00000400, ("add: previous version length=%d",
3628 - _previous_versions->length()));
3629 + TRACE_RC3("add: previous version length=%d", _previous_versions->length());
3631 // skip the last entry since we just added it
3632 for (int i = _previous_versions->length() - 2; i >= 0; i--) {
3633 @@ -2626,13 +2917,12 @@
3634 // do anything special with the index.
3637 - RC_TRACE(0x00000400, ("add: previous version @%d is alive", i));
3638 + TRACE_RC3("add: previous version @%d is alive", i);
3641 GrowableArray<jweak>* method_refs = pv_node->prev_EMCP_methods();
3642 if (method_refs != NULL) {
3643 - RC_TRACE(0x00000400, ("add: previous methods length=%d",
3644 - method_refs->length()));
3645 + TRACE_RC3("add: previous methods length=%d", method_refs->length());
3646 for (int j = method_refs->length() - 1; j >= 0; j--) {
3647 jweak method_ref = method_refs->at(j);
3648 assert(method_ref != NULL, "weak method ref was unexpectedly cleared");
3649 @@ -2651,11 +2941,8 @@
3650 JNIHandles::destroy_weak_global(method_ref);
3651 method_refs->remove_at(j);
3653 - // RC_TRACE macro has an embedded ResourceMark
3654 - RC_TRACE(0x00000400,
3655 - ("add: %s(%s): previous method @%d in version @%d is alive",
3656 - method->name()->as_C_string(), method->signature()->as_C_string(),
3658 + TRACE_RC3("add: %s(%s): previous method @%d in version @%d is alive",
3659 + method->name()->as_C_string(), method->signature()->as_C_string(), j, i);
3663 @@ -2738,9 +3025,8 @@
3664 // The current RedefineClasses() call has made all EMCP
3665 // versions of this method obsolete so mark it as obsolete
3666 // and remove the weak ref.
3667 - RC_TRACE(0x00000400,
3668 - ("add: %s(%s): flush obsolete method @%d in version @%d",
3669 - m_name->as_C_string(), m_signature->as_C_string(), k, j));
3670 + TRACE_RC3("add: %s(%s): flush obsolete method @%d in version @%d",
3671 + m_name->as_C_string(), m_signature->as_C_string(), k, j);
3673 method->set_is_obsolete();
3674 JNIHandles::destroy_weak_global(method_ref);
3675 diff -r f5603a6e5042 src/share/vm/oops/instanceKlass.hpp
3676 --- a/src/share/vm/oops/instanceKlass.hpp Wed Nov 17 22:42:08 2010 -0800
3677 +++ b/src/share/vm/oops/instanceKlass.hpp Fri Dec 17 13:24:08 2010 +0100
3679 virtual void do_field(fieldDescriptor* fd) = 0;
3682 +// (tw) Iterates over the fields of the old and new class
3683 +class FieldEvolutionClosure : public StackObj {
3685 + virtual void do_new_field(fieldDescriptor* fd) = 0;
3686 + virtual void do_old_field(fieldDescriptor* fd) = 0;
3687 + virtual void do_changed_field(fieldDescriptor* old_fd, fieldDescriptor *new_fd) = 0;
3692 // If "obj" argument to constructor is NULL, prints static fields, otherwise prints non-static fields.
3693 @@ -244,6 +252,11 @@
3694 JvmtiCachedClassFieldMap* _jvmti_cached_class_field_map; // JVMTI: used during heap iteration
3695 volatile u2 _idnum_allocated_count; // JNI/JVMTI: increments with the addition of methods, old ids don't change
3697 + // (tw) Field that allows for a short-path when calculating updated fields for the second time and
3698 + // no fields changed. Testing performance impact with this, can be removed later when the update
3699 + // information is cached.
3700 + bool _fields_not_changed;
3702 // embedded Java vtable follows here
3703 // embedded Java itables follows here
3704 // embedded static fields follows here
3706 // initialization (virtuals from Klass)
3707 bool should_be_initialized() const; // means that initialize should be called
3708 void initialize(TRAPS);
3709 + void initialize_redefined_class();
3710 void link_class(TRAPS);
3711 bool link_class_or_fail(TRAPS); // returns false on failure
3712 void unlink_class();
3714 static void get_jmethod_id_length_value(jmethodID* cache, size_t idnum,
3715 size_t *length_p, jmethodID* id_p);
3716 jmethodID jmethod_id_or_null(methodOop method);
3717 + bool update_jmethod_id(methodOop method, jmethodID newMethodID);
3719 // cached itable index support
3720 void set_cached_itable_index(size_t idnum, int index);
3723 // subclass/subinterface checks
3724 bool implements_interface(klassOop k) const;
3725 + bool implements_interface_any_version(klassOop k) const;
3727 // Access to implementors of an interface. We only store the count
3728 // of implementors, and in case, there are only a few
3729 @@ -629,6 +645,10 @@
3730 void do_local_static_fields(FieldClosure* cl);
3731 void do_nonstatic_fields(FieldClosure* cl); // including inherited fields
3732 void do_local_static_fields(void f(fieldDescriptor*, TRAPS), TRAPS);
3733 + void do_fields_evolution(FieldEvolutionClosure *cl);
3734 + void store_update_information(GrowableArray<int> &values);
3735 + void clear_update_information();
3738 void methods_do(void f(methodOop method));
3739 void array_klasses_do(void f(klassOop k));
3740 diff -r f5603a6e5042 src/share/vm/oops/instanceKlassKlass.cpp
3741 --- a/src/share/vm/oops/instanceKlassKlass.cpp Wed Nov 17 22:42:08 2010 -0800
3742 +++ b/src/share/vm/oops/instanceKlassKlass.cpp Fri Dec 17 13:24:08 2010 +0100
3743 @@ -487,6 +487,28 @@
3744 instanceKlass* ik = instanceKlass::cast(klassOop(obj));
3745 klassKlass::oop_print_on(obj, st);
3747 + // (tw) Output revision number and revision numbers of older / newer and oldest / newest version of this class.
3749 + st->print(BULLET"revision: %d", ik->revision_number());
3751 + if (ik->new_version() != NULL) {
3752 + st->print(" (newer=%d)", ik->new_version()->klass_part()->revision_number());
3755 + if (ik->newest_version() != ik->new_version() && ik->newest_version() != obj) {
3756 + st->print(" (newest=%d)", ik->newest_version()->klass_part()->revision_number());
3759 + if (ik->old_version() != NULL) {
3760 + st->print(" (old=%d)", ik->old_version()->klass_part()->revision_number());
3763 + if (ik->oldest_version() != ik->old_version() && ik->oldest_version() != obj) {
3764 + st->print(" (oldest=%d)", ik->oldest_version()->klass_part()->revision_number());
3769 st->print(BULLET"instance size: %d", ik->size_helper()); st->cr();
3770 st->print(BULLET"klass size: %d", ik->object_size()); st->cr();
3771 st->print(BULLET"access: "); ik->access_flags().print_on(st); st->cr();
3774 guarantee(sib->as_klassOop()->is_klass(), "should be klass");
3775 guarantee(sib->as_klassOop()->is_perm(), "should be in permspace");
3776 - guarantee(sib->super() == super, "siblings should have same superklass");
3777 + guarantee(sib->super() == super || super->klass_part()->newest_version() == SystemDictionary::Object_klass(), "siblings should have same superklass");
3778 sib = sib->next_sibling();
3781 diff -r f5603a6e5042 src/share/vm/oops/instanceRefKlass.cpp
3782 --- a/src/share/vm/oops/instanceRefKlass.cpp Wed Nov 17 22:42:08 2010 -0800
3783 +++ b/src/share/vm/oops/instanceRefKlass.cpp Fri Dec 17 13:24:08 2010 +0100
3784 @@ -363,10 +363,13 @@
3785 instanceKlass* ik = instanceKlass::cast(k);
3787 // Check that we have the right class
3788 - debug_only(static bool first_time = true);
3789 - assert(k == SystemDictionary::Reference_klass() && first_time,
3790 - "Invalid update of maps");
3791 - debug_only(first_time = false);
3793 + // (tw) Asserts no longer valid for class redefinition
3794 + // debug_only(static bool first_time = true);
3796 + //assert(k == SystemDictionary::Reference_klass() && first_time,
3797 + // "Invalid update of maps");
3798 + //debug_only(first_time = false);
3799 assert(ik->nonstatic_oop_map_count() == 1, "just checking");
3801 OopMapBlock* map = ik->start_of_nonstatic_oop_maps();
3802 diff -r f5603a6e5042 src/share/vm/oops/klass.cpp
3803 --- a/src/share/vm/oops/klass.cpp Wed Nov 17 22:42:08 2010 -0800
3804 +++ b/src/share/vm/oops/klass.cpp Fri Dec 17 13:24:08 2010 +0100
3809 +void Klass::update_supers_to_newest_version() {
3811 + if (super() != NULL) set_super(super()->klass_part()->newest_version());
3813 + for (uint i=0; i<primary_super_limit(); i++) {
3814 + klassOop cur = _primary_supers[i];
3815 + if (cur != NULL) {
3816 + _primary_supers[i] = cur->klass_part()->newest_version();
3820 + // Scan the array-of-objects
3821 + int cnt = secondary_supers()->length();
3822 + for (int i = 0; i < cnt; i++) {
3823 + klassOop cur = (klassOop)secondary_supers()->obj_at(i);
3824 + if (cur != NULL) {
3825 + secondary_supers()->obj_at_put(i, cur->klass_part()->newest_version());
3829 bool Klass::search_secondary_supers(klassOop k) const {
3830 // Put some extra logic here out-of-line, before the search proper.
3831 // This cuts down the size of the inline method.
3832 @@ -145,6 +165,13 @@
3833 kl->set_alloc_count(0);
3834 kl->set_alloc_size(0);
3836 + kl->set_redefinition_flags(Klass::NoRedefinition);
3837 + kl->set_redefining(false);
3838 + kl->set_new_version(NULL);
3839 + kl->set_old_version(NULL);
3840 + kl->set_redefinition_index(-1);
3841 + kl->set_revision_number(-1);
3843 kl->set_prototype_header(markOopDesc::prototype());
3844 kl->set_biased_lock_revocation_count(0);
3845 kl->set_last_biased_lock_bulk_revocation_time(0);
3848 oop_store_without_check((oop*) &_primary_supers[0], (oop) this->as_klassOop());
3849 assert(super_depth() == 0, "Object must already be initialized properly");
3850 - } else if (k != super() || k == SystemDictionary::Object_klass()) {
3851 + } else if (k != super() || k->klass_part()->super() == NULL) {
3852 assert(super() == NULL || super() == SystemDictionary::Object_klass(),
3853 "initialize this only once to a non-trivial value");
3855 diff -r f5603a6e5042 src/share/vm/oops/klass.hpp
3856 --- a/src/share/vm/oops/klass.hpp Wed Nov 17 22:42:08 2010 -0800
3857 +++ b/src/share/vm/oops/klass.hpp Fri Dec 17 13:24:08 2010 +0100
3859 void* operator new(size_t ignored, KlassHandle& klass, int size, TRAPS);
3862 +template<class L, class R> class Pair;
3864 class Klass : public Klass_vtbl {
3865 friend class VMStructs;
3866 @@ -198,6 +199,31 @@
3867 oop* oop_block_beg() const { return adr_secondary_super_cache(); }
3868 oop* oop_block_end() const { return adr_next_sibling() + 1; }
3870 + // (tw) Different class redefinition flags of code evolution.
3871 + enum RedefinitionFlags {
3873 + // This class is not redefined at all!
3876 + // There are changes to the class meta data.
3879 + // The size of the class meta data changes.
3880 + ModifyClassSize = ModifyClass << 1,
3882 + // There are change to the instance format.
3883 + ModifyInstances = ModifyClassSize << 1,
3885 + // The size of instances changes.
3886 + ModifyInstanceSize = ModifyInstances << 1,
3888 + // A super type of this class is removed.
3889 + RemoveSuperType = ModifyInstanceSize << 1,
3891 + // This class (or one of its super classes) has an instance transformer method.
3892 + HasInstanceTransformer = RemoveSuperType << 1,
3897 // The oop block. All oop fields must be declared here and only oop fields
3898 @@ -217,6 +243,10 @@
3903 + klassOop _old_version;
3905 + klassOop _new_version;
3906 // Class name. Instance classes: java/lang/String, etc. Array classes: [I,
3907 // [Ljava/lang/String;, etc. Set to zero for all other kinds of classes.
3909 @@ -232,6 +262,16 @@
3910 jint _modifier_flags; // Processed access flags, for use by Class.getModifiers.
3911 AccessFlags _access_flags; // Access flags. The class/interface distinction is stored here.
3913 + // (tw) Non-oop fields for enhanced class redefinition
3914 + jint _revision_number; // The revision number for redefined classes
3915 + jint _redefinition_index; // Index of this class when performing the redefinition
3916 + bool _subtype_changed;
3917 + int _redefinition_flags; // Level of class redefinition
3918 + bool _is_copying_backwards; // Does the class need to copy fields backwards? => possibly overwrite itself?
3919 + int * _update_information; // Update information
3920 + Pair<int, klassOop> * _type_check_information; // Offsets of object fields that need a type check
3921 + bool _is_redefining;
3924 int _verify_count; // to avoid redundant verifies
3926 @@ -279,6 +319,75 @@
3927 klassOop secondary_super_cache() const { return _secondary_super_cache; }
3928 void set_secondary_super_cache(klassOop k) { oop_store_without_check((oop*) &_secondary_super_cache, (oop) k); }
3930 + // BEGIN class redefinition utilities
3932 + // double links between new and old version of a class
3933 + klassOop old_version() const { return _old_version; }
3934 + void set_old_version(klassOop klass) { assert(_old_version == NULL || klass == NULL, "Can only be set once!"); _old_version = klass; }
3935 + klassOop new_version() const { return _new_version; }
3936 + void set_new_version(klassOop klass) { assert(_new_version == NULL || klass == NULL, "Can only be set once!"); _new_version = klass; }
3938 + // A subtype of this class is no longer a subtype
3939 + bool has_subtype_changed() const { return _subtype_changed; }
3940 + void set_subtype_changed(bool b) { assert(is_newest_version() || new_version()->klass_part()->is_newest_version(), "must be newest or second newest version");
3941 + _subtype_changed = b; }
3942 + // state of being redefined
3943 + int redefinition_index() const { return _redefinition_index; }
3944 + void set_redefinition_index(int index) { _redefinition_index = index; }
3945 + void set_redefining(bool b) { _is_redefining = b; }
3946 + bool is_redefining() const { return _is_redefining; }
3947 + int redefinition_flags() const { return _redefinition_flags; }
3948 + bool check_redefinition_flag(int flags) const { return (_redefinition_flags & flags) != 0; }
3949 + void set_redefinition_flags(int flags) { _redefinition_flags = flags; }
3950 + bool is_copying_backwards() const { return _is_copying_backwards; }
3951 + void set_copying_backwards(bool b) { _is_copying_backwards = b; }
3953 + // update information
3954 + int *update_information() const { return _update_information; }
3955 + void set_update_information(int *info) { _update_information = info; }
3956 + Pair<int, klassOop> *type_check_information() const { return _type_check_information; }
3957 + void set_type_check_information(Pair<int, klassOop> *info) { _type_check_information = info; }
3959 + bool is_same_or_older_version(klassOop klass) const {
3960 + if (Klass::cast(klass) == this) { return true; }
3961 + else if (_old_version == NULL) { return false; }
3962 + else { return _old_version->klass_part()->is_same_or_older_version(klass); }
3965 + // Revision number for redefined classes, -1 for originally loaded classes
3966 + jint revision_number() const {
3967 + return _revision_number;
3970 + bool was_redefined() const {
3971 + return _revision_number != -1;
3974 + void set_revision_number(jint number) {
3975 + _revision_number = number;
3978 + klassOop oldest_version() const {
3979 + if (_old_version == NULL) { return this->as_klassOop(); }
3980 + else { return _old_version->klass_part()->oldest_version(); };
3983 + klassOop newest_version() const {
3984 + if (_new_version == NULL) { return this->as_klassOop(); }
3985 + else { return _new_version->klass_part()->newest_version(); };
3988 + klassOop active_version() const {
3989 + if (_new_version == NULL || _new_version->klass_part()->is_redefining()) { return this->as_klassOop(); assert(!this->is_redefining(), "just checking"); }
3990 + else { return _new_version->klass_part()->active_version(); };
3993 + bool is_newest_version() const {
3994 + return _new_version == NULL;
3997 + // END class redefinition utilities
3999 objArrayOop secondary_supers() const { return _secondary_supers; }
4000 void set_secondary_supers(objArrayOop k) { oop_store_without_check((oop*) &_secondary_supers, (oop) k); }
4003 void set_next_sibling(klassOop s);
4005 oop* adr_super() const { return (oop*)&_super; }
4006 + oop* adr_old_version() const { return (oop*)&_old_version; }
4007 + oop* adr_new_version() const { return (oop*)&_new_version; }
4008 oop* adr_primary_supers() const { return (oop*)&_primary_supers[0]; }
4009 oop* adr_secondary_super_cache() const { return (oop*)&_secondary_super_cache; }
4010 oop* adr_secondary_supers()const { return (oop*)&_secondary_supers; }
4012 return search_secondary_supers(k);
4015 + void update_supers_to_newest_version();
4016 bool search_secondary_supers(klassOop k) const;
4018 // Find LCA in class hierarchy
4019 diff -r f5603a6e5042 src/share/vm/oops/klassKlass.cpp
4020 --- a/src/share/vm/oops/klassKlass.cpp Wed Nov 17 22:42:08 2010 -0800
4021 +++ b/src/share/vm/oops/klassKlass.cpp Fri Dec 17 13:24:08 2010 +0100
4023 Klass* k = Klass::cast(klassOop(obj));
4024 // If we are alive it is valid to keep our superclass and subtype caches alive
4025 MarkSweep::mark_and_push(k->adr_super());
4026 + MarkSweep::mark_and_push(k->adr_old_version());
4027 + MarkSweep::mark_and_push(k->adr_new_version());
4028 for (juint i = 0; i < Klass::primary_super_limit(); i++)
4029 MarkSweep::mark_and_push(k->adr_primary_supers()+i);
4030 MarkSweep::mark_and_push(k->adr_secondary_super_cache());
4032 Klass* k = Klass::cast(klassOop(obj));
4033 // If we are alive it is valid to keep our superclass and subtype caches alive
4034 PSParallelCompact::mark_and_push(cm, k->adr_super());
4035 + PSParallelCompact::mark_and_push(cm, k->adr_old_version());
4036 + PSParallelCompact::mark_and_push(cm, k->adr_new_version());
4037 for (juint i = 0; i < Klass::primary_super_limit(); i++)
4038 PSParallelCompact::mark_and_push(cm, k->adr_primary_supers()+i);
4039 PSParallelCompact::mark_and_push(cm, k->adr_secondary_super_cache());
4041 int size = oop_size(obj);
4042 Klass* k = Klass::cast(klassOop(obj));
4043 blk->do_oop(k->adr_super());
4044 + blk->do_oop(k->adr_old_version());
4045 + blk->do_oop(k->adr_new_version());
4046 for (juint i = 0; i < Klass::primary_super_limit(); i++)
4047 blk->do_oop(k->adr_primary_supers()+i);
4048 blk->do_oop(k->adr_secondary_super_cache());
4049 @@ -114,6 +120,10 @@
4051 adr = k->adr_super();
4052 if (mr.contains(adr)) blk->do_oop(adr);
4053 + adr = k->adr_old_version();
4054 + if (mr.contains(adr)) blk->do_oop(adr);
4055 + adr = k->adr_new_version();
4056 + if (mr.contains(adr)) blk->do_oop(adr);
4057 for (juint i = 0; i < Klass::primary_super_limit(); i++) {
4058 adr = k->adr_primary_supers()+i;
4059 if (mr.contains(adr)) blk->do_oop(adr);
4061 Klass* k = Klass::cast(klassOop(obj));
4063 MarkSweep::adjust_pointer(k->adr_super());
4064 + MarkSweep::adjust_pointer(k->adr_new_version());
4065 + MarkSweep::adjust_pointer(k->adr_old_version());
4066 for (juint i = 0; i < Klass::primary_super_limit(); i++)
4067 MarkSweep::adjust_pointer(k->adr_primary_supers()+i);
4068 MarkSweep::adjust_pointer(k->adr_secondary_super_cache());
4069 diff -r f5603a6e5042 src/share/vm/oops/klassVtable.cpp
4070 --- a/src/share/vm/oops/klassVtable.cpp Wed Nov 17 22:42:08 2010 -0800
4071 +++ b/src/share/vm/oops/klassVtable.cpp Fri Dec 17 13:24:08 2010 +0100
4073 vtable_length = Universe::base_vtable_size();
4076 - if (super == NULL && !Universe::is_bootstrapping() &&
4077 + // (tw) TODO: Check if we can relax the condition on a fixed base vtable size
4078 + /*if (super == NULL && !Universe::is_bootstrapping() &&
4079 vtable_length != Universe::base_vtable_size()) {
4080 // Someone is attempting to redefine java.lang.Object incorrectly. The
4081 // only way this should happen is from
4083 vtable_length = Universe::base_vtable_size();
4085 assert(super != NULL || vtable_length == Universe::base_vtable_size(),
4086 - "bad vtable size for class Object");
4087 + "bad vtable size for class Object");*/
4088 assert(vtable_length % vtableEntry::size() == 0, "bad vtable length");
4089 - assert(vtable_length >= Universe::base_vtable_size(), "vtable too small");
4090 + //assert(vtable_length >= Universe::base_vtable_size(), "vtable too small");
4093 int klassVtable::index_of(methodOop m, int len) const {
4094 @@ -611,17 +612,13 @@
4095 if (unchecked_method_at(index) == old_method) {
4096 put_method_at(new_method, index);
4098 - if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
4100 if (!(*trace_name_printed)) {
4101 - // RC_TRACE_MESG macro has an embedded ResourceMark
4102 - RC_TRACE_MESG(("adjust: name=%s",
4103 - Klass::cast(old_method->method_holder())->external_name()));
4104 + TRACE_RC4("adjust: name=%s", Klass::cast(old_method->method_holder())->external_name());
4105 *trace_name_printed = true;
4107 - // RC_TRACE macro has an embedded ResourceMark
4108 - RC_TRACE(0x00100000, ("vtable method update: %s(%s)",
4109 - new_method->name()->as_C_string(),
4110 - new_method->signature()->as_C_string()));
4111 + TRACE_RC4("vtable method update: %s(%s)", new_method->name()->as_C_string(),
4112 + new_method->signature()->as_C_string());
4116 @@ -994,17 +991,13 @@
4117 if (ime->method() == old_method) {
4118 ime->initialize(new_method);
4120 - if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
4122 if (!(*trace_name_printed)) {
4123 - // RC_TRACE_MESG macro has an embedded ResourceMark
4124 - RC_TRACE_MESG(("adjust: name=%s",
4125 - Klass::cast(old_method->method_holder())->external_name()));
4126 + TRACE_RC4("adjust: name=%s", Klass::cast(old_method->method_holder())->external_name());
4127 *trace_name_printed = true;
4129 - // RC_TRACE macro has an embedded ResourceMark
4130 - RC_TRACE(0x00200000, ("itable method update: %s(%s)",
4131 - new_method->name()->as_C_string(),
4132 - new_method->signature()->as_C_string()));
4133 + TRACE_RC4("itable method update: %s(%s)", new_method->name()->as_C_string(),
4134 + new_method->signature()->as_C_string());
4138 @@ -1198,6 +1191,7 @@
4140 void klassVtable::verify_against(outputStream* st, klassVtable* vt, int index) {
4141 vtableEntry* vte = &vt->table()[index];
4142 + if (vte->method() == NULL || table()[index].method() == NULL) return;
4143 if (vte->method()->name() != table()[index].method()->name() ||
4144 vte->method()->signature() != table()[index].method()->signature()) {
4145 fatal("mismatched name/signature of vtable entries");
4146 @@ -1217,6 +1211,8 @@
4148 void vtableEntry::verify(klassVtable* vt, outputStream* st) {
4149 NOT_PRODUCT(FlagSetting fs(IgnoreLockingAssertions, true));
4150 + // (tw) TODO: Check: Does not hold?
4151 + if (method() != NULL) {
4152 assert(method() != NULL, "must have set method");
4154 // we sub_type, because it could be a miranda method
4155 @@ -1224,7 +1220,13 @@
4159 - fatal(err_msg("vtableEntry " PTR_FORMAT ": method is from subclass", this));
4160 + klassOop first_klass = vt->klass()();
4161 + klassOop second_klass = method()->method_holder();
4162 + // (tw) the following fatal does not work for old versions of classes
4163 + if (first_klass->klass_part()->is_newest_version()) {
4164 + //fatal1("vtableEntry %#lx: method is from subclass", this);
4170 @@ -1232,7 +1234,7 @@
4172 void vtableEntry::print() {
4174 - tty->print("vtableEntry %s: ", method()->name()->as_C_string());
4175 + tty->print("vtableEntry %s: ", (method() == NULL) ? "null" : method()->name()->as_C_string());
4177 tty->print("m %#lx ", (address)method());
4179 @@ -1304,7 +1306,7 @@
4180 for (int i = 0; i < length(); i++) {
4181 methodOop m = unchecked_method_at(i);
4183 - if (m->is_old()) {
4184 + if (m->is_old() || !m->method_holder()->klass_part()->is_newest_version()) {
4188 diff -r f5603a6e5042 src/share/vm/oops/methodKlass.cpp
4189 --- a/src/share/vm/oops/methodKlass.cpp Wed Nov 17 22:42:08 2010 -0800
4190 +++ b/src/share/vm/oops/methodKlass.cpp Fri Dec 17 13:24:08 2010 +0100
4192 m->set_adapter_entry(NULL);
4193 m->clear_code(); // from_c/from_i get set to c2i/i2i
4195 + m->set_forward_method(NULL);
4196 + m->set_new_version(NULL);
4197 + m->set_old_version(NULL);
4199 if (access_flags.is_native()) {
4200 m->clear_native_function();
4201 m->set_signature_handler(NULL);
4203 // Performance tweak: We skip iterating over the klass pointer since we
4204 // know that Universe::methodKlassObj never moves.
4205 MarkSweep::mark_and_push(m->adr_constMethod());
4206 + MarkSweep::mark_and_push(m->adr_forward_method());
4207 + MarkSweep::mark_and_push(m->adr_new_version());
4208 + MarkSweep::mark_and_push(m->adr_old_version());
4209 MarkSweep::mark_and_push(m->adr_constants());
4210 if (m->method_data() != NULL) {
4211 MarkSweep::mark_and_push(m->adr_method_data());
4213 // Performance tweak: We skip iterating over the klass pointer since we
4214 // know that Universe::methodKlassObj never moves.
4215 PSParallelCompact::mark_and_push(cm, m->adr_constMethod());
4216 + PSParallelCompact::mark_and_push(cm, m->adr_forward_method());
4217 + PSParallelCompact::mark_and_push(cm, m->adr_new_version());
4218 + PSParallelCompact::mark_and_push(cm, m->adr_old_version());
4219 PSParallelCompact::mark_and_push(cm, m->adr_constants());
4221 if (m->method_data() != NULL) {
4223 // Performance tweak: We skip iterating over the klass pointer since we
4224 // know that Universe::methodKlassObj never moves
4225 blk->do_oop(m->adr_constMethod());
4226 + blk->do_oop(m->adr_forward_method());
4227 + blk->do_oop(m->adr_new_version());
4228 + blk->do_oop(m->adr_old_version());
4229 blk->do_oop(m->adr_constants());
4230 if (m->method_data() != NULL) {
4231 blk->do_oop(m->adr_method_data());
4232 @@ -157,6 +170,12 @@
4234 adr = m->adr_constMethod();
4235 if (mr.contains(adr)) blk->do_oop(adr);
4236 + adr = m->adr_new_version();
4237 + if (mr.contains(adr)) blk->do_oop(adr);
4238 + adr = m->adr_forward_method();
4239 + if (mr.contains(adr)) blk->do_oop(adr);
4240 + adr = m->adr_old_version();
4241 + if (mr.contains(adr)) blk->do_oop(adr);
4242 adr = m->adr_constants();
4243 if (mr.contains(adr)) blk->do_oop(adr);
4244 if (m->method_data() != NULL) {
4246 // Performance tweak: We skip iterating over the klass pointer since we
4247 // know that Universe::methodKlassObj never moves.
4248 MarkSweep::adjust_pointer(m->adr_constMethod());
4249 + MarkSweep::adjust_pointer(m->adr_forward_method());
4250 + MarkSweep::adjust_pointer(m->adr_new_version());
4251 + MarkSweep::adjust_pointer(m->adr_old_version());
4252 MarkSweep::adjust_pointer(m->adr_constants());
4253 if (m->method_data() != NULL) {
4254 MarkSweep::adjust_pointer(m->adr_method_data());
4256 assert(obj->is_method(), "should be method");
4257 methodOop m = methodOop(obj);
4258 PSParallelCompact::adjust_pointer(m->adr_constMethod());
4259 + PSParallelCompact::adjust_pointer(m->adr_new_version());
4260 + PSParallelCompact::adjust_pointer(m->adr_old_version());
4261 PSParallelCompact::adjust_pointer(m->adr_constants());
4263 if (m->method_data() != NULL) {
4264 @@ -210,6 +234,12 @@
4266 p = m->adr_constMethod();
4267 PSParallelCompact::adjust_pointer(p, beg_addr, end_addr);
4268 + p = m->adr_forward_method();
4269 + PSParallelCompact::adjust_pointer(p, beg_addr, end_addr);
4270 + p = m->adr_new_version();
4271 + PSParallelCompact::adjust_pointer(p, beg_addr, end_addr);
4272 + p = m->adr_old_version();
4273 + PSParallelCompact::adjust_pointer(p, beg_addr, end_addr);
4274 p = m->adr_constants();
4275 PSParallelCompact::adjust_pointer(p, beg_addr, end_addr);
4277 @@ -234,7 +264,18 @@
4278 methodOop m = methodOop(obj);
4279 // get the effect of PrintOopAddress, always, for methods:
4280 st->print_cr(" - this oop: "INTPTR_FORMAT, (intptr_t)m);
4281 - st->print (" - method holder: "); m->method_holder()->print_value_on(st); st->cr();
4282 + st->print (" - method holder: "); m->method_holder()->print_value_on(st);
4284 + if (m->method_holder()->klass_part()->new_version() != NULL) {
4285 + st->print(" (old)");
4289 + st->print_cr(" - is obsolete: %d", (int)(m->is_obsolete()));
4290 + st->print_cr(" - is old: %d", (int)(m->is_old()));
4291 + st->print_cr(" - new version: %d", (int)(m->new_version()));
4292 + st->print_cr(" - old version: %d", (int)(m->old_version()));
4293 + st->print_cr(" - holder revision: %d", m->method_holder()->klass_part()->revision_number());
4294 st->print (" - constants: "INTPTR_FORMAT" ", (address)m->constants());
4295 m->constants()->print_value_on(st); st->cr();
4296 st->print (" - access: 0x%x ", m->access_flags().as_int()); m->access_flags().print_on(st); st->cr();
4297 diff -r f5603a6e5042 src/share/vm/oops/methodOop.cpp
4298 --- a/src/share/vm/oops/methodOop.cpp Wed Nov 17 22:42:08 2010 -0800
4299 +++ b/src/share/vm/oops/methodOop.cpp Fri Dec 17 13:24:08 2010 +0100
4301 // Reset correct method/const method, method size, and parameter info
4302 newcm->set_method(newm());
4303 newm->set_constMethod(newcm);
4304 + newm->set_forward_method(newm->forward_method());
4305 + newm->set_new_version(newm->new_version());
4306 + newm->set_old_version(newm->old_version());
4307 assert(newcm->method() == newm(), "check");
4308 newm->constMethod()->set_code_size(new_code_length);
4309 newm->constMethod()->set_constMethod_size(new_const_method_size);
4310 diff -r f5603a6e5042 src/share/vm/oops/methodOop.hpp
4311 --- a/src/share/vm/oops/methodOop.hpp Wed Nov 17 22:42:08 2010 -0800
4312 +++ b/src/share/vm/oops/methodOop.hpp Fri Dec 17 13:24:08 2010 +0100
4314 AccessFlags _access_flags; // Access flags
4315 int _vtable_index; // vtable index of this method (see VtableIndexFlag)
4316 // note: can have vtables with >2**16 elements (because of inheritance)
4317 + // (tw) Newer version of method available?
4318 + methodOop _forward_method;
4319 + methodOop _new_version;
4320 + methodOop _old_version;
4323 int _result_index; // C++ interpreter needs for converting results to/from stack
4325 @@ -150,6 +155,32 @@
4326 int name_index() const { return constMethod()->name_index(); }
4327 void set_name_index(int index) { constMethod()->set_name_index(index); }
4329 + methodOop forward_method() const {return _forward_method; }
4330 + void set_forward_method(methodOop m) { _forward_method = m; }
4331 + bool has_forward_method() const { return forward_method() != NULL; }
4332 + methodOop new_version() const {return _new_version; }
4333 + void set_new_version(methodOop m) { _new_version = m; }
4334 + methodOop newest_version() { if(_new_version == NULL) return this; else return new_version()->newest_version(); }
4336 + methodOop old_version() const {return _old_version; };
4337 + void set_old_version(methodOop m) {
4339 + _old_version = NULL;
4343 + assert(_old_version == NULL, "may only be set once");
4344 + assert(this->code_size() == m->code_size(), "must have same code length");
4348 + methodOop oldest_version() const {
4349 + if(_old_version == NULL) return (methodOop)this;
4351 + return old_version()->oldest_version();
4356 symbolOop signature() const { return _constants->symbol_at(signature_index()); }
4357 int signature_index() const { return constMethod()->signature_index(); }
4360 // Garbage collection support
4361 oop* adr_constMethod() const { return (oop*)&_constMethod; }
4362 + oop* adr_forward_method() const { return (oop*)&_forward_method; }
4363 + oop* adr_new_version() const { return (oop*)&_new_version; }
4364 + oop* adr_old_version() const { return (oop*)&_old_version; }
4365 oop* adr_constants() const { return (oop*)&_constants; }
4366 oop* adr_method_data() const { return (oop*)&_method_data; }
4368 diff -r f5603a6e5042 src/share/vm/oops/oop.hpp
4369 --- a/src/share/vm/oops/oop.hpp Wed Nov 17 22:42:08 2010 -0800
4370 +++ b/src/share/vm/oops/oop.hpp Fri Dec 17 13:24:08 2010 +0100
4372 narrowOop* compressed_klass_addr();
4374 void set_klass(klassOop k);
4375 + void set_klass_no_check(klassOop k);
4377 // For klass field compression
4378 int klass_gap() const;
4380 bool is_objArray() const;
4381 bool is_symbol() const;
4382 bool is_klass() const;
4383 + bool is_instanceKlass() const;
4384 bool is_thread() const;
4385 bool is_method() const;
4386 bool is_constMethod() const;
4387 diff -r f5603a6e5042 src/share/vm/oops/oop.inline.hpp
4388 --- a/src/share/vm/oops/oop.inline.hpp Wed Nov 17 22:42:08 2010 -0800
4389 +++ b/src/share/vm/oops/oop.inline.hpp Fri Dec 17 13:24:08 2010 +0100
4394 +inline void oopDesc::set_klass_no_check(klassOop k) {
4395 + if (UseCompressedOops) {
4396 + oop_store_without_check(compressed_klass_addr(), (oop)k);
4398 + oop_store_without_check(klass_addr(), (oop) k);
4402 inline int oopDesc::klass_gap() const {
4403 return *(int*)(((intptr_t)this) + klass_gap_offset_in_bytes());
4406 inline bool oopDesc::is_javaArray() const { return blueprint()->oop_is_javaArray(); }
4407 inline bool oopDesc::is_symbol() const { return blueprint()->oop_is_symbol(); }
4408 inline bool oopDesc::is_klass() const { return blueprint()->oop_is_klass(); }
4409 +inline bool oopDesc::is_instanceKlass() const { return blueprint()->oop_is_instanceKlass(); }
4410 inline bool oopDesc::is_thread() const { return blueprint()->oop_is_thread(); }
4411 inline bool oopDesc::is_method() const { return blueprint()->oop_is_method(); }
4412 inline bool oopDesc::is_constMethod() const { return blueprint()->oop_is_constMethod(); }
4413 diff -r f5603a6e5042 src/share/vm/prims/jni.cpp
4414 --- a/src/share/vm/prims/jni.cpp Wed Nov 17 22:42:08 2010 -0800
4415 +++ b/src/share/vm/prims/jni.cpp Fri Dec 17 13:24:08 2010 +0100
4419 klassOop k = SystemDictionary::resolve_from_stream(class_name, class_loader,
4420 - Handle(), &st, true,
4421 + Handle(), &st, true, KlassHandle(),
4424 if (TraceClassResolution && k != NULL) {
4425 diff -r f5603a6e5042 src/share/vm/prims/jvm.cpp
4426 --- a/src/share/vm/prims/jvm.cpp Wed Nov 17 22:42:08 2010 -0800
4427 +++ b/src/share/vm/prims/jvm.cpp Fri Dec 17 13:24:08 2010 +0100
4429 Handle protection_domain (THREAD, JNIHandles::resolve(pd));
4430 klassOop k = SystemDictionary::resolve_from_stream(class_name, class_loader,
4431 protection_domain, &st,
4433 + verify != 0, KlassHandle(),
4436 if (TraceClassResolution && k != NULL) {
4437 diff -r f5603a6e5042 src/share/vm/prims/jvmtiClassFileReconstituter.cpp
4438 --- a/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Wed Nov 17 22:42:08 2010 -0800
4439 +++ b/src/share/vm/prims/jvmtiClassFileReconstituter.cpp Fri Dec 17 13:24:08 2010 +0100
4441 constMethodHandle const_method(thread(), method->constMethod());
4442 u2 line_num_cnt = 0;
4443 int stackmap_len = 0;
4444 + int local_variable_table_length = 0;
4446 // compute number and length of attributes -- FIXME: for now no LVT
4448 @@ -154,6 +155,25 @@
4449 attr_size += 2 + 4 + stackmap_len;
4452 + if (method->has_localvariable_table()) {
4453 + local_variable_table_length = method->localvariable_table_length();
4455 + if (local_variable_table_length != 0) {
4456 + // Compute the size of the local variable table attribute (VM stores raw):
4457 + // LocalVariableTable_attribute {
4458 + // u2 attribute_name_index;
4459 + // u4 attribute_length;
4460 + // u2 local_variable_table_length;
4465 + // u2 descriptor_index;
4468 + attr_size += 2 + 4 + 2 + local_variable_table_length * (2 + 2 + 2 + 2 + 2);
4472 typeArrayHandle exception_table(thread(), const_method->exception_table());
4473 int exception_table_length = exception_table->length();
4474 @@ -188,6 +208,10 @@
4475 write_stackmap_table_attribute(method, stackmap_len);
4478 + if (local_variable_table_length != 0) {
4479 + write_local_variable_table_attribute(method, local_variable_table_length);
4482 // FIXME: write LVT attribute
4485 @@ -355,6 +379,36 @@
4489 +// Write LineNumberTable attribute
4490 +// JVMSpec| LocalVariableTable_attribute {
4491 +// JVMSpec| u2 attribute_name_index;
4492 +// JVMSpec| u4 attribute_length;
4493 +// JVMSpec| u2 local_variable_table_length;
4494 +// JVMSpec| { u2 start_pc;
4495 +// JVMSpec| u2 length;
4496 +// JVMSpec| u2 name_index;
4497 +// JVMSpec| u2 descriptor_index;
4498 +// JVMSpec| u2 index;
4499 +// JVMSpec| } local_variable_table[local_variable_table_length];
4501 +void JvmtiClassFileReconstituter::write_local_variable_table_attribute(methodHandle method, u2 num_entries) {
4502 + write_attribute_name_index("LocalVariableTable");
4503 + write_u4(2 + num_entries * (2 + 2 + 2 + 2 + 2));
4504 + write_u2(num_entries);
4506 + assert(method->localvariable_table_length() == num_entries, "just checking");
4508 + LocalVariableTableElement *elem = method->localvariable_table_start();
4509 + for (int j=0; j<method->localvariable_table_length(); j++) {
4510 + write_u2(elem->start_bci);
4511 + write_u2(elem->length);
4512 + write_u2(elem->name_cp_index);
4513 + write_u2(elem->descriptor_cp_index);
4514 + write_u2(elem->slot);
4519 // Write stack map table attribute
4520 // JSR-202| StackMapTable_attribute {
4521 // JSR-202| u2 attribute_name_index;
4522 diff -r f5603a6e5042 src/share/vm/prims/jvmtiClassFileReconstituter.hpp
4523 --- a/src/share/vm/prims/jvmtiClassFileReconstituter.hpp Wed Nov 17 22:42:08 2010 -0800
4524 +++ b/src/share/vm/prims/jvmtiClassFileReconstituter.hpp Fri Dec 17 13:24:08 2010 +0100
4526 void write_source_debug_extension_attribute();
4527 u2 line_number_table_entries(methodHandle method);
4528 void write_line_number_table_attribute(methodHandle method, u2 num_entries);
4529 + void write_local_variable_table_attribute(methodHandle method, u2 num_entries);
4530 void write_stackmap_table_attribute(methodHandle method, int stackmap_table_len);
4531 u2 inner_classes_attribute_length();
4532 void write_inner_classes_attribute(int length);
4533 diff -r f5603a6e5042 src/share/vm/prims/jvmtiEnv.cpp
4534 --- a/src/share/vm/prims/jvmtiEnv.cpp Wed Nov 17 22:42:08 2010 -0800
4535 +++ b/src/share/vm/prims/jvmtiEnv.cpp Fri Dec 17 13:24:08 2010 +0100
4536 @@ -240,7 +240,10 @@
4537 class_definitions[index].klass = jcls;
4539 VM_RedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_retransform);
4540 - VMThread::execute(&op);
4542 + MutexLocker sd_mutex(RedefineClasses_lock);
4543 + VMThread::execute(&op);
4545 return (op.check_error());
4546 } /* end RetransformClasses */
4548 @@ -249,9 +252,12 @@
4549 // class_definitions - pre-checked for NULL
4551 JvmtiEnv::RedefineClasses(jint class_count, const jvmtiClassDefinition* class_definitions) {
4552 -//TODO: add locking
4554 VM_RedefineClasses op(class_count, class_definitions, jvmti_class_load_kind_redefine);
4555 - VMThread::execute(&op);
4557 + MutexLocker sd_mutex(RedefineClasses_lock);
4558 + VMThread::execute(&op);
4560 return (op.check_error());
4561 } /* end RedefineClasses */
4563 diff -r f5603a6e5042 src/share/vm/prims/jvmtiExport.cpp
4564 --- a/src/share/vm/prims/jvmtiExport.cpp Wed Nov 17 22:42:08 2010 -0800
4565 +++ b/src/share/vm/prims/jvmtiExport.cpp Fri Dec 17 13:24:08 2010 +0100
4568 void JvmtiExport::post_pending_compiled_method_unload_events() {
4569 JavaThread* self = JavaThread::current();
4570 - assert(!self->owns_locks(), "can't hold locks");
4571 + assert(!self->owns_locks_but_redefine_classes_lock(), "can't hold locks");
4573 // Indicates if this is the first activiation of this function.
4574 // In theory the profiler's callback could call back into VM and provoke
4575 @@ -2392,7 +2392,7 @@
4576 // iterate over any code blob descriptors collected and post a
4577 // DYNAMIC_CODE_GENERATED event to the profiler.
4578 JvmtiDynamicCodeEventCollector::~JvmtiDynamicCodeEventCollector() {
4579 - assert(!JavaThread::current()->owns_locks(), "all locks must be released to post deferred events");
4580 + assert(!JavaThread::current()->owns_locks_but_redefine_classes_lock(), "all locks must be released to post deferred events");
4581 // iterate over any code blob descriptors that we collected
4582 if (_code_blobs != NULL) {
4583 for (int i=0; i<_code_blobs->length(); i++) {
4584 diff -r f5603a6e5042 src/share/vm/prims/jvmtiImpl.cpp
4585 --- a/src/share/vm/prims/jvmtiImpl.cpp Wed Nov 17 22:42:08 2010 -0800
4586 +++ b/src/share/vm/prims/jvmtiImpl.cpp Fri Dec 17 13:24:08 2010 +0100
4588 void JvmtiBreakpoint::each_method_version_do(method_action meth_act) {
4589 ((methodOopDesc*)_method->*meth_act)(_bci);
4591 + // (tw) TODO: Check how we can implement this differently here!
4593 // add/remove breakpoint to/from versions of the method that
4594 // are EMCP. Directly or transitively obsolete methods are
4595 // not saved in the PreviousVersionInfo.
4596 @@ -293,10 +295,10 @@
4597 for (int i = methods->length() - 1; i >= 0; i--) {
4598 methodHandle method = methods->at(i);
4599 if (method->name() == m_name && method->signature() == m_signature) {
4600 - RC_TRACE(0x00000800, ("%sing breakpoint in %s(%s)",
4601 + TRACE_RC3("%sing breakpoint in %s(%s)",
4602 meth_act == &methodOopDesc::set_breakpoint ? "sett" : "clear",
4603 method->name()->as_C_string(),
4604 - method->signature()->as_C_string()));
4605 + method->signature()->as_C_string());
4606 assert(!method->is_obsolete(), "only EMCP methods here");
4608 ((methodOopDesc*)method()->*meth_act)(_bci);
4609 diff -r f5603a6e5042 src/share/vm/prims/jvmtiRedefineClasses.cpp
4610 --- a/src/share/vm/prims/jvmtiRedefineClasses.cpp Wed Nov 17 22:42:08 2010 -0800
4611 +++ b/src/share/vm/prims/jvmtiRedefineClasses.cpp Fri Dec 17 13:24:08 2010 +0100
4614 - * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved.
4615 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4617 - * This code is free software; you can redistribute it and/or modify it
4618 - * under the terms of the GNU General Public License version 2 only, as
4619 - * published by the Free Software Foundation.
4621 - * This code is distributed in the hope that it will be useful, but WITHOUT
4622 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4623 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4624 - * version 2 for more details (a copy is included in the LICENSE file that
4625 - * accompanied this code).
4627 - * You should have received a copy of the GNU General Public License version
4628 - * 2 along with this work; if not, write to the Free Software Foundation,
4629 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
4631 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
4632 - * or visit www.oracle.com if you need additional information or have any
4636 +* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
4637 +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4639 +* This code is free software; you can redistribute it and/or modify it
4640 +* under the terms of the GNU General Public License version 2 only, as
4641 +* published by the Free Software Foundation.
4643 +* This code is distributed in the hope that it will be useful, but WITHOUT
4644 +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4645 +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
4646 +* version 2 for more details (a copy is included in the LICENSE file that
4647 +* accompanied this code).
4649 +* You should have received a copy of the GNU General Public License version
4650 +* 2 along with this work; if not, write to the Free Software Foundation,
4651 +* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
4653 +* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
4654 +* or visit www.oracle.com if you need additional information or have any
4659 # include "incls/_precompiled.incl"
4660 # include "incls/_jvmtiRedefineClasses.cpp.incl"
4661 @@ -28,479 +28,600 @@
4663 objArrayOop VM_RedefineClasses::_old_methods = NULL;
4664 objArrayOop VM_RedefineClasses::_new_methods = NULL;
4665 -methodOop* VM_RedefineClasses::_matching_old_methods = NULL;
4666 -methodOop* VM_RedefineClasses::_matching_new_methods = NULL;
4667 -methodOop* VM_RedefineClasses::_deleted_methods = NULL;
4668 -methodOop* VM_RedefineClasses::_added_methods = NULL;
4669 +int* VM_RedefineClasses::_matching_old_methods = NULL;
4670 +int* VM_RedefineClasses::_matching_new_methods = NULL;
4671 +int* VM_RedefineClasses::_deleted_methods = NULL;
4672 +int* VM_RedefineClasses::_added_methods = NULL;
4673 int VM_RedefineClasses::_matching_methods_length = 0;
4674 int VM_RedefineClasses::_deleted_methods_length = 0;
4675 int VM_RedefineClasses::_added_methods_length = 0;
4676 klassOop VM_RedefineClasses::_the_class_oop = NULL;
4679 -VM_RedefineClasses::VM_RedefineClasses(jint class_count,
4680 - const jvmtiClassDefinition *class_defs,
4681 - JvmtiClassLoadKind class_load_kind) {
4682 +// Holds the revision number of the current class redefinition
4683 +int VM_RedefineClasses::_revision_number = -1;
4685 +VM_RedefineClasses::VM_RedefineClasses(jint class_count, const jvmtiClassDefinition *class_defs, JvmtiClassLoadKind class_load_kind)
4686 + : VM_GC_Operation(Universe::heap()->total_full_collections()) {
4687 + RC_TIMER_START(_timer_total);
4688 _class_count = class_count;
4689 _class_defs = class_defs;
4690 _class_load_kind = class_load_kind;
4691 - _res = JVMTI_ERROR_NONE;
4692 + _updated_oops = NULL;
4693 + _result = JVMTI_ERROR_NONE;
4696 +VM_RedefineClasses::~VM_RedefineClasses() {
4698 + RC_TIMER_STOP(_timer_total);
4700 + if (TimeRedefineClasses) {
4701 + tty->print_cr("Timing Prologue: %d", _timer_prologue.milliseconds());
4702 + tty->print_cr("Timing Class Loading: %d", _timer_class_loading.milliseconds());
4703 + tty->print_cr("Timing Waiting for Lock: %d", _timer_wait_for_locks.milliseconds());
4704 + tty->print_cr("Timing Class Linking: %d", _timer_class_linking.milliseconds());
4705 + tty->print_cr("Timing Check Type: %d", _timer_check_type.milliseconds());
4706 + tty->print_cr("Timing Prepare Redefinition: %d", _timer_prepare_redefinition.milliseconds());
4707 + tty->print_cr("Timing Redefinition GC: %d", _timer_redefinition.milliseconds());
4708 + tty->print_cr("Timing Epilogue: %d", _timer_vm_op_epilogue.milliseconds());
4709 + tty->print_cr("------------------------------------------------------------------");
4710 + tty->print_cr("Total Time: %d", _timer_total.milliseconds());
4714 +// Searches for all affected classes and performs a sorting such that a supertype is always before a subtype.
4715 +jvmtiError VM_RedefineClasses::find_sorted_affected_classes(GrowableArray<instanceKlassHandle> *all_affected_klasses) {
4717 + // Create array with all classes for which the redefine command was given
4718 + GrowableArray<instanceKlassHandle> klasses_to_redefine;
4719 + for (int i=0; i<_class_count; i++) {
4720 + oop mirror = JNIHandles::resolve_non_null(_class_defs[i].klass);
4721 + instanceKlassHandle klass_handle(Thread::current(), java_lang_Class::as_klassOop(mirror));
4722 + klasses_to_redefine.append(klass_handle);
4723 + assert(klass_handle->new_version() == NULL, "Must be new class");
4726 + // Find classes not directly redefined, but affected by a redefinition (because one of its supertypes is redefined)
4727 + GrowableArray<instanceKlassHandle> affected_classes;
4728 + FindAffectedKlassesClosure closure(&klasses_to_redefine, &affected_classes);
4730 + // Trace affected classes
4731 + TRACE_RC1("Klasses affected: %d", affected_classes.length());
4733 + for (int i=0; i<affected_classes.length(); i++) {
4734 + TRACE_RC2(affected_classes.at(i)->name()->as_C_string());
4738 + // Add the array of affected classes and the array of redefined classes to get a list of all classes that need a redefinition
4739 + all_affected_klasses->appendAll(&klasses_to_redefine);
4740 + all_affected_klasses->appendAll(&affected_classes);
4742 + // Sort the affected klasses such that a supertype is always on a smaller array index than its subtype.
4743 + jvmtiError result = do_topological_class_sorting(_class_defs, _class_count, &affected_classes, all_affected_klasses, Thread::current());
4745 + TRACE_RC2("Redefine order: ");
4746 + for (int i=0; i<all_affected_klasses->length(); i++) {
4747 + TRACE_RC2("%s", all_affected_klasses->at(i)->name()->as_C_string());
4754 +// Searches for the class bytes of the given class and returns them as a byte array.
4755 +jvmtiError VM_RedefineClasses::find_class_bytes(instanceKlassHandle the_class, const unsigned char **class_bytes, jint *class_byte_count, jboolean *not_changed) {
4757 + *not_changed = false;
4759 + // Search for the index in the redefinition array that corresponds to the current class
4761 + for (j=0; j<_class_count; j++) {
4762 + oop mirror = JNIHandles::resolve_non_null(_class_defs[j].klass);
4763 + klassOop the_class_oop = java_lang_Class::as_klassOop(mirror);
4764 + if (the_class_oop == the_class()) {
4769 + if (j == _class_count) {
4771 + *not_changed = true;
4773 + // Redefine with same bytecodes. This is a class that is only indirectly affected by redefinition,
4774 + // so the user did not specify a different bytecode for that class.
4776 + if (the_class->get_cached_class_file_bytes() == NULL) {
4777 + // not cached, we need to reconstitute the class file from VM representation
4778 + constantPoolHandle constants(Thread::current(), the_class->constants());
4779 + ObjectLocker ol(constants, Thread::current()); // lock constant pool while we query it
4781 + JvmtiClassFileReconstituter reconstituter(the_class);
4782 + if (reconstituter.get_error() != JVMTI_ERROR_NONE) {
4783 + return reconstituter.get_error();
4786 + *class_byte_count = (jint)reconstituter.class_file_size();
4787 + *class_bytes = (unsigned char*)reconstituter.class_file_bytes();
4791 + // it is cached, get it from the cache
4792 + *class_byte_count = the_class->get_cached_class_file_len();
4793 + *class_bytes = the_class->get_cached_class_file_bytes();
4798 + // Redefine with bytecodes at index j
4799 + *class_bytes = _class_defs[j].class_bytes;
4800 + *class_byte_count = _class_defs[j].class_byte_count;
4803 + return JVMTI_ERROR_NONE;
4806 +// Prologue of the VM operation, called on the Java thread in parallel to normal program execution
4807 bool VM_RedefineClasses::doit_prologue() {
4808 - if (_class_count == 0) {
4809 - _res = JVMTI_ERROR_NONE;
4811 + _revision_number++;
4812 + TRACE_RC1("Redefinition with revision number %d started!", _revision_number);
4814 + assert(Thread::current()->is_Java_thread(), "must be Java thread");
4815 + RC_TIMER_START(_timer_prologue);
4817 + if (!check_arguments()) {
4818 + RC_TIMER_STOP(_timer_prologue);
4821 - if (_class_defs == NULL) {
4822 - _res = JVMTI_ERROR_NULL_POINTER;
4824 + // We first load new class versions in the prologue, because somewhere down the
4825 + // call chain it is required that the current thread is a Java thread.
4826 + _new_classes = new (ResourceObj::C_HEAP) GrowableArray<instanceKlassHandle>(5, true);
4827 + _result = load_new_class_versions(Thread::current());
4829 + TRACE_RC1("Loaded new class versions!");
4830 + if (_result != JVMTI_ERROR_NONE) {
4831 + TRACE_RC1("error occured: %d!", _result);
4832 + delete _new_classes;
4833 + _new_classes = NULL;
4834 + RC_TIMER_STOP(_timer_prologue);
4838 + TRACE_RC2("nearly finished");
4839 + VM_GC_Operation::doit_prologue();
4840 + RC_TIMER_STOP(_timer_prologue);
4841 + TRACE_RC2("doit_prologue finished!");
4845 +// Checks basic properties of the arguments of the redefinition command.
4846 +bool VM_RedefineClasses::check_arguments() {
4848 + if (_class_count == 0) RC_ABORT(JVMTI_ERROR_NONE);
4849 + if (_class_defs == NULL) RC_ABORT(JVMTI_ERROR_NULL_POINTER);
4850 for (int i = 0; i < _class_count; i++) {
4851 - if (_class_defs[i].klass == NULL) {
4852 - _res = JVMTI_ERROR_INVALID_CLASS;
4854 + if (_class_defs[i].klass == NULL) RC_ABORT(JVMTI_ERROR_INVALID_CLASS);
4855 + if (_class_defs[i].class_byte_count == 0) RC_ABORT(JVMTI_ERROR_INVALID_CLASS_FORMAT);
4856 + if (_class_defs[i].class_bytes == NULL) RC_ABORT(JVMTI_ERROR_NULL_POINTER);
4862 +jvmtiError VM_RedefineClasses::check_exception() const {
4863 + Thread* THREAD = Thread::current();
4864 + if (HAS_PENDING_EXCEPTION) {
4866 + symbolOop ex_name = PENDING_EXCEPTION->klass()->klass_part()->name();
4867 + TRACE_RC1("parse_stream exception: '%s'", ex_name->as_C_string());
4868 + if (TraceRedefineClasses >= 1) {
4869 + java_lang_Throwable::print(PENDING_EXCEPTION, tty);
4870 + tty->print_cr("");
4872 - if (_class_defs[i].class_byte_count == 0) {
4873 - _res = JVMTI_ERROR_INVALID_CLASS_FORMAT;
4876 - if (_class_defs[i].class_bytes == NULL) {
4877 - _res = JVMTI_ERROR_NULL_POINTER;
4879 + CLEAR_PENDING_EXCEPTION;
4881 + if (ex_name == vmSymbols::java_lang_UnsupportedClassVersionError()) {
4882 + return JVMTI_ERROR_UNSUPPORTED_VERSION;
4883 + } else if (ex_name == vmSymbols::java_lang_ClassFormatError()) {
4884 + return JVMTI_ERROR_INVALID_CLASS_FORMAT;
4885 + } else if (ex_name == vmSymbols::java_lang_ClassCircularityError()) {
4886 + return JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION;
4887 + } else if (ex_name == vmSymbols::java_lang_NoClassDefFoundError()) {
4888 + // The message will be "XXX (wrong name: YYY)"
4889 + return JVMTI_ERROR_NAMES_DONT_MATCH;
4890 + } else if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) {
4891 + return JVMTI_ERROR_OUT_OF_MEMORY;
4893 + // Just in case more exceptions can be thrown..
4894 + return JVMTI_ERROR_FAILS_VERIFICATION;
4898 - // Start timer after all the sanity checks; not quite accurate, but
4899 - // better than adding a bunch of stop() calls.
4900 - RC_TIMER_START(_timer_vm_op_prologue);
4902 - // We first load new class versions in the prologue, because somewhere down the
4903 - // call chain it is required that the current thread is a Java thread.
4904 - _res = load_new_class_versions(Thread::current());
4905 - if (_res != JVMTI_ERROR_NONE) {
4906 - // Free os::malloc allocated memory in load_new_class_version.
4907 - os::free(_scratch_classes);
4908 - RC_TIMER_STOP(_timer_vm_op_prologue);
4910 + return JVMTI_ERROR_NONE;
4913 +// Loads all new class versions and stores the instanceKlass handles in an array.
4914 +jvmtiError VM_RedefineClasses::load_new_class_versions(TRAPS) {
4916 + ResourceMark rm(THREAD);
4918 + TRACE_RC1("===================================================================");
4919 + TRACE_RC1("load new class versions (%d)", _class_count);
4921 + // Retrieve an array of all classes that need to be redefined
4922 + GrowableArray<instanceKlassHandle> all_affected_klasses;
4923 + jvmtiError err = find_sorted_affected_classes(&all_affected_klasses);
4924 + if (err != JVMTI_ERROR_NONE) {
4925 + TRACE_RC1("Error finding sorted affected classes: %d", (int)err);
4929 - RC_TIMER_STOP(_timer_vm_op_prologue);
4933 -void VM_RedefineClasses::doit() {
4934 - Thread *thread = Thread::current();
4936 - if (UseSharedSpaces) {
4937 - // Sharing is enabled so we remap the shared readonly space to
4938 - // shared readwrite, private just in case we need to redefine
4939 - // a shared class. We do the remap during the doit() phase of
4940 - // the safepoint to be safer.
4941 - if (!CompactingPermGenGen::remap_shared_readonly_as_readwrite()) {
4942 - RC_TRACE_WITH_THREAD(0x00000001, thread,
4943 - ("failed to remap shared readonly space to readwrite, private"));
4944 - _res = JVMTI_ERROR_INTERNAL;
4947 + JvmtiThreadState *state = JvmtiThreadState::state_for(JavaThread::current());
4949 + _max_redefinition_flags = Klass::NoRedefinition;
4950 + jvmtiError result = JVMTI_ERROR_NONE;
4952 + for (int i=0; i<all_affected_klasses.length(); i++) {
4953 + TRACE_RC2("Processing affected class %d of %d", i+1, all_affected_klasses.length());
4955 + instanceKlassHandle the_class = all_affected_klasses.at(i);
4956 + TRACE_RC2("name=%s", the_class->name()->as_C_string());
4958 + the_class->link_class(THREAD);
4959 + result = check_exception();
4960 + if (result != JVMTI_ERROR_NONE) break;
4962 + // Find new class bytes
4963 + const unsigned char* class_bytes;
4964 + jint class_byte_count;
4966 + jboolean not_changed;
4967 + if ((error = find_class_bytes(the_class, &class_bytes, &class_byte_count, ¬_changed)) != JVMTI_ERROR_NONE) {
4968 + TRACE_RC1("Error finding class bytes: %d", (int)error);
4972 + assert(class_bytes != NULL && class_byte_count != 0, "Class bytes defined at this point!");
4975 + // Set redefined class handle in JvmtiThreadState class.
4976 + // This redefined class is sent to agent event handler for class file
4977 + // load hook event.
4978 + state->set_class_being_redefined(&the_class, _class_load_kind);
4980 + TRACE_RC2("Before resolving from stream");
4982 + RC_TIMER_STOP(_timer_prologue);
4983 + RC_TIMER_START(_timer_class_loading);
4986 + // Parse the stream.
4987 + Handle the_class_loader(THREAD, the_class->class_loader());
4988 + Handle protection_domain(THREAD, the_class->protection_domain());
4989 + symbolHandle the_class_sym = symbolHandle(THREAD, the_class->name());
4990 + ClassFileStream st((u1*) class_bytes, class_byte_count, (char *)"__VM_RedefineClasses__");
4991 + instanceKlassHandle new_class(THREAD, SystemDictionary::resolve_from_stream(the_class_sym,
4993 + protection_domain,
4999 + not_changed = false;
5001 + RC_TIMER_STOP(_timer_class_loading);
5002 + RC_TIMER_START(_timer_prologue);
5004 + TRACE_RC2("After resolving class from stream!");
5005 + // Clear class_being_redefined just to be sure.
5006 + state->clear_class_being_redefined();
5008 + result = check_exception();
5009 + if (result != JVMTI_ERROR_NONE) break;
5013 + assert(new_class() != NULL, "Class could not be loaded!");
5014 + assert(new_class() != the_class(), "must be different");
5015 + assert(new_class->new_version() == NULL && new_class->old_version() != NULL, "");
5018 + objArrayOop k_interfaces = new_class->local_interfaces();
5019 + for (int j=0; j<k_interfaces->length(); j++) {
5020 + assert(((klassOop)k_interfaces->obj_at(j))->klass_part()->is_newest_version(), "just checking");
5023 + if (!THREAD->is_Compiler_thread()) {
5025 + TRACE_RC2("name=%s loader=%d protection_domain=%d", the_class->name()->as_C_string(), (int)(the_class->class_loader()), (int)(the_class->protection_domain()));
5026 + // If we are on the compiler thread, we must not try to resolve a class.
5027 + klassOop systemLookup = SystemDictionary::resolve_or_null(the_class->name(), the_class->class_loader(), the_class->protection_domain(), THREAD);
5029 + if (systemLookup != NULL) {
5030 + assert(systemLookup == new_class->old_version(), "Old class must be in system dictionary!");
5033 + Klass *subklass = new_class()->klass_part()->subklass();
5034 + while (subklass != NULL) {
5035 + assert(subklass->new_version() == NULL, "Most recent version of class!");
5036 + subklass = subklass->next_sibling();
5039 + // This can happen for reflection generated classes.. ?
5040 + CLEAR_PENDING_EXCEPTION;
5047 + if (new_class->layout_helper() != the_class->layout_helper()) {
5048 + TRACE_RC1("Instance size change for class %s: new=%d old=%d", new_class->name()->as_C_string(), new_class->layout_helper(), the_class->layout_helper());
5052 + // Set the new version of the class
5053 + new_class->set_revision_number(_revision_number);
5054 + new_class->set_redefinition_index(i);
5055 + the_class->set_new_version(new_class());
5056 + _new_classes->append(new_class);
5058 + assert(new_class->new_version() == NULL, "");
5060 + int redefinition_flags = Klass::NoRedefinition;
5062 + if (not_changed) {
5063 + redefinition_flags = Klass::NoRedefinition;
5064 + } else if (AllowAdvancedClassRedefinition) {
5065 + redefinition_flags = calculate_redefinition_flags(new_class);
5066 + if (redefinition_flags >= Klass::RemoveSuperType) {
5067 + TRACE_RC1("Remove super type is not allowed");
5068 + result = JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED;
5072 + jvmtiError allowed = check_redefinition_allowed(new_class);
5073 + if (allowed != JVMTI_ERROR_NONE) {
5074 + TRACE_RC1("Error redefinition not allowed!");
5078 + redefinition_flags = Klass::ModifyClass;
5081 + if (new_class->super() != NULL) {
5082 + redefinition_flags = redefinition_flags | new_class->super()->klass_part()->redefinition_flags();
5085 + for (int j=0; j<new_class->local_interfaces()->length(); j++) {
5086 + redefinition_flags = redefinition_flags | ((klassOop)new_class->local_interfaces()->obj_at(j))->klass_part()->redefinition_flags();
5089 + new_class->set_redefinition_flags(redefinition_flags);
5091 + _max_redefinition_flags = _max_redefinition_flags | redefinition_flags;
5093 + if ((redefinition_flags & Klass::ModifyInstances) != 0) {
5094 + // TODO: Check if watch access flags of static fields are updated correctly.
5095 + calculate_instance_update_information(_new_classes->at(i)());
5097 + assert(new_class->layout_helper() >> 1 == new_class->old_version()->klass_part()->layout_helper() >> 1, "must be equal");
5098 + assert(new_class->fields()->length() == ((instanceKlass*)new_class->old_version()->klass_part())->fields()->length(), "must be equal");
5100 + fieldDescriptor fd_new;
5101 + fieldDescriptor fd_old;
5102 + for (int i=0; i<new_class->fields()->length(); i+=instanceKlass::next_offset) {
5103 + fd_new.initialize(new_class(), i);
5104 + fd_old.initialize(new_class->old_version(), i);
5105 + transfer_special_access_flags(&fd_old, &fd_new);
5110 + if (new_class->super() != NULL) {
5111 + TRACE_RC3("Super class is %s", new_class->super()->klass_part()->name()->as_C_string());
5116 + assert(new_class->super() == NULL || new_class->super()->klass_part()->new_version() == NULL, "Super klass must be newest version!");
5118 + the_class->vtable()->verify(tty);
5119 + new_class->vtable()->verify(tty);
5122 + TRACE_RC2("Verification done!");
5124 + if (i == all_affected_klasses.length() - 1) {
5126 + // This was the last class processed => check if additional classes have been loaded in the meantime
5128 + RC_TIMER_STOP(_timer_prologue);
5130 + RC_TIMER_START(_timer_prologue);
5132 + for (int j=0; j<all_affected_klasses.length(); j++) {
5134 + klassOop initial_klass = all_affected_klasses.at(j)();
5135 + Klass *initial_subklass = initial_klass->klass_part()->subklass();
5136 + Klass *cur_klass = initial_subklass;
5137 + while(cur_klass != NULL) {
5139 + if(cur_klass->oop_is_instance() && cur_klass->is_newest_version()) {
5140 + instanceKlassHandle handle(THREAD, cur_klass->as_klassOop());
5141 + if (!all_affected_klasses.contains(handle)) {
5144 + for (; k<all_affected_klasses.length(); k++) {
5145 + if (all_affected_klasses.at(k)->is_subtype_of(cur_klass->as_klassOop())) {
5149 + all_affected_klasses.insert_before(k, handle);
5150 + TRACE_RC2("Adding newly loaded class to affected classes: %s", cur_klass->name()->as_C_string());
5154 + cur_klass = cur_klass->next_sibling();
5158 + int new_count = all_affected_klasses.length() - 1 - i;
5159 + if (new_count != 0) {
5162 + TRACE_RC1("Found new number of affected classes: %d", new_count);
5167 - for (int i = 0; i < _class_count; i++) {
5168 - redefine_single_class(_class_defs[i].klass, _scratch_classes[i], thread);
5169 + if (result != JVMTI_ERROR_NONE) {
5173 - // Disable any dependent concurrent compilations
5174 - SystemDictionary::notice_modification();
5176 - // Set flag indicating that some invariants are no longer true.
5177 - // See jvmtiExport.hpp for detailed explanation.
5178 - JvmtiExport::set_has_redefined_a_class();
5180 + RC_TIMER_STOP(_timer_prologue);
5181 + RC_TIMER_START(_timer_class_linking);
5182 + // Link and verify new classes _after_ all classes have been updated in the system dictionary!
5183 + for (int i=0; i<all_affected_klasses.length(); i++) {
5184 + instanceKlassHandle the_class = all_affected_klasses.at(i);
5185 + instanceKlassHandle new_class(the_class->new_version());
5187 + TRACE_RC2("Linking class %d/%d %s", i, all_affected_klasses.length(), the_class->name()->as_C_string());
5188 + new_class->link_class(THREAD);
5190 + result = check_exception();
5191 + if (result != JVMTI_ERROR_NONE) break;
5193 + RC_TIMER_STOP(_timer_class_linking);
5194 + RC_TIMER_START(_timer_prologue);
5196 + if (result != JVMTI_ERROR_NONE) {
5201 + TRACE_RC2("All classes loaded!");
5204 - SystemDictionary::classes_do(check_class, thread);
5205 + for (int i=0; i<all_affected_klasses.length(); i++) {
5206 + instanceKlassHandle the_class = all_affected_klasses.at(i);
5207 + assert(the_class->new_version() != NULL, "Must have been redefined");
5208 + instanceKlassHandle new_version = instanceKlassHandle(THREAD, the_class->new_version());
5209 + assert(new_version->new_version() == NULL, "Must be newest version");
5211 + if (!(new_version->super() == NULL || new_version->super()->klass_part()->new_version() == NULL)) {
5212 + new_version()->print();
5213 + new_version->super()->print();
5215 + assert(new_version->super() == NULL || new_version->super()->klass_part()->new_version() == NULL, "Super class must be newest version");
5218 + SystemDictionary::classes_do(check_class, THREAD);
5222 + TRACE_RC1("Finished verification!");
5223 + return JVMTI_ERROR_NONE;
5226 -void VM_RedefineClasses::doit_epilogue() {
5227 - // Free os::malloc allocated memory.
5228 - // The memory allocated in redefine will be free'ed in next VM operation.
5229 - os::free(_scratch_classes);
5231 - if (RC_TRACE_ENABLED(0x00000004)) {
5232 - // Used to have separate timers for "doit" and "all", but the timer
5233 - // overhead skewed the measurements.
5234 - jlong doit_time = _timer_rsc_phase1.milliseconds() +
5235 - _timer_rsc_phase2.milliseconds();
5236 - jlong all_time = _timer_vm_op_prologue.milliseconds() + doit_time;
5238 - RC_TRACE(0x00000004, ("vm_op: all=" UINT64_FORMAT
5239 - " prologue=" UINT64_FORMAT " doit=" UINT64_FORMAT, all_time,
5240 - _timer_vm_op_prologue.milliseconds(), doit_time));
5241 - RC_TRACE(0x00000004,
5242 - ("redefine_single_class: phase1=" UINT64_FORMAT " phase2=" UINT64_FORMAT,
5243 - _timer_rsc_phase1.milliseconds(), _timer_rsc_phase2.milliseconds()));
5244 +void VM_RedefineClasses::lock_threads() {
5246 + RC_TIMER_START(_timer_wait_for_locks);
5249 + JavaThread *javaThread = Threads::first();
5250 + while (javaThread != NULL) {
5251 + if (javaThread->is_Compiler_thread() && javaThread != Thread::current()) {
5252 + CompilerThread *compilerThread = (CompilerThread *)javaThread;
5253 + compilerThread->set_should_bailout(true);
5255 + javaThread = javaThread->next();
5259 + javaThread = Threads::first();
5260 + while (javaThread != NULL) {
5261 + if (javaThread->is_Compiler_thread() && javaThread != Thread::current()) {
5262 + CompilerThread *compilerThread = (CompilerThread *)javaThread;
5263 + compilerThread->compilation_mutex()->lock();
5266 + javaThread = javaThread->next();
5269 + TRACE_RC2("Locked %d compiler threads", cnt);
5272 + javaThread = Threads::first();
5273 + while (javaThread != NULL) {
5274 + if (javaThread != Thread::current()) {
5275 + javaThread->redefine_classes_mutex()->lock();
5277 + javaThread = javaThread->next();
5281 + TRACE_RC2("Locked %d threads", cnt);
5283 + RC_TIMER_STOP(_timer_wait_for_locks);
5286 -bool VM_RedefineClasses::is_modifiable_class(oop klass_mirror) {
5287 - // classes for primitives cannot be redefined
5288 - if (java_lang_Class::is_primitive(klass_mirror)) {
5290 +void VM_RedefineClasses::unlock_threads() {
5293 + JavaThread *javaThread = Threads::first();
5294 + Thread *thread = Thread::current();
5295 + while (javaThread != NULL) {
5296 + if (javaThread->is_Compiler_thread() && javaThread != Thread::current()) {
5297 + CompilerThread *compilerThread = (CompilerThread *)javaThread;
5298 + if (compilerThread->compilation_mutex()->owned_by_self()) {
5299 + compilerThread->compilation_mutex()->unlock();
5303 + javaThread = javaThread->next();
5305 - klassOop the_class_oop = java_lang_Class::as_klassOop(klass_mirror);
5306 - // classes for arrays cannot be redefined
5307 - if (the_class_oop == NULL || !Klass::cast(the_class_oop)->oop_is_instance()) {
5310 + TRACE_RC2("Unlocked %d compiler threads", cnt);
5313 + javaThread = Threads::first();
5314 + while (javaThread != NULL) {
5315 + if (javaThread != Thread::current()) {
5316 + if (javaThread->redefine_classes_mutex()->owned_by_self()) {
5317 + javaThread->redefine_classes_mutex()->unlock();
5320 + javaThread = javaThread->next();
5324 + TRACE_RC2("Unlocked %d threads", cnt);
5327 -// Append the current entry at scratch_i in scratch_cp to *merge_cp_p
5328 -// where the end of *merge_cp_p is specified by *merge_cp_length_p. For
5329 -// direct CP entries, there is just the current entry to append. For
5330 -// indirect and double-indirect CP entries, there are zero or more
5331 -// referenced CP entries along with the current entry to append.
5332 -// Indirect and double-indirect CP entries are handled by recursive
5333 -// calls to append_entry() as needed. The referenced CP entries are
5334 -// always appended to *merge_cp_p before the referee CP entry. These
5335 -// referenced CP entries may already exist in *merge_cp_p in which case
5336 -// there is nothing extra to append and only the current entry is
5338 -void VM_RedefineClasses::append_entry(constantPoolHandle scratch_cp,
5339 - int scratch_i, constantPoolHandle *merge_cp_p, int *merge_cp_length_p,
5342 - // append is different depending on entry tag type
5343 - switch (scratch_cp->tag_at(scratch_i).value()) {
5345 - // The old verifier is implemented outside the VM. It loads classes,
5346 - // but does not resolve constant pool entries directly so we never
5347 - // see Class entries here with the old verifier. Similarly the old
5348 - // verifier does not like Class entries in the input constant pool.
5349 - // The split-verifier is implemented in the VM so it can optionally
5350 - // and directly resolve constant pool entries to load classes. The
5351 - // split-verifier can accept either Class entries or UnresolvedClass
5352 - // entries in the input constant pool. We revert the appended copy
5353 - // back to UnresolvedClass so that either verifier will be happy
5354 - // with the constant pool entry.
5355 - case JVM_CONSTANT_Class:
5357 - // revert the copy to JVM_CONSTANT_UnresolvedClass
5358 - (*merge_cp_p)->unresolved_klass_at_put(*merge_cp_length_p,
5359 - scratch_cp->klass_name_at(scratch_i));
5361 - if (scratch_i != *merge_cp_length_p) {
5362 - // The new entry in *merge_cp_p is at a different index than
5363 - // the new entry in scratch_cp so we need to map the index values.
5364 - map_index(scratch_cp, scratch_i, *merge_cp_length_p);
5366 - (*merge_cp_length_p)++;
5369 - // these are direct CP entries so they can be directly appended,
5370 - // but double and long take two constant pool entries
5371 - case JVM_CONSTANT_Double: // fall through
5372 - case JVM_CONSTANT_Long:
5374 - scratch_cp->copy_entry_to(scratch_i, *merge_cp_p, *merge_cp_length_p,
5377 - if (scratch_i != *merge_cp_length_p) {
5378 - // The new entry in *merge_cp_p is at a different index than
5379 - // the new entry in scratch_cp so we need to map the index values.
5380 - map_index(scratch_cp, scratch_i, *merge_cp_length_p);
5382 - (*merge_cp_length_p) += 2;
5385 - // these are direct CP entries so they can be directly appended
5386 - case JVM_CONSTANT_Float: // fall through
5387 - case JVM_CONSTANT_Integer: // fall through
5388 - case JVM_CONSTANT_Utf8: // fall through
5390 - // This was an indirect CP entry, but it has been changed into
5391 - // an interned string so this entry can be directly appended.
5392 - case JVM_CONSTANT_String: // fall through
5394 - // These were indirect CP entries, but they have been changed into
5395 - // symbolOops so these entries can be directly appended.
5396 - case JVM_CONSTANT_UnresolvedClass: // fall through
5397 - case JVM_CONSTANT_UnresolvedString:
5399 - scratch_cp->copy_entry_to(scratch_i, *merge_cp_p, *merge_cp_length_p,
5402 - if (scratch_i != *merge_cp_length_p) {
5403 - // The new entry in *merge_cp_p is at a different index than
5404 - // the new entry in scratch_cp so we need to map the index values.
5405 - map_index(scratch_cp, scratch_i, *merge_cp_length_p);
5407 - (*merge_cp_length_p)++;
5410 - // this is an indirect CP entry so it needs special handling
5411 - case JVM_CONSTANT_NameAndType:
5413 - int name_ref_i = scratch_cp->name_ref_index_at(scratch_i);
5414 - int new_name_ref_i = 0;
5415 - bool match = (name_ref_i < *merge_cp_length_p) &&
5416 - scratch_cp->compare_entry_to(name_ref_i, *merge_cp_p, name_ref_i,
5419 - // forward reference in *merge_cp_p or not a direct match
5421 - int found_i = scratch_cp->find_matching_entry(name_ref_i, *merge_cp_p,
5423 - if (found_i != 0) {
5424 - guarantee(found_i != name_ref_i,
5425 - "compare_entry_to() and find_matching_entry() do not agree");
5427 - // Found a matching entry somewhere else in *merge_cp_p so
5428 - // just need a mapping entry.
5429 - new_name_ref_i = found_i;
5430 - map_index(scratch_cp, name_ref_i, found_i);
5432 - // no match found so we have to append this entry to *merge_cp_p
5433 - append_entry(scratch_cp, name_ref_i, merge_cp_p, merge_cp_length_p,
5435 - // The above call to append_entry() can only append one entry
5436 - // so the post call query of *merge_cp_length_p is only for
5437 - // the sake of consistency.
5438 - new_name_ref_i = *merge_cp_length_p - 1;
5442 - int signature_ref_i = scratch_cp->signature_ref_index_at(scratch_i);
5443 - int new_signature_ref_i = 0;
5444 - match = (signature_ref_i < *merge_cp_length_p) &&
5445 - scratch_cp->compare_entry_to(signature_ref_i, *merge_cp_p,
5446 - signature_ref_i, THREAD);
5448 - // forward reference in *merge_cp_p or not a direct match
5450 - int found_i = scratch_cp->find_matching_entry(signature_ref_i,
5451 - *merge_cp_p, THREAD);
5452 - if (found_i != 0) {
5453 - guarantee(found_i != signature_ref_i,
5454 - "compare_entry_to() and find_matching_entry() do not agree");
5456 - // Found a matching entry somewhere else in *merge_cp_p so
5457 - // just need a mapping entry.
5458 - new_signature_ref_i = found_i;
5459 - map_index(scratch_cp, signature_ref_i, found_i);
5461 - // no match found so we have to append this entry to *merge_cp_p
5462 - append_entry(scratch_cp, signature_ref_i, merge_cp_p,
5463 - merge_cp_length_p, THREAD);
5464 - // The above call to append_entry() can only append one entry
5465 - // so the post call query of *merge_cp_length_p is only for
5466 - // the sake of consistency.
5467 - new_signature_ref_i = *merge_cp_length_p - 1;
5471 - // If the referenced entries already exist in *merge_cp_p, then
5472 - // both new_name_ref_i and new_signature_ref_i will both be 0.
5473 - // In that case, all we are appending is the current entry.
5474 - if (new_name_ref_i == 0) {
5475 - new_name_ref_i = name_ref_i;
5477 - RC_TRACE(0x00080000,
5478 - ("NameAndType entry@%d name_ref_index change: %d to %d",
5479 - *merge_cp_length_p, name_ref_i, new_name_ref_i));
5481 - if (new_signature_ref_i == 0) {
5482 - new_signature_ref_i = signature_ref_i;
5484 - RC_TRACE(0x00080000,
5485 - ("NameAndType entry@%d signature_ref_index change: %d to %d",
5486 - *merge_cp_length_p, signature_ref_i, new_signature_ref_i));
5489 - (*merge_cp_p)->name_and_type_at_put(*merge_cp_length_p,
5490 - new_name_ref_i, new_signature_ref_i);
5491 - if (scratch_i != *merge_cp_length_p) {
5492 - // The new entry in *merge_cp_p is at a different index than
5493 - // the new entry in scratch_cp so we need to map the index values.
5494 - map_index(scratch_cp, scratch_i, *merge_cp_length_p);
5496 - (*merge_cp_length_p)++;
5499 - // this is a double-indirect CP entry so it needs special handling
5500 - case JVM_CONSTANT_Fieldref: // fall through
5501 - case JVM_CONSTANT_InterfaceMethodref: // fall through
5502 - case JVM_CONSTANT_Methodref:
5504 - int klass_ref_i = scratch_cp->uncached_klass_ref_index_at(scratch_i);
5505 - int new_klass_ref_i = 0;
5506 - bool match = (klass_ref_i < *merge_cp_length_p) &&
5507 - scratch_cp->compare_entry_to(klass_ref_i, *merge_cp_p, klass_ref_i,
5510 - // forward reference in *merge_cp_p or not a direct match
5512 - int found_i = scratch_cp->find_matching_entry(klass_ref_i, *merge_cp_p,
5514 - if (found_i != 0) {
5515 - guarantee(found_i != klass_ref_i,
5516 - "compare_entry_to() and find_matching_entry() do not agree");
5518 - // Found a matching entry somewhere else in *merge_cp_p so
5519 - // just need a mapping entry.
5520 - new_klass_ref_i = found_i;
5521 - map_index(scratch_cp, klass_ref_i, found_i);
5523 - // no match found so we have to append this entry to *merge_cp_p
5524 - append_entry(scratch_cp, klass_ref_i, merge_cp_p, merge_cp_length_p,
5526 - // The above call to append_entry() can only append one entry
5527 - // so the post call query of *merge_cp_length_p is only for
5528 - // the sake of consistency. Without the optimization where we
5529 - // use JVM_CONSTANT_UnresolvedClass, then up to two entries
5530 - // could be appended.
5531 - new_klass_ref_i = *merge_cp_length_p - 1;
5535 - int name_and_type_ref_i =
5536 - scratch_cp->uncached_name_and_type_ref_index_at(scratch_i);
5537 - int new_name_and_type_ref_i = 0;
5538 - match = (name_and_type_ref_i < *merge_cp_length_p) &&
5539 - scratch_cp->compare_entry_to(name_and_type_ref_i, *merge_cp_p,
5540 - name_and_type_ref_i, THREAD);
5542 - // forward reference in *merge_cp_p or not a direct match
5544 - int found_i = scratch_cp->find_matching_entry(name_and_type_ref_i,
5545 - *merge_cp_p, THREAD);
5546 - if (found_i != 0) {
5547 - guarantee(found_i != name_and_type_ref_i,
5548 - "compare_entry_to() and find_matching_entry() do not agree");
5550 - // Found a matching entry somewhere else in *merge_cp_p so
5551 - // just need a mapping entry.
5552 - new_name_and_type_ref_i = found_i;
5553 - map_index(scratch_cp, name_and_type_ref_i, found_i);
5555 - // no match found so we have to append this entry to *merge_cp_p
5556 - append_entry(scratch_cp, name_and_type_ref_i, merge_cp_p,
5557 - merge_cp_length_p, THREAD);
5558 - // The above call to append_entry() can append more than
5559 - // one entry so the post call query of *merge_cp_length_p
5560 - // is required in order to get the right index for the
5561 - // JVM_CONSTANT_NameAndType entry.
5562 - new_name_and_type_ref_i = *merge_cp_length_p - 1;
5566 - // If the referenced entries already exist in *merge_cp_p, then
5567 - // both new_klass_ref_i and new_name_and_type_ref_i will both be
5568 - // 0. In that case, all we are appending is the current entry.
5569 - if (new_klass_ref_i == 0) {
5570 - new_klass_ref_i = klass_ref_i;
5572 - if (new_name_and_type_ref_i == 0) {
5573 - new_name_and_type_ref_i = name_and_type_ref_i;
5576 - const char *entry_name;
5577 - switch (scratch_cp->tag_at(scratch_i).value()) {
5578 - case JVM_CONSTANT_Fieldref:
5579 - entry_name = "Fieldref";
5580 - (*merge_cp_p)->field_at_put(*merge_cp_length_p, new_klass_ref_i,
5581 - new_name_and_type_ref_i);
5583 - case JVM_CONSTANT_InterfaceMethodref:
5584 - entry_name = "IFMethodref";
5585 - (*merge_cp_p)->interface_method_at_put(*merge_cp_length_p,
5586 - new_klass_ref_i, new_name_and_type_ref_i);
5588 - case JVM_CONSTANT_Methodref:
5589 - entry_name = "Methodref";
5590 - (*merge_cp_p)->method_at_put(*merge_cp_length_p, new_klass_ref_i,
5591 - new_name_and_type_ref_i);
5594 - guarantee(false, "bad switch");
5598 - if (klass_ref_i != new_klass_ref_i) {
5599 - RC_TRACE(0x00080000, ("%s entry@%d class_index changed: %d to %d",
5600 - entry_name, *merge_cp_length_p, klass_ref_i, new_klass_ref_i));
5602 - if (name_and_type_ref_i != new_name_and_type_ref_i) {
5603 - RC_TRACE(0x00080000,
5604 - ("%s entry@%d name_and_type_index changed: %d to %d",
5605 - entry_name, *merge_cp_length_p, name_and_type_ref_i,
5606 - new_name_and_type_ref_i));
5609 - if (scratch_i != *merge_cp_length_p) {
5610 - // The new entry in *merge_cp_p is at a different index than
5611 - // the new entry in scratch_cp so we need to map the index values.
5612 - map_index(scratch_cp, scratch_i, *merge_cp_length_p);
5614 - (*merge_cp_length_p)++;
5617 - // At this stage, Class or UnresolvedClass could be here, but not
5619 - case JVM_CONSTANT_ClassIndex: // fall through
5621 - // Invalid is used as the tag for the second constant pool entry
5622 - // occupied by JVM_CONSTANT_Double or JVM_CONSTANT_Long. It should
5623 - // not be seen by itself.
5624 - case JVM_CONSTANT_Invalid: // fall through
5626 - // At this stage, String or UnresolvedString could be here, but not
5628 - case JVM_CONSTANT_StringIndex: // fall through
5630 - // At this stage JVM_CONSTANT_UnresolvedClassInError should not be
5632 - case JVM_CONSTANT_UnresolvedClassInError: // fall through
5636 - // leave a breadcrumb
5637 - jbyte bad_value = scratch_cp->tag_at(scratch_i).value();
5638 - ShouldNotReachHere();
5640 - } // end switch tag value
5641 -} // end append_entry()
5644 -void VM_RedefineClasses::swap_all_method_annotations(int i, int j, instanceKlassHandle scratch_class) {
5645 - typeArrayOop save;
5647 - save = scratch_class->get_method_annotations_of(i);
5648 - scratch_class->set_method_annotations_of(i, scratch_class->get_method_annotations_of(j));
5649 - scratch_class->set_method_annotations_of(j, save);
5651 - save = scratch_class->get_method_parameter_annotations_of(i);
5652 - scratch_class->set_method_parameter_annotations_of(i, scratch_class->get_method_parameter_annotations_of(j));
5653 - scratch_class->set_method_parameter_annotations_of(j, save);
5655 - save = scratch_class->get_method_default_annotations_of(i);
5656 - scratch_class->set_method_default_annotations_of(i, scratch_class->get_method_default_annotations_of(j));
5657 - scratch_class->set_method_default_annotations_of(j, save);
5661 -jvmtiError VM_RedefineClasses::compare_and_normalize_class_versions(
5662 - instanceKlassHandle the_class,
5663 - instanceKlassHandle scratch_class) {
5664 +jvmtiError VM_RedefineClasses::check_redefinition_allowed(instanceKlassHandle scratch_class) {
5668 + // Compatibility mode => check for unsupported modification
5671 + assert(scratch_class->old_version() != NULL, "must have old version");
5672 + instanceKlassHandle the_class(scratch_class->old_version());
5676 // Check superclasses, or rather their names, since superclasses themselves can be
5677 // requested to replace.
5678 // Check for NULL superclass first since this might be java.lang.Object
5679 if (the_class->super() != scratch_class->super() &&
5680 - (the_class->super() == NULL || scratch_class->super() == NULL ||
5681 - Klass::cast(the_class->super())->name() !=
5682 - Klass::cast(scratch_class->super())->name())) {
5683 - return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED;
5684 + (the_class->super() == NULL || scratch_class->super() == NULL ||
5685 + Klass::cast(the_class->super())->name() !=
5686 + Klass::cast(scratch_class->super())->name())) {
5687 + return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED;
5690 // Check if the number, names and order of directly implemented interfaces are the same.
5693 for (i = 0; i < n_intfs; i++) {
5694 if (Klass::cast((klassOop) k_interfaces->obj_at(i))->name() !=
5695 - Klass::cast((klassOop) k_new_interfaces->obj_at(i))->name()) {
5696 - return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED;
5697 + Klass::cast((klassOop) k_new_interfaces->obj_at(i))->name()) {
5698 + return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED;
5702 @@ -554,10 +675,10 @@
5705 if (k_old_fields->short_at(i + instanceKlass::low_offset) !=
5706 - k_new_fields->short_at(i + instanceKlass::low_offset) ||
5707 - k_old_fields->short_at(i + instanceKlass::high_offset) !=
5708 - k_new_fields->short_at(i + instanceKlass::high_offset)) {
5709 - return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED;
5710 + k_new_fields->short_at(i + instanceKlass::low_offset) ||
5711 + k_old_fields->short_at(i + instanceKlass::high_offset) !=
5712 + k_new_fields->short_at(i + instanceKlass::high_offset)) {
5713 + return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED;
5715 // name and signature
5716 jshort name_index = k_old_fields->short_at(i + instanceKlass::name_index_offset);
5722 // Do a parallel walk through the old and new methods. Detect
5723 // cases where they match (exist in both), have been added in
5724 // the new methods, or have been deleted (exist only in the
5725 @@ -674,12 +796,8 @@
5726 idnum_owner->set_method_idnum(new_num);
5728 k_new_method->set_method_idnum(old_num);
5729 - swap_all_method_annotations(old_num, new_num, scratch_class);
5732 - RC_TRACE(0x00008000, ("Method matched: new: %s [%d] == old: %s [%d]",
5733 - k_new_method->name_and_sig_as_C_string(), ni,
5734 - k_old_method->name_and_sig_as_C_string(), oi));
5735 // advance to next pair of methods
5738 @@ -688,11 +806,11 @@
5739 // method added, see if it is OK
5740 new_flags = (jushort) k_new_method->access_flags().get_flags();
5741 if ((new_flags & JVM_ACC_PRIVATE) == 0
5742 - // hack: private should be treated as final, but alas
5743 - || (new_flags & (JVM_ACC_FINAL|JVM_ACC_STATIC)) == 0
5745 - // new methods must be private
5746 - return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED;
5747 + // hack: private should be treated as final, but alas
5748 + || (new_flags & (JVM_ACC_FINAL|JVM_ACC_STATIC)) == 0
5750 + // new methods must be private
5751 + return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED;
5754 u2 num = the_class->next_method_idnum();
5755 @@ -707,24 +825,19 @@
5756 idnum_owner->set_method_idnum(new_num);
5758 k_new_method->set_method_idnum(num);
5759 - swap_all_method_annotations(new_num, num, scratch_class);
5761 - RC_TRACE(0x00008000, ("Method added: new: %s [%d]",
5762 - k_new_method->name_and_sig_as_C_string(), ni));
5763 ++ni; // advance to next new method
5766 // method deleted, see if it is OK
5767 old_flags = (jushort) k_old_method->access_flags().get_flags();
5768 if ((old_flags & JVM_ACC_PRIVATE) == 0
5769 - // hack: private should be treated as final, but alas
5770 - || (old_flags & (JVM_ACC_FINAL|JVM_ACC_STATIC)) == 0
5772 - // deleted methods must be private
5773 - return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED;
5774 + // hack: private should be treated as final, but alas
5775 + || (old_flags & (JVM_ACC_FINAL|JVM_ACC_STATIC)) == 0
5777 + // deleted methods must be private
5778 + return JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED;
5780 - RC_TRACE(0x00008000, ("Method deleted: old: %s [%d]",
5781 - k_old_method->name_and_sig_as_C_string(), oi));
5782 ++oi; // advance to next old method
5785 @@ -735,2081 +848,1502 @@
5786 return JVMTI_ERROR_NONE;
5790 -// Find new constant pool index value for old constant pool index value
5791 -// by seaching the index map. Returns zero (0) if there is no mapped
5792 -// value for the old constant pool index.
5793 -int VM_RedefineClasses::find_new_index(int old_index) {
5794 - if (_index_map_count == 0) {
5795 - // map is empty so nothing can be found
5797 +int VM_RedefineClasses::calculate_redefinition_flags(instanceKlassHandle new_class) {
5799 + int result = Klass::NoRedefinition;
5803 + TRACE_RC2("Comparing different class versions of class %s", new_class->name()->as_C_string());
5805 + assert(new_class->old_version() != NULL, "must have old version");
5806 + instanceKlassHandle the_class(new_class->old_version());
5808 + // Check whether class is in the error init state.
5809 + if (the_class->is_in_error_state()) {
5810 + // TBD #5057930: special error code is needed in 1.6
5811 + //result = Klass::union_redefinition_level(result, Klass::Invalid);
5814 - if (old_index < 1 || old_index >= _index_map_p->length()) {
5815 - // The old_index is out of range so it is not mapped. This should
5816 - // not happen in regular constant pool merging use, but it can
5817 - // happen if a corrupt annotation is processed.
5821 + //////////////////////////////////////////////////////////////////////////////////////////////////////////
5822 + // Check superclasses
5823 + assert(new_class->super() == NULL || new_class->super()->klass_part()->is_newest_version(), "");
5824 + if (the_class->super() != new_class->super()) {
5825 + // Super class changed
5827 + klassOop cur_klass = the_class->super();
5828 + while (cur_klass != NULL) {
5829 + if (!new_class->is_subclass_of(cur_klass->klass_part()->newest_version())) {
5830 + TRACE_RC2("Removed super class %s", cur_klass->klass_part()->name()->as_C_string());
5831 + result = result | Klass::RemoveSuperType | Klass::ModifyInstances | Klass::ModifyClass;
5833 + if (!cur_klass->klass_part()->has_subtype_changed()) {
5834 + TRACE_RC2("Subtype changed of class %s", cur_klass->klass_part()->name()->as_C_string());
5835 + cur_klass->klass_part()->set_subtype_changed(true);
5839 + cur_klass = cur_klass->klass_part()->super();
5842 + cur_klass = new_class->super();
5843 + while (cur_klass != NULL) {
5844 + if (!the_class->is_subclass_of(cur_klass->klass_part()->old_version())) {
5845 + TRACE_RC2("Added super class %s", cur_klass->klass_part()->name()->as_C_string());
5846 + result = result | Klass::ModifyClass | Klass::ModifyInstances;
5848 + cur_klass = cur_klass->klass_part()->super();
5852 - int value = _index_map_p->at(old_index);
5853 - if (value == -1) {
5854 - // the old_index is not mapped
5859 -} // end find_new_index()
5862 -// Returns true if the current mismatch is due to a resolved/unresolved
5863 -// class pair. Otherwise, returns false.
5864 -bool VM_RedefineClasses::is_unresolved_class_mismatch(constantPoolHandle cp1,
5865 - int index1, constantPoolHandle cp2, int index2) {
5867 - jbyte t1 = cp1->tag_at(index1).value();
5868 - if (t1 != JVM_CONSTANT_Class && t1 != JVM_CONSTANT_UnresolvedClass) {
5869 - return false; // wrong entry type; not our special case
5872 - jbyte t2 = cp2->tag_at(index2).value();
5873 - if (t2 != JVM_CONSTANT_Class && t2 != JVM_CONSTANT_UnresolvedClass) {
5874 - return false; // wrong entry type; not our special case
5878 - return false; // not a mismatch; not our special case
5881 - char *s1 = cp1->klass_name_at(index1)->as_C_string();
5882 - char *s2 = cp2->klass_name_at(index2)->as_C_string();
5883 - if (strcmp(s1, s2) != 0) {
5884 - return false; // strings don't match; not our special case
5887 - return true; // made it through the gauntlet; this is our special case
5888 -} // end is_unresolved_class_mismatch()
5891 -// Returns true if the current mismatch is due to a resolved/unresolved
5892 -// string pair. Otherwise, returns false.
5893 -bool VM_RedefineClasses::is_unresolved_string_mismatch(constantPoolHandle cp1,
5894 - int index1, constantPoolHandle cp2, int index2) {
5896 - jbyte t1 = cp1->tag_at(index1).value();
5897 - if (t1 != JVM_CONSTANT_String && t1 != JVM_CONSTANT_UnresolvedString) {
5898 - return false; // wrong entry type; not our special case
5901 - jbyte t2 = cp2->tag_at(index2).value();
5902 - if (t2 != JVM_CONSTANT_String && t2 != JVM_CONSTANT_UnresolvedString) {
5903 - return false; // wrong entry type; not our special case
5907 - return false; // not a mismatch; not our special case
5910 - char *s1 = cp1->string_at_noresolve(index1);
5911 - char *s2 = cp2->string_at_noresolve(index2);
5912 - if (strcmp(s1, s2) != 0) {
5913 - return false; // strings don't match; not our special case
5916 - return true; // made it through the gauntlet; this is our special case
5917 -} // end is_unresolved_string_mismatch()
5920 -jvmtiError VM_RedefineClasses::load_new_class_versions(TRAPS) {
5921 - // For consistency allocate memory using os::malloc wrapper.
5922 - _scratch_classes = (instanceKlassHandle *)
5923 - os::malloc(sizeof(instanceKlassHandle) * _class_count);
5924 - if (_scratch_classes == NULL) {
5925 - return JVMTI_ERROR_OUT_OF_MEMORY;
5928 - ResourceMark rm(THREAD);
5930 - JvmtiThreadState *state = JvmtiThreadState::state_for(JavaThread::current());
5931 - // state can only be NULL if the current thread is exiting which
5932 - // should not happen since we're trying to do a RedefineClasses
5933 - guarantee(state != NULL, "exiting thread calling load_new_class_versions");
5934 - for (int i = 0; i < _class_count; i++) {
5935 - oop mirror = JNIHandles::resolve_non_null(_class_defs[i].klass);
5936 - // classes for primitives cannot be redefined
5937 - if (!is_modifiable_class(mirror)) {
5938 - return JVMTI_ERROR_UNMODIFIABLE_CLASS;
5940 - klassOop the_class_oop = java_lang_Class::as_klassOop(mirror);
5941 - instanceKlassHandle the_class = instanceKlassHandle(THREAD, the_class_oop);
5942 - symbolHandle the_class_sym = symbolHandle(THREAD, the_class->name());
5944 - // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark
5945 - RC_TRACE_WITH_THREAD(0x00000001, THREAD,
5946 - ("loading name=%s (avail_mem=" UINT64_FORMAT "K)",
5947 - the_class->external_name(), os::available_memory() >> 10));
5949 - ClassFileStream st((u1*) _class_defs[i].class_bytes,
5950 - _class_defs[i].class_byte_count, (char *)"__VM_RedefineClasses__");
5952 - // Parse the stream.
5953 - Handle the_class_loader(THREAD, the_class->class_loader());
5954 - Handle protection_domain(THREAD, the_class->protection_domain());
5955 - // Set redefined class handle in JvmtiThreadState class.
5956 - // This redefined class is sent to agent event handler for class file
5957 - // load hook event.
5958 - state->set_class_being_redefined(&the_class, _class_load_kind);
5960 - klassOop k = SystemDictionary::parse_stream(the_class_sym,
5962 - protection_domain,
5965 - // Clear class_being_redefined just to be sure.
5966 - state->clear_class_being_redefined();
5968 - // TODO: if this is retransform, and nothing changed we can skip it
5970 - instanceKlassHandle scratch_class (THREAD, k);
5972 - if (HAS_PENDING_EXCEPTION) {
5973 - symbolOop ex_name = PENDING_EXCEPTION->klass()->klass_part()->name();
5974 - // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark
5975 - RC_TRACE_WITH_THREAD(0x00000002, THREAD, ("parse_stream exception: '%s'",
5976 - ex_name->as_C_string()));
5977 - CLEAR_PENDING_EXCEPTION;
5979 - if (ex_name == vmSymbols::java_lang_UnsupportedClassVersionError()) {
5980 - return JVMTI_ERROR_UNSUPPORTED_VERSION;
5981 - } else if (ex_name == vmSymbols::java_lang_ClassFormatError()) {
5982 - return JVMTI_ERROR_INVALID_CLASS_FORMAT;
5983 - } else if (ex_name == vmSymbols::java_lang_ClassCircularityError()) {
5984 - return JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION;
5985 - } else if (ex_name == vmSymbols::java_lang_NoClassDefFoundError()) {
5986 - // The message will be "XXX (wrong name: YYY)"
5987 - return JVMTI_ERROR_NAMES_DONT_MATCH;
5988 - } else if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) {
5989 - return JVMTI_ERROR_OUT_OF_MEMORY;
5990 - } else { // Just in case more exceptions can be thrown..
5991 - return JVMTI_ERROR_FAILS_VERIFICATION;
5992 + //////////////////////////////////////////////////////////////////////////////////////////////////////////
5993 + // Check interfaces
5995 + // Interfaces removed?
5996 + objArrayOop old_interfaces = the_class->transitive_interfaces();
5997 + for (i = 0; i<old_interfaces->length(); i++) {
5998 + instanceKlassHandle old_interface((klassOop)old_interfaces->obj_at(i));
5999 + if (!new_class->implements_interface_any_version(old_interface())) {
6000 + result = result | Klass::RemoveSuperType | Klass::ModifyClass;
6001 + TRACE_RC2("Removed interface %s", old_interface->name()->as_C_string());
6003 + if (!old_interface->has_subtype_changed()) {
6004 + TRACE_RC2("Subtype changed of interface %s", old_interface->name()->as_C_string());
6005 + old_interface->set_subtype_changed(true);
6009 - // Ensure class is linked before redefine
6010 - if (!the_class->is_linked()) {
6011 - the_class->link_class(THREAD);
6012 - if (HAS_PENDING_EXCEPTION) {
6013 - symbolOop ex_name = PENDING_EXCEPTION->klass()->klass_part()->name();
6014 - // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark
6015 - RC_TRACE_WITH_THREAD(0x00000002, THREAD, ("link_class exception: '%s'",
6016 - ex_name->as_C_string()));
6017 - CLEAR_PENDING_EXCEPTION;
6018 - if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) {
6019 - return JVMTI_ERROR_OUT_OF_MEMORY;
6022 + // Interfaces added?
6023 + objArrayOop new_interfaces = new_class->transitive_interfaces();
6024 + for (i = 0; i<new_interfaces->length(); i++) {
6025 + if (!the_class->implements_interface_any_version((klassOop)new_interfaces->obj_at(i))) {
6026 + result = result | Klass::ModifyClass;
6027 + TRACE_RC2("Added interface %s", ((klassOop)new_interfaces->obj_at(i))->klass_part()->name()->as_C_string());
6032 + // Check whether class modifiers are the same.
6033 + jushort old_flags = (jushort) the_class->access_flags().get_flags();
6034 + jushort new_flags = (jushort) new_class->access_flags().get_flags();
6035 + if (old_flags != new_flags) {
6036 + // TODO (tw): Can this have any effects?
6039 + // Check if the number, names, types and order of fields declared in these classes
6041 + typeArrayOop k_old_fields = the_class->fields();
6042 + typeArrayOop k_new_fields = new_class->fields();
6043 + int n_fields = k_old_fields->length();
6044 + if (n_fields != k_new_fields->length()) {
6045 + result = result | Klass::ModifyInstances;
6047 + for (i = 0; i < n_fields; i += instanceKlass::next_offset) {
6049 + old_flags = k_old_fields->ushort_at(i + instanceKlass::access_flags_offset);
6050 + new_flags = k_new_fields->ushort_at(i + instanceKlass::access_flags_offset);
6051 + if ((old_flags ^ new_flags) & JVM_RECOGNIZED_FIELD_MODIFIERS) {
6052 + // (tw) Can this have any effects?
6055 + if (k_old_fields->short_at(i + instanceKlass::low_offset) !=
6056 + k_new_fields->short_at(i + instanceKlass::low_offset) ||
6057 + k_old_fields->short_at(i + instanceKlass::high_offset) !=
6058 + k_new_fields->short_at(i + instanceKlass::high_offset)) {
6059 + result = result | Klass::ModifyInstances;
6061 + // name and signature
6062 + jshort name_index = k_old_fields->short_at(i + instanceKlass::name_index_offset);
6063 + jshort sig_index = k_old_fields->short_at(i +instanceKlass::signature_index_offset);
6064 + symbolOop name_sym1 = the_class->constants()->symbol_at(name_index);
6065 + symbolOop sig_sym1 = the_class->constants()->symbol_at(sig_index);
6066 + name_index = k_new_fields->short_at(i + instanceKlass::name_index_offset);
6067 + sig_index = k_new_fields->short_at(i + instanceKlass::signature_index_offset);
6068 + symbolOop name_sym2 = new_class->constants()->symbol_at(name_index);
6069 + symbolOop sig_sym2 = new_class->constants()->symbol_at(sig_index);
6070 + if (name_sym1 != name_sym2 || sig_sym1 != sig_sym2) {
6071 + result = result | Klass::ModifyInstances;
6076 + // Do a parallel walk through the old and new methods. Detect
6077 + // cases where they match (exist in both), have been added in
6078 + // the new methods, or have been deleted (exist only in the
6079 + // old methods). The class file parser places methods in order
6080 + // by method name, but does not order overloaded methods by
6081 + // signature. In order to determine what fate befell the methods,
6082 + // this code places the overloaded new methods that have matching
6083 + // old methods in the same order as the old methods and places
6084 + // new overloaded methods at the end of overloaded methods of
6085 + // that name. The code for this order normalization is adapted
6086 + // from the algorithm used in instanceKlass::find_method().
6087 + // Since we are swapping out of order entries as we find them,
6088 + // we only have to search forward through the overloaded methods.
6089 + // Methods which are added and have the same name as an existing
6090 + // method (but different signature) will be put at the end of
6091 + // the methods with that name, and the name mismatch code will
6093 + objArrayHandle k_old_methods(the_class->methods());
6094 + objArrayHandle k_new_methods(new_class->methods());
6095 + int n_old_methods = k_old_methods->length();
6096 + int n_new_methods = k_new_methods->length();
6101 + methodOop k_old_method;
6102 + methodOop k_new_method;
6103 + enum { matched, added, deleted, undetermined } method_was = undetermined;
6105 + if (oi >= n_old_methods) {
6106 + if (ni >= n_new_methods) {
6107 + break; // we've looked at everything, done
6109 + // New method at the end
6110 + k_new_method = (methodOop) k_new_methods->obj_at(ni);
6111 + method_was = added;
6112 + } else if (ni >= n_new_methods) {
6113 + // Old method, at the end, is deleted
6114 + k_old_method = (methodOop) k_old_methods->obj_at(oi);
6115 + method_was = deleted;
6117 + // There are more methods in both the old and new lists
6118 + k_old_method = (methodOop) k_old_methods->obj_at(oi);
6119 + k_new_method = (methodOop) k_new_methods->obj_at(ni);
6120 + if (k_old_method->name() != k_new_method->name()) {
6121 + // Methods are sorted by method name, so a mismatch means added
6123 + if (k_old_method->name()->fast_compare(k_new_method->name()) > 0) {
6124 + method_was = added;
6126 - return JVMTI_ERROR_INTERNAL;
6127 + method_was = deleted;
6129 + } else if (k_old_method->signature() == k_new_method->signature()) {
6130 + // Both the name and signature match
6131 + method_was = matched;
6133 + // The name matches, but the signature doesn't, which means we have to
6134 + // search forward through the new overloaded methods.
6135 + int nj; // outside the loop for post-loop check
6136 + for (nj = ni + 1; nj < n_new_methods; nj++) {
6137 + methodOop m = (methodOop)k_new_methods->obj_at(nj);
6138 + if (k_old_method->name() != m->name()) {
6139 + // reached another method name so no more overloaded methods
6140 + method_was = deleted;
6143 + if (k_old_method->signature() == m->signature()) {
6144 + // found a match so swap the methods
6145 + k_new_methods->obj_at_put(ni, m);
6146 + k_new_methods->obj_at_put(nj, k_new_method);
6148 + method_was = matched;
6153 + if (nj >= n_new_methods) {
6154 + // reached the end without a match; so method was deleted
6155 + method_was = deleted;
6160 - // Do the validity checks in compare_and_normalize_class_versions()
6161 - // before verifying the byte codes. By doing these checks first, we
6162 - // limit the number of functions that require redirection from
6163 - // the_class to scratch_class. In particular, we don't have to
6164 - // modify JNI GetSuperclass() and thus won't change its performance.
6165 - jvmtiError res = compare_and_normalize_class_versions(the_class,
6167 - if (res != JVMTI_ERROR_NONE) {
6169 + switch (method_was) {
6171 + // methods match, be sure modifiers do too
6172 + old_flags = (jushort) k_old_method->access_flags().get_flags();
6173 + new_flags = (jushort) k_new_method->access_flags().get_flags();
6174 + if ((old_flags ^ new_flags) & ~(JVM_ACC_NATIVE)) {
6175 + // (tw) Can this have any effects? Probably yes on vtables?
6176 + result = result | Klass::ModifyClass;
6179 - // verify what the caller passed us
6181 - // The bug 6214132 caused the verification to fail.
6182 - // Information about the_class and scratch_class is temporarily
6183 - // recorded into jvmtiThreadState. This data is used to redirect
6184 - // the_class to scratch_class in the JVM_* functions called by the
6185 - // verifier. Please, refer to jvmtiThreadState.hpp for the detailed
6187 - RedefineVerifyMark rvm(&the_class, &scratch_class, state);
6189 - scratch_class, Verifier::ThrowException, true, THREAD);
6192 - if (HAS_PENDING_EXCEPTION) {
6193 - symbolOop ex_name = PENDING_EXCEPTION->klass()->klass_part()->name();
6194 - // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark
6195 - RC_TRACE_WITH_THREAD(0x00000002, THREAD,
6196 - ("verify_byte_codes exception: '%s'", ex_name->as_C_string()));
6197 - CLEAR_PENDING_EXCEPTION;
6198 - if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) {
6199 - return JVMTI_ERROR_OUT_OF_MEMORY;
6201 - // tell the caller the bytecodes are bad
6202 - return JVMTI_ERROR_FAILS_VERIFICATION;
6203 + u2 new_num = k_new_method->method_idnum();
6204 + u2 old_num = k_old_method->method_idnum();
6205 + if (new_num != old_num) {
6206 + methodOop idnum_owner = new_class->method_with_idnum(old_num);
6207 + if (idnum_owner != NULL) {
6208 + // There is already a method assigned this idnum -- switch them
6209 + idnum_owner->set_method_idnum(new_num);
6211 + k_new_method->set_method_idnum(old_num);
6212 + TRACE_RC2("swapping idnum of new and old method %d / %d!", new_num, old_num);
6213 + // swap_all_method_annotations(old_num, new_num, new_class);
6217 - res = merge_cp_and_rewrite(the_class, scratch_class, THREAD);
6218 - if (res != JVMTI_ERROR_NONE) {
6220 + TRACE_RC3("Method matched: new: %s [%d] == old: %s [%d]",
6221 + k_new_method->name_and_sig_as_C_string(), ni,
6222 + k_old_method->name_and_sig_as_C_string(), oi);
6223 + // advance to next pair of methods
6228 + // method added, see if it is OK
6229 + new_flags = (jushort) k_new_method->access_flags().get_flags();
6230 + if ((new_flags & JVM_ACC_PRIVATE) == 0
6231 + // hack: private should be treated as final, but alas
6232 + || (new_flags & (JVM_ACC_FINAL|JVM_ACC_STATIC)) == 0
6234 + // new methods must be private
6235 + result = result | Klass::ModifyClass;
6238 - if (VerifyMergedCPBytecodes) {
6239 - // verify what we have done during constant pool merging
6241 - RedefineVerifyMark rvm(&the_class, &scratch_class, state);
6242 - Verifier::verify(scratch_class, Verifier::ThrowException, true, THREAD);
6244 + u2 num = the_class->next_method_idnum();
6245 + if (num == constMethodOopDesc::UNSET_IDNUM) {
6246 + // cannot add any more methods
6247 + result = result | Klass::ModifyClass;
6250 - if (HAS_PENDING_EXCEPTION) {
6251 - symbolOop ex_name = PENDING_EXCEPTION->klass()->klass_part()->name();
6252 - // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark
6253 - RC_TRACE_WITH_THREAD(0x00000002, THREAD,
6254 - ("verify_byte_codes post merge-CP exception: '%s'",
6255 - ex_name->as_C_string()));
6256 - CLEAR_PENDING_EXCEPTION;
6257 - if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) {
6258 - return JVMTI_ERROR_OUT_OF_MEMORY;
6260 - // tell the caller that constant pool merging screwed up
6261 - return JVMTI_ERROR_INTERNAL;
6262 + u2 new_num = k_new_method->method_idnum();
6263 + methodOop idnum_owner = new_class->method_with_idnum(num);
6264 + if (idnum_owner != NULL) {
6265 + // There is already a method assigned this idnum -- switch them
6266 + idnum_owner->set_method_idnum(new_num);
6268 + k_new_method->set_method_idnum(num);
6269 + //swap_all_method_annotations(new_num, num, new_class);
6271 + TRACE_RC1("Method added: new: %s [%d]",
6272 + k_new_method->name_and_sig_as_C_string(), ni);
6273 + ++ni; // advance to next new method
6276 + // method deleted, see if it is OK
6277 + old_flags = (jushort) k_old_method->access_flags().get_flags();
6278 + if ((old_flags & JVM_ACC_PRIVATE) == 0
6279 + // hack: private should be treated as final, but alas
6280 + || (old_flags & (JVM_ACC_FINAL|JVM_ACC_STATIC)) == 0
6282 + // deleted methods must be private
6283 + result = result | Klass::ModifyClass;
6285 + TRACE_RC1("Method deleted: old: %s [%d]",
6286 + k_old_method->name_and_sig_as_C_string(), oi);
6287 + ++oi; // advance to next old method
6290 + ShouldNotReachHere();
6294 + if (new_class()->size() != new_class->old_version()->size()) {
6295 + result |= Klass::ModifyClassSize;
6298 + if (new_class->size_helper() != ((instanceKlass*)(new_class->old_version()->klass_part()))->size_helper()) {
6299 + result |= Klass::ModifyInstanceSize;
6302 + methodHandle instanceTransformerMethod(new_class->find_method(vmSymbols::transformer_name(), vmSymbols::void_method_signature()));
6303 + if (!instanceTransformerMethod.is_null() && !instanceTransformerMethod->is_static()) {
6304 + result |= Klass::HasInstanceTransformer;
6307 + // (tw) Check method bodies to be able to return NoChange?
6311 +void VM_RedefineClasses::calculate_instance_update_information(klassOop new_version) {
6313 + class UpdateFieldsEvolutionClosure : public FieldEvolutionClosure {
6317 + GrowableArray<int> info;
6319 + bool copy_backwards;
6323 + bool does_copy_backwards() {
6324 + return copy_backwards;
6327 + UpdateFieldsEvolutionClosure(klassOop klass) {
6329 + int base_offset = instanceOopDesc::base_offset_in_bytes();
6331 + if (klass->klass_part()->newest_version() == SystemDictionary::Class_klass()->klass_part()->newest_version()) {
6332 + base_offset += java_lang_Class::number_of_fake_oop_fields*size_of_type(T_OBJECT);
6335 + info.append(base_offset);
6337 + curPosition = base_offset;
6338 + copy_backwards = false;
6341 + GrowableArray<int> &finish() {
6346 + virtual void do_new_field(fieldDescriptor* fd){
6347 + int size = size_of_type(fd->field_type());
6353 + void fill(int size) {
6354 + if (info.length() > 0 && info.at(info.length() - 1) < 0) {
6355 + (*info.adr_at(info.length() - 1)) -= size;
6357 + info.append(-size);
6360 + curPosition += size;
6363 + int size_of_type(BasicType type) {
6367 + size = sizeof(jboolean);
6371 + size = (sizeof(jchar));
6375 + size = (sizeof(jfloat));
6379 + size = (sizeof(jdouble));
6383 + size = (sizeof(jbyte));
6387 + size = (sizeof(jshort));
6391 + size = (sizeof(jint));
6395 + size = (sizeof(jlong));
6400 + if (UseCompressedOops) {
6401 + size = sizeof(narrowOop);
6403 + size = (sizeof(oop));
6408 + ShouldNotReachHere();
6411 + assert(size > 0, "");
6418 + virtual void do_old_field(fieldDescriptor* fd){}
6420 + virtual void do_changed_field(fieldDescriptor* old_fd, fieldDescriptor *new_fd){
6422 + int alignment = new_fd->offset() - curPosition;
6423 + if (alignment > 0) {
6424 + // This field was aligned, so we need to make sure that we fill the gap
6428 + assert(old_fd->field_type() == new_fd->field_type(), "");
6429 + assert(curPosition == new_fd->offset(), "must be correct offset!");
6431 + int offset = old_fd->offset();
6432 + int size = size_of_type(old_fd->field_type());
6435 + if (info.length() > 0 && info.at(info.length() - 1) > 0) {
6436 + prevEnd = info.at(info.length() - 2) + info.at(info.length() - 1);
6439 + if (prevEnd == offset) {
6440 + info.at_put(info.length() - 2, info.at(info.length() - 2) + size);
6442 + info.append(size);
6443 + info.append(offset);
6446 + if (old_fd->offset() < new_fd->offset()) {
6447 + copy_backwards = true;
6450 + transfer_special_access_flags(old_fd, new_fd);
6452 + curPosition += size;
6456 + UpdateFieldsEvolutionClosure cl(new_version);
6457 + ((instanceKlass*)new_version->klass_part())->do_fields_evolution(&cl);
6459 + GrowableArray<int> result = cl.finish();
6460 + ((instanceKlass*)new_version->klass_part())->store_update_information(result);
6461 + ((instanceKlass*)new_version->klass_part())->set_copying_backwards(cl.does_copy_backwards());
6464 + TRACE_RC2("Instance update information for %s:", new_version->klass_part()->name()->as_C_string());
6465 + if (cl.does_copy_backwards()) {
6466 + TRACE_RC2("\tDoes copy backwards!");
6468 + for (int i=0; i<result.length(); i++) {
6469 + int curNum = result.at(i);
6471 + TRACE_RC2("\t%d CLEAN", curNum);
6472 + } else if (curNum > 0) {
6473 + TRACE_RC2("\t%d COPY from %d", curNum, result.at(i + 1));
6476 + TRACE_RC2("\tEND");
6482 +void VM_RedefineClasses::update_active_methods() {
6484 + TRACE_RC2("Updating active methods");
6485 + JavaThread *java_thread = Threads::first();
6486 + while (java_thread != NULL) {
6488 + int stack_depth = 0;
6489 + if (java_thread->has_last_Java_frame()) {
6491 + TRACE_RC4("checking stack of Java thread %s", java_thread->name());
6493 + // vframes are resource allocated
6494 + Thread* current_thread = Thread::current();
6495 + ResourceMark rm(current_thread);
6496 + HandleMark hm(current_thread);
6498 + RegisterMap reg_map(java_thread);
6499 + frame f = java_thread->last_frame();
6500 + vframe* vf = vframe::new_vframe(&f, ®_map, java_thread);
6501 + frame* last_entry_frame = NULL;
6503 + while (vf != NULL) {
6504 + if (vf->is_java_frame()) {
6505 + // java frame (interpreted, compiled, ...)
6506 + javaVFrame *jvf = javaVFrame::cast(vf);
6508 + if (!(jvf->method()->is_native())) {
6509 + int bci = jvf->bci();
6510 + TRACE_RC4("found method: %s / bci=%d", jvf->method()->name()->as_C_string(), bci);
6511 + ResourceMark rm(Thread::current());
6513 + instanceKlassHandle klass(jvf->method()->method_holder());
6515 + if (jvf->method()->new_version() != NULL && jvf->is_interpreted_frame()) {
6518 + TRACE_RC2("Found method that should just be updated to the newest version %s", jvf->method()->name_and_sig_as_C_string());
6521 + int code_size = jvf->method()->code_size();
6522 + char *code_base_old = (char*)jvf->method()->code_base();
6523 + char *code_base_new = (char*)jvf->method()->new_version()->code_base();
6524 + for (int i=0; i<code_size; i++) {
6525 + tty->print_cr("old=%d new=%d", *code_base_old++, *code_base_new++);
6527 + jvf->method()->print_codes_on(tty);
6528 + jvf->method()->new_version()->print_codes_on(tty);
6531 + assert(jvf->is_interpreted_frame(), "Every frame must be interpreted!");
6532 + interpretedVFrame *iframe = (interpretedVFrame *)jvf;
6536 + constantPoolCacheOop cp_old = jvf->method()->constants()->cache();
6537 + tty->print_cr("old cp");
6538 + for (int i=0; i<cp_old->length(); i++) {
6539 + cp_old->entry_at(i)->print(tty, i);
6541 + constantPoolCacheOop cp_new = jvf->method()->new_version()->constants()->cache();
6542 + tty->print_cr("new cp");
6543 + for (int i=0; i<cp_new->length(); i++) {
6544 + cp_new->entry_at(i)->print(tty, i);
6548 + iframe->set_method(jvf->method()->new_version(), bci);
6549 + TRACE_RC2("Updated method to newer version");
6550 + assert(jvf->method()->new_version() == NULL, "must be latest version");
6555 + vf = vf->sender();
6559 + // Advance to next thread
6560 + java_thread = java_thread->next();
6564 +void VM_RedefineClasses::rollback() {
6565 + TRACE_RC1("Rolling back redefinition!");
6566 + SystemDictionary::rollback_redefinition();
6568 + TRACE_RC1("After rolling back system dictionary!");
6569 + for (int i=0; i<_new_classes->length(); i++) {
6570 + SystemDictionary::remove_from_hierarchy(_new_classes->at(i));
6573 + for (int i=0; i<_new_classes->length(); i++) {
6574 + instanceKlassHandle new_class = _new_classes->at(i);
6575 + new_class->set_redefining(false);
6576 + new_class->old_version()->klass_part()->set_new_version(NULL);
6577 + new_class->set_old_version(NULL);
6582 +template <class T> void VM_RedefineClasses::do_oop_work(T* p) {
6583 + T heap_oop = oopDesc::load_heap_oop(p);
6584 + if (!oopDesc::is_null(heap_oop)) {
6585 + oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
6586 + if (obj->is_instanceKlass()) {
6587 + klassOop klass = (klassOop)obj;
6588 + if (klass->klass_part()->new_version() != NULL && klass->klass_part()->new_version()->klass_part()->is_redefining()) {
6589 + obj = klass->klass_part()->new_version();
6590 + oopDesc::encode_store_heap_oop_not_null(p, obj);
6592 + } else if (obj->blueprint()->newest_version() == SystemDictionary::Class_klass()->klass_part()->newest_version()) {
6594 + klassOop klass_oop = java_lang_Class::as_klassOop(obj);
6595 + if (klass_oop != NULL) {
6596 + if (klass_oop->klass_part()->new_version() != NULL && klass_oop->klass_part()->new_version()->klass_part()->is_redefining()) {
6597 + obj = klass_oop->klass_part()->new_version()->klass_part()->java_mirror();
6598 + oopDesc::encode_store_heap_oop_not_null(p, obj);
6599 + } else if (klass_oop->klass_part()->is_redefining()) {
6600 + obj = klass_oop->klass_part()->java_mirror();
6601 + oopDesc::encode_store_heap_oop_not_null(p, obj);
6606 - Rewriter::rewrite(scratch_class, THREAD);
6607 - if (HAS_PENDING_EXCEPTION) {
6608 - symbolOop ex_name = PENDING_EXCEPTION->klass()->klass_part()->name();
6609 - CLEAR_PENDING_EXCEPTION;
6610 - if (ex_name == vmSymbols::java_lang_OutOfMemoryError()) {
6611 - return JVMTI_ERROR_OUT_OF_MEMORY;
6613 - return JVMTI_ERROR_INTERNAL;
6617 - _scratch_classes[i] = scratch_class;
6619 - // RC_TRACE_WITH_THREAD macro has an embedded ResourceMark
6620 - RC_TRACE_WITH_THREAD(0x00000001, THREAD,
6621 - ("loaded name=%s (avail_mem=" UINT64_FORMAT "K)",
6622 - the_class->external_name(), os::available_memory() >> 10));
6625 - return JVMTI_ERROR_NONE;
6629 -// Map old_index to new_index as needed. scratch_cp is only needed
6630 -// for RC_TRACE() calls.
6631 -void VM_RedefineClasses::map_index(constantPoolHandle scratch_cp,
6632 - int old_index, int new_index) {
6633 - if (find_new_index(old_index) != 0) {
6634 - // old_index is already mapped
6638 - if (old_index == new_index) {
6639 - // no mapping is needed
6643 - _index_map_p->at_put(old_index, new_index);
6644 - _index_map_count++;
6646 - RC_TRACE(0x00040000, ("mapped tag %d at index %d to %d",
6647 - scratch_cp->tag_at(old_index).value(), old_index, new_index));
6648 -} // end map_index()
6651 -// Merge old_cp and scratch_cp and return the results of the merge via
6652 -// merge_cp_p. The number of entries in *merge_cp_p is returned via
6653 -// merge_cp_length_p. The entries in old_cp occupy the same locations
6654 -// in *merge_cp_p. Also creates a map of indices from entries in
6655 -// scratch_cp to the corresponding entry in *merge_cp_p. Index map
6656 -// entries are only created for entries in scratch_cp that occupy a
6657 -// different location in *merged_cp_p.
6658 -bool VM_RedefineClasses::merge_constant_pools(constantPoolHandle old_cp,
6659 - constantPoolHandle scratch_cp, constantPoolHandle *merge_cp_p,
6660 - int *merge_cp_length_p, TRAPS) {
6662 - if (merge_cp_p == NULL) {
6663 - assert(false, "caller must provide scatch constantPool");
6664 - return false; // robustness
6666 - if (merge_cp_length_p == NULL) {
6667 - assert(false, "caller must provide scatch CP length");
6668 - return false; // robustness
6670 - // Worst case we need old_cp->length() + scratch_cp()->length(),
6671 - // but the caller might be smart so make sure we have at least
6673 - if ((*merge_cp_p)->length() < old_cp->length()) {
6674 - assert(false, "merge area too small");
6675 - return false; // robustness
6678 - RC_TRACE_WITH_THREAD(0x00010000, THREAD,
6679 - ("old_cp_len=%d, scratch_cp_len=%d", old_cp->length(),
6680 - scratch_cp->length()));
6684 - // The old_cp is copied to *merge_cp_p; this means that any code
6685 - // using old_cp does not have to change. This work looks like a
6686 - // perfect fit for constantPoolOop::copy_cp_to(), but we need to
6687 - // handle one special case:
6688 - // - revert JVM_CONSTANT_Class to JVM_CONSTANT_UnresolvedClass
6689 - // This will make verification happy.
6691 - int old_i; // index into old_cp
6693 - // index zero (0) is not used in constantPools
6694 - for (old_i = 1; old_i < old_cp->length(); old_i++) {
6695 - // leave debugging crumb
6696 - jbyte old_tag = old_cp->tag_at(old_i).value();
6697 - switch (old_tag) {
6698 - case JVM_CONSTANT_Class:
6699 - // revert the copy to JVM_CONSTANT_UnresolvedClass
6700 - (*merge_cp_p)->unresolved_klass_at_put(old_i,
6701 - old_cp->klass_name_at(old_i));
6704 - case JVM_CONSTANT_Double:
6705 - case JVM_CONSTANT_Long:
6706 - // just copy the entry to *merge_cp_p, but double and long take
6707 - // two constant pool entries
6708 - old_cp->copy_entry_to(old_i, *merge_cp_p, old_i, CHECK_0);
6713 - // just copy the entry to *merge_cp_p
6714 - old_cp->copy_entry_to(old_i, *merge_cp_p, old_i, CHECK_0);
6717 - } // end for each old_cp entry
6719 - // We don't need to sanity check that *merge_cp_length_p is within
6720 - // *merge_cp_p bounds since we have the minimum on-entry check above.
6721 - (*merge_cp_length_p) = old_i;
6724 - // merge_cp_len should be the same as old_cp->length() at this point
6725 - // so this trace message is really a "warm-and-breathing" message.
6726 - RC_TRACE_WITH_THREAD(0x00020000, THREAD,
6727 - ("after pass 0: merge_cp_len=%d", *merge_cp_length_p));
6729 - int scratch_i; // index into scratch_cp
6732 - // Compare scratch_cp entries to the old_cp entries that we have
6733 - // already copied to *merge_cp_p. In this pass, we are eliminating
6734 - // exact duplicates (matching entry at same index) so we only
6735 - // compare entries in the common indice range.
6736 - int increment = 1;
6737 - int pass1a_length = MIN2(old_cp->length(), scratch_cp->length());
6738 - for (scratch_i = 1; scratch_i < pass1a_length; scratch_i += increment) {
6739 - switch (scratch_cp->tag_at(scratch_i).value()) {
6740 - case JVM_CONSTANT_Double:
6741 - case JVM_CONSTANT_Long:
6742 - // double and long take two constant pool entries
6751 - bool match = scratch_cp->compare_entry_to(scratch_i, *merge_cp_p,
6752 - scratch_i, CHECK_0);
6754 - // found a match at the same index so nothing more to do
6756 - } else if (is_unresolved_class_mismatch(scratch_cp, scratch_i,
6757 - *merge_cp_p, scratch_i)) {
6758 - // The mismatch in compare_entry_to() above is because of a
6759 - // resolved versus unresolved class entry at the same index
6760 - // with the same string value. Since Pass 0 reverted any
6761 - // class entries to unresolved class entries in *merge_cp_p,
6762 - // we go with the unresolved class entry.
6764 - } else if (is_unresolved_string_mismatch(scratch_cp, scratch_i,
6765 - *merge_cp_p, scratch_i)) {
6766 - // The mismatch in compare_entry_to() above is because of a
6767 - // resolved versus unresolved string entry at the same index
6768 - // with the same string value. We can live with whichever
6769 - // happens to be at scratch_i in *merge_cp_p.
6773 - int found_i = scratch_cp->find_matching_entry(scratch_i, *merge_cp_p,
6775 - if (found_i != 0) {
6776 - guarantee(found_i != scratch_i,
6777 - "compare_entry_to() and find_matching_entry() do not agree");
6779 - // Found a matching entry somewhere else in *merge_cp_p so
6780 - // just need a mapping entry.
6781 - map_index(scratch_cp, scratch_i, found_i);
6785 - // The find_matching_entry() call above could fail to find a match
6786 - // due to a resolved versus unresolved class or string entry situation
6787 - // like we solved above with the is_unresolved_*_mismatch() calls.
6788 - // However, we would have to call is_unresolved_*_mismatch() over
6789 - // all of *merge_cp_p (potentially) and that doesn't seem to be
6790 - // worth the time.
6792 - // No match found so we have to append this entry and any unique
6793 - // referenced entries to *merge_cp_p.
6794 - append_entry(scratch_cp, scratch_i, merge_cp_p, merge_cp_length_p,
6796 +void VM_RedefineClasses::swap_marks(oop first, oop second) {
6797 + markOop first_mark = first->mark();
6798 + markOop second_mark = second->mark();
6799 + first->set_mark(second_mark);
6800 + second->set_mark(first_mark);
6803 +void VM_RedefineClasses::doit() {
6804 + Thread *thread = Thread::current();
6806 + TRACE_RC1("Entering doit!");
6808 + assert((_max_redefinition_flags & Klass::RemoveSuperType) == 0, "removing super types not allowed");
6810 + if (UseSharedSpaces) {
6811 + // Sharing is enabled so we remap the shared readonly space to
6812 + // shared readwrite, private just in case we need to redefine
6813 + // a shared class. We do the remap during the doit() phase of
6814 + // the safepoint to be safer.
6815 + if (!CompactingPermGenGen::remap_shared_readonly_as_readwrite()) {
6816 + TRACE_RC1("failed to remap shared readonly space to readwrite, private");
6817 + _result = JVMTI_ERROR_INTERNAL;
6822 - RC_TRACE_WITH_THREAD(0x00020000, THREAD,
6823 - ("after pass 1a: merge_cp_len=%d, scratch_i=%d, index_map_len=%d",
6824 - *merge_cp_length_p, scratch_i, _index_map_count));
6826 - if (scratch_i < scratch_cp->length()) {
6828 - // old_cp is smaller than scratch_cp so there are entries in
6829 - // scratch_cp that we have not yet processed. We take care of
6831 - int increment = 1;
6832 - for (; scratch_i < scratch_cp->length(); scratch_i += increment) {
6833 - switch (scratch_cp->tag_at(scratch_i).value()) {
6834 - case JVM_CONSTANT_Double:
6835 - case JVM_CONSTANT_Long:
6836 - // double and long take two constant pool entries
6843 + RC_TIMER_START(_timer_prepare_redefinition);
6844 + for (int i = 0; i < _new_classes->length(); i++) {
6845 + redefine_single_class(_new_classes->at(i), thread);
6848 + // Deoptimize all compiled code that depends on this class
6849 + flush_dependent_code(instanceKlassHandle(Thread::current(), (klassOop)NULL), Thread::current());
6851 + // Adjust constantpool caches and vtables for all classes
6852 + // that reference methods of the evolved class.
6853 + SystemDictionary::classes_do(adjust_cpool_cache, Thread::current());
6855 + RC_TIMER_STOP(_timer_prepare_redefinition);
6856 + RC_TIMER_START(_timer_redefinition);
6858 + class ChangePointersOopClosure : public OopClosure {
6859 + virtual void do_oop(oop* o) {
6864 - scratch_cp->find_matching_entry(scratch_i, *merge_cp_p, CHECK_0);
6865 - if (found_i != 0) {
6866 - // Found a matching entry somewhere else in *merge_cp_p so
6867 - // just need a mapping entry.
6868 - map_index(scratch_cp, scratch_i, found_i);
6870 + virtual void do_oop(narrowOop* o) {
6874 - // No match found so we have to append this entry and any unique
6875 - // referenced entries to *merge_cp_p.
6876 - append_entry(scratch_cp, scratch_i, merge_cp_p, merge_cp_length_p,
6880 + class ChangePointersObjectClosure : public ObjectClosure {
6884 + OopClosure *_closure;
6885 + bool _needs_instance_update;
6886 + GrowableArray<oop> *_updated_oops;
6889 + ChangePointersObjectClosure(OopClosure *closure) : _closure(closure), _needs_instance_update(false), _updated_oops(NULL) {}
6891 + bool needs_instance_update() {
6892 + return _needs_instance_update;
6895 + GrowableArray<oop> *updated_oops() { return _updated_oops; }
6897 + virtual void do_object(oop obj) {
6898 + if (!obj->is_instanceKlass()) {
6899 + obj->oop_iterate(_closure);
6901 + if (obj->blueprint()->is_redefining()) {
6903 + if (obj->blueprint()->check_redefinition_flag(Klass::HasInstanceTransformer)) {
6904 + if (_updated_oops == NULL) {
6905 + _updated_oops = new (ResourceObj::C_HEAP) GrowableArray<oop>(100, true);
6907 + _updated_oops->append(obj);
6910 + if(obj->blueprint()->update_information() != NULL || obj->is_perm()) {
6912 + assert(obj->blueprint()->old_version() != NULL, "must have old version");
6913 + obj->set_klass_no_check(obj->blueprint()->old_version());
6915 + if (obj->size() != obj->size_given_klass(obj->blueprint()->new_version()->klass_part()) || obj->is_perm()) {
6916 + // We need an instance update => set back to old klass
6917 + _needs_instance_update = true;
6920 + MarkSweep::update_fields(obj, obj);
6921 + assert(obj->blueprint()->is_redefining(), "update fields resets the klass");
6927 + instanceKlass *klass = instanceKlass::cast((klassOop)obj);
6928 + if (klass->is_redefining()) {
6929 + // Initialize the new class! Special static initialization that does not execute the
6930 + // static constructor but copies static field values from the old class if name
6931 + // and signature of a static field match.
6932 + klass->initialize_redefined_class();
6934 + klass->iterate_static_fields(_closure);
6939 + ChangePointersOopClosure oopClosure;
6940 + ChangePointersObjectClosure objectClosure(&oopClosure);
6943 + SharedHeap::heap()->gc_prologue(true);
6944 + Universe::root_oops_do(&oopClosure);
6945 + Universe::heap()->object_iterate(&objectClosure);
6946 + SharedHeap::heap()->gc_epilogue(false);
6949 - RC_TRACE_WITH_THREAD(0x00020000, THREAD,
6950 - ("after pass 1b: merge_cp_len=%d, scratch_i=%d, index_map_len=%d",
6951 - *merge_cp_length_p, scratch_i, _index_map_count));
6952 + // Swap marks to have same hashcodes
6953 + for (int i=0; i<_new_classes->length(); i++) {
6954 + swap_marks(_new_classes->at(i)(), _new_classes->at(i)->old_version());
6955 + swap_marks(_new_classes->at(i)->java_mirror(), _new_classes->at(i)->old_version()->klass_part()->java_mirror());
6956 + ((instanceKlass*)_new_classes->at(i)->old_version()->klass_part())->constants()->set_pool_holder(_new_classes->at(i)->old_v