Mercurial > hg > graal-compiler
changeset 421:577f3a2e0662
Merge
author | never |
---|---|
date | Fri, 07 Nov 2008 13:55:14 -0800 |
parents | 348be627a148 (diff) a1980da045cc (current diff) |
children | 909cfd030fab 3c07cda72b7d 334969144810 |
files | |
diffstat | 6 files changed, 65 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Fri Nov 07 09:29:38 2008 -0800 +++ b/.hgtags Fri Nov 07 13:55:14 2008 -0800 @@ -12,3 +12,4 @@ 5fa96a5a7e76da7c8dad12486293a0456c2c116c jdk7-b35 e91159f921a58af3698e6479ea1fc5818da66d09 jdk7-b36 9ee9cf798b59e7d51f8c0a686959f313867a55d6 jdk7-b37 +d9bc824aa078573829bb66572af847e26e1bd12e jdk7-b38
--- a/src/share/vm/interpreter/bytecodeStream.cpp Fri Nov 07 09:29:38 2008 -0800 +++ b/src/share/vm/interpreter/bytecodeStream.cpp Fri Nov 07 13:55:14 2008 -0800 @@ -28,8 +28,9 @@ Bytecodes::Code RawBytecodeStream::raw_next_special(Bytecodes::Code code) { assert(!is_last_bytecode(), "should have been checked"); // set next bytecode position - address bcp = RawBytecodeStream::bcp(); - int l = Bytecodes::raw_special_length_at(bcp); + address bcp = RawBytecodeStream::bcp(); + address end = method()->code_base() + end_bci(); + int l = Bytecodes::raw_special_length_at(bcp, end); if (l <= 0 || (_bci + l) > _end_bci) { code = Bytecodes::_illegal; } else { @@ -39,8 +40,12 @@ _is_wide = false; // check for special (uncommon) cases if (code == Bytecodes::_wide) { - code = (Bytecodes::Code)bcp[1]; - _is_wide = true; + if (bcp + 1 >= end) { + code = Bytecodes::_illegal; + } else { + code = (Bytecodes::Code)bcp[1]; + _is_wide = true; + } } } _code = code;
--- a/src/share/vm/interpreter/bytecodes.cpp Fri Nov 07 09:29:38 2008 -0800 +++ b/src/share/vm/interpreter/bytecodes.cpp Fri Nov 07 13:55:14 2008 -0800 @@ -54,13 +54,19 @@ return method->orig_bytecode_at(method->bci_from(bcp)); } -int Bytecodes::special_length_at(address bcp) { +int Bytecodes::special_length_at(address bcp, address end) { Code code = code_at(bcp); switch (code) { case _wide: + if (end != NULL && bcp + 1 >= end) { + return -1; // don't read past end of code buffer + } return wide_length_for(cast(*(bcp + 1))); case _tableswitch: { address aligned_bcp = (address)round_to((intptr_t)bcp + 1, jintSize); + if (end != NULL && aligned_bcp + 3*jintSize >= end) { + return -1; // don't read past end of code buffer + } jlong lo = (jint)Bytes::get_Java_u4(aligned_bcp + 1*jintSize); jlong hi = (jint)Bytes::get_Java_u4(aligned_bcp + 2*jintSize); jlong len = (aligned_bcp - bcp) + (3 + hi - lo + 1)*jintSize; @@ -73,6 +79,9 @@ case _fast_binaryswitch: // fall through case _fast_linearswitch: { address aligned_bcp = (address)round_to((intptr_t)bcp + 1, jintSize); + if (end != NULL && aligned_bcp + 2*jintSize >= end) { + return -1; // don't read past end of code buffer + } jlong npairs = (jint)Bytes::get_Java_u4(aligned_bcp + jintSize); jlong len = (aligned_bcp - bcp) + (2 + 2*npairs)*jintSize; // only return len if it can be represented as a positive int; @@ -90,14 +99,17 @@ // verifier when reading in bytecode to verify. Other mechanisms that // run at runtime (such as generateOopMaps) need to iterate over the code // and don't expect to see breakpoints: they want to see the instruction -// which was replaces so that they can get the correct length and find +// which was replaced so that they can get the correct length and find // the next bytecode. -int Bytecodes::raw_special_length_at(address bcp) { +// +// 'end' indicates the end of the code buffer, which we should not try to read +// past. +int Bytecodes::raw_special_length_at(address bcp, address end) { Code code = code_or_bp_at(bcp); if (code == _breakpoint) { return 1; } else { - return special_length_at(bcp); + return special_length_at(bcp, end); } }
--- a/src/share/vm/interpreter/bytecodes.hpp Fri Nov 07 09:29:38 2008 -0800 +++ b/src/share/vm/interpreter/bytecodes.hpp Fri Nov 07 13:55:14 2008 -0800 @@ -340,8 +340,10 @@ const char* wf = wide_format(code); return (wf == NULL) ? 0 : (int)strlen(wf); } - static int special_length_at(address bcp); - static int raw_special_length_at(address bcp); + // if 'end' is provided, it indicates the end of the code buffer which + // should not be read past when parsing. + static int special_length_at(address bcp, address end = NULL); + static int raw_special_length_at(address bcp, address end = NULL); static int length_at (address bcp) { int l = length_for(code_at(bcp)); return l > 0 ? l : special_length_at(bcp); } static int java_length_at (address bcp) { int l = length_for(java_code_at(bcp)); return l > 0 ? l : special_length_at(bcp); } static bool is_java_code (Code code) { return 0 <= code && code < number_of_java_codes; }
--- a/src/share/vm/memory/compactingPermGenGen.hpp Fri Nov 07 09:29:38 2008 -0800 +++ b/src/share/vm/memory/compactingPermGenGen.hpp Fri Nov 07 13:55:14 2008 -0800 @@ -100,7 +100,7 @@ enum { vtbl_list_size = 16, // number of entries in the shared space vtable list. - num_virtuals = 100 // number of virtual methods in Klass (or + num_virtuals = 200 // number of virtual methods in Klass (or // subclass) objects, or greater. };
--- a/src/share/vm/memory/dump.cpp Fri Nov 07 09:29:38 2008 -0800 +++ b/src/share/vm/memory/dump.cpp Fri Nov 07 13:55:14 2008 -0800 @@ -818,6 +818,40 @@ // across the space while doing this, as that causes the vtables to be // patched, undoing our useful work. Instead, iterate to make a list, // then use the list to do the fixing. +// +// Our constructed vtables: +// Dump time: +// 1. init_self_patching_vtbl_list: table of pointers to current virtual method addrs +// 2. generate_vtable_methods: create jump table, appended to above vtbl_list +// 3. PatchKlassVtables: for Klass list, patch the vtable entry to point to jump table +// rather than to current vtbl +// Table layout: NOTE FIXED SIZE +// 1. vtbl pointers +// 2. #Klass X #virtual methods per Klass +// 1 entry for each, in the order: +// Klass1:method1 entry, Klass1:method2 entry, ... Klass1:method<num_virtuals> entry +// Klass2:method1 entry, Klass2:method2 entry, ... Klass2:method<num_virtuals> entry +// ... +// Klass<vtbl_list_size>:method1 entry, Klass<vtbl_list_size>:method2 entry, +// ... Klass<vtbl_list_size>:method<num_virtuals> entry +// Sample entry: (Sparc): +// save(sp, -256, sp) +// ba,pt common_code +// mov XXX, %L0 %L0 gets: Klass index <<8 + method index (note: max method index 255) +// +// Restore time: +// 1. initialize_oops: reserve space for table +// 2. init_self_patching_vtbl_list: update pointers to NEW virtual method addrs in text +// +// Execution time: +// First virtual method call for any object of these Klass types: +// 1. object->klass->klass_part +// 2. vtable entry for that klass_part points to the jump table entries +// 3. branches to common_code with %O0/klass_part, %L0: Klass index <<8 + method index +// 4. common_code: +// Get address of new vtbl pointer for this Klass from updated table +// Update new vtbl pointer in the Klass: future virtual calls go direct +// Jump to method, using new vtbl pointer and method index class PatchKlassVtables: public ObjectClosure { private: