1.1 --- a/src/share/vm/runtime/deoptimization.cpp Mon Feb 08 12:20:09 2010 -0800 1.2 +++ b/src/share/vm/runtime/deoptimization.cpp Tue Feb 09 01:31:13 2010 -0800 1.3 @@ -145,6 +145,27 @@ 1.4 if (EliminateAllocations) { 1.5 assert (chunk->at(0)->scope() != NULL,"expect only compiled java frames"); 1.6 GrowableArray<ScopeValue*>* objects = chunk->at(0)->scope()->objects(); 1.7 + 1.8 + // The flag return_oop() indicates call sites which return oop 1.9 + // in compiled code. Such sites include java method calls, 1.10 + // runtime calls (for example, used to allocate new objects/arrays 1.11 + // on slow code path) and any other calls generated in compiled code. 1.12 + // It is not guaranteed that we can get such information here only 1.13 + // by analyzing bytecode in deoptimized frames. This is why this flag 1.14 + // is set during method compilation (see Compile::Process_OopMap_Node()). 1.15 + bool save_oop_result = chunk->at(0)->scope()->return_oop(); 1.16 + Handle return_value; 1.17 + if (save_oop_result) { 1.18 + // Reallocation may trigger GC. If deoptimization happened on return from 1.19 + // call which returns oop we need to save it since it is not in oopmap. 1.20 + oop result = deoptee.saved_oop_result(&map); 1.21 + assert(result == NULL || result->is_oop(), "must be oop"); 1.22 + return_value = Handle(thread, result); 1.23 + assert(Universe::heap()->is_in_or_null(result), "must be heap pointer"); 1.24 + if (TraceDeoptimization) { 1.25 + tty->print_cr("SAVED OOP RESULT " INTPTR_FORMAT " in thread " INTPTR_FORMAT, result, thread); 1.26 + } 1.27 + } 1.28 bool reallocated = false; 1.29 if (objects != NULL) { 1.30 JRT_BLOCK 1.31 @@ -158,8 +179,12 @@ 1.32 ttyLocker ttyl; 1.33 tty->print_cr("REALLOC OBJECTS in thread " INTPTR_FORMAT, thread); 1.34 print_objects(objects); 1.35 + } 1.36 +#endif 1.37 } 1.38 -#endif 1.39 + if (save_oop_result) { 1.40 + // Restore result. 1.41 + deoptee.set_saved_oop_result(&map, return_value()); 1.42 } 1.43 } 1.44 if (EliminateLocks) {