141 #ifdef COMPILER2 |
141 #ifdef COMPILER2 |
142 // Reallocate the non-escaping objects and restore their fields. Then |
142 // Reallocate the non-escaping objects and restore their fields. Then |
143 // relock objects if synchronization on them was eliminated. |
143 // relock objects if synchronization on them was eliminated. |
144 if (DoEscapeAnalysis) { |
144 if (DoEscapeAnalysis) { |
145 if (EliminateAllocations) { |
145 if (EliminateAllocations) { |
|
146 assert (chunk->at(0)->scope() != NULL,"expect only compiled java frames"); |
146 GrowableArray<ScopeValue*>* objects = chunk->at(0)->scope()->objects(); |
147 GrowableArray<ScopeValue*>* objects = chunk->at(0)->scope()->objects(); |
147 bool reallocated = false; |
148 bool reallocated = false; |
148 if (objects != NULL) { |
149 if (objects != NULL) { |
149 JRT_BLOCK |
150 JRT_BLOCK |
150 reallocated = realloc_objects(thread, &deoptee, objects, THREAD); |
151 reallocated = realloc_objects(thread, &deoptee, objects, THREAD); |
160 } |
161 } |
161 #endif |
162 #endif |
162 } |
163 } |
163 } |
164 } |
164 if (EliminateLocks) { |
165 if (EliminateLocks) { |
|
166 #ifndef PRODUCT |
|
167 bool first = true; |
|
168 #endif |
165 for (int i = 0; i < chunk->length(); i++) { |
169 for (int i = 0; i < chunk->length(); i++) { |
166 GrowableArray<MonitorValue*>* monitors = chunk->at(i)->scope()->monitors(); |
170 compiledVFrame* cvf = chunk->at(i); |
167 if (monitors != NULL) { |
171 assert (cvf->scope() != NULL,"expect only compiled java frames"); |
168 relock_objects(&deoptee, &map, monitors); |
172 GrowableArray<MonitorInfo*>* monitors = cvf->monitors(); |
|
173 if (monitors->is_nonempty()) { |
|
174 relock_objects(monitors, thread); |
169 #ifndef PRODUCT |
175 #ifndef PRODUCT |
170 if (TraceDeoptimization) { |
176 if (TraceDeoptimization) { |
171 ttyLocker ttyl; |
177 ttyLocker ttyl; |
172 tty->print_cr("RELOCK OBJECTS in thread " INTPTR_FORMAT, thread); |
|
173 for (int j = 0; j < monitors->length(); j++) { |
178 for (int j = 0; j < monitors->length(); j++) { |
174 MonitorValue* mv = monitors->at(j); |
179 MonitorInfo* mi = monitors->at(j); |
175 if (mv->eliminated()) { |
180 if (mi->eliminated()) { |
176 StackValue* owner = StackValue::create_stack_value(&deoptee, &map, mv->owner()); |
181 if (first) { |
177 tty->print_cr(" object <" INTPTR_FORMAT "> locked", owner->get_obj()()); |
182 first = false; |
|
183 tty->print_cr("RELOCK OBJECTS in thread " INTPTR_FORMAT, thread); |
|
184 } |
|
185 tty->print_cr(" object <" INTPTR_FORMAT "> locked", mi->owner()); |
178 } |
186 } |
179 } |
187 } |
180 } |
188 } |
181 #endif |
189 #endif |
182 } |
190 } |
797 } |
805 } |
798 } |
806 } |
799 |
807 |
800 |
808 |
801 // relock objects for which synchronization was eliminated |
809 // relock objects for which synchronization was eliminated |
802 void Deoptimization::relock_objects(frame* fr, RegisterMap* reg_map, GrowableArray<MonitorValue*>* monitors) { |
810 void Deoptimization::relock_objects(GrowableArray<MonitorInfo*>* monitors, JavaThread* thread) { |
803 for (int i = 0; i < monitors->length(); i++) { |
811 for (int i = 0; i < monitors->length(); i++) { |
804 MonitorValue* mv = monitors->at(i); |
812 MonitorInfo* mon_info = monitors->at(i); |
805 StackValue* owner = StackValue::create_stack_value(fr, reg_map, mv->owner()); |
813 if (mon_info->eliminated()) { |
806 if (mv->eliminated()) { |
814 assert(mon_info->owner() != NULL, "reallocation was missed"); |
807 Handle obj = owner->get_obj(); |
815 Handle obj = Handle(mon_info->owner()); |
808 assert(obj.not_null(), "reallocation was missed"); |
816 markOop mark = obj->mark(); |
809 BasicLock* lock = StackValue::resolve_monitor_lock(fr, mv->basic_lock()); |
817 if (UseBiasedLocking && mark->has_bias_pattern()) { |
810 lock->set_displaced_header(obj->mark()); |
818 // New allocated objects may have the mark set to anonymously biased. |
811 obj->set_mark((markOop) lock); |
819 // Also the deoptimized method may called methods with synchronization |
812 } |
820 // where the thread-local object is bias locked to the current thread. |
813 assert(owner->get_obj()->is_locked(), "object must be locked now"); |
821 assert(mark->is_biased_anonymously() || |
|
822 mark->biased_locker() == thread, "should be locked to current thread"); |
|
823 // Reset mark word to unbiased prototype. |
|
824 markOop unbiased_prototype = markOopDesc::prototype()->set_age(mark->age()); |
|
825 obj->set_mark(unbiased_prototype); |
|
826 } |
|
827 BasicLock* lock = mon_info->lock(); |
|
828 ObjectSynchronizer::slow_enter(obj, lock, thread); |
|
829 } |
|
830 assert(mon_info->owner()->is_locked(), "object must be locked now"); |
814 } |
831 } |
815 } |
832 } |
816 |
833 |
817 |
834 |
818 #ifndef PRODUCT |
835 #ifndef PRODUCT |
914 |
931 |
915 static void collect_monitors(compiledVFrame* cvf, GrowableArray<Handle>* objects_to_revoke) { |
932 static void collect_monitors(compiledVFrame* cvf, GrowableArray<Handle>* objects_to_revoke) { |
916 GrowableArray<MonitorInfo*>* monitors = cvf->monitors(); |
933 GrowableArray<MonitorInfo*>* monitors = cvf->monitors(); |
917 for (int i = 0; i < monitors->length(); i++) { |
934 for (int i = 0; i < monitors->length(); i++) { |
918 MonitorInfo* mon_info = monitors->at(i); |
935 MonitorInfo* mon_info = monitors->at(i); |
919 if (mon_info->owner() != NULL) { |
936 if (mon_info->owner() != NULL && !mon_info->eliminated()) { |
920 objects_to_revoke->append(Handle(mon_info->owner())); |
937 objects_to_revoke->append(Handle(mon_info->owner())); |
921 } |
938 } |
922 } |
939 } |
923 } |
940 } |
924 |
941 |