171
172 void OopMap::set_narrowoop(VMReg reg) {
173 set_xxx(reg, OopMapValue::narrowoop_value, VMRegImpl::Bad());
174 }
175
176
177 void OopMap::set_callee_saved(VMReg reg, VMReg caller_machine_register ) {
178 set_xxx(reg, OopMapValue::callee_saved_value, caller_machine_register);
179 }
180
181
182 void OopMap::set_derived_oop(VMReg reg, VMReg derived_from_local_register ) {
183 if( reg == derived_from_local_register ) {
184 // Actually an oop, derived shares storage with base,
185 set_oop(reg);
186 } else {
187 set_xxx(reg, OopMapValue::derived_oop_value, derived_from_local_register);
188 }
189 }
190
191 void OopMap::set_stack_obj(VMReg reg) {
192 set_xxx(reg, OopMapValue::stack_obj, VMRegImpl::Bad());
193 }
194
195 // OopMapSet
196
197 OopMapSet::OopMapSet() {
198 set_om_size(MinOopMapAllocation);
199 set_om_count(0);
200 OopMap** temp = NEW_RESOURCE_ARRAY(OopMap*, om_size());
201 set_om_data(temp);
202 }
203
204
205 void OopMapSet::grow_om_data() {
206 int new_size = om_size() * 2;
207 OopMap** new_data = NEW_RESOURCE_ARRAY(OopMap*, new_size);
208 memcpy(new_data,om_data(),om_size() * sizeof(OopMap*));
209 set_om_size(new_size);
210 set_om_data(new_data);
211 }
212
213
214 void OopMapSet::copy_to(address addr) {
382 oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
383 if ( loc != NULL ) {
384 oop *base_loc = fr->oopmapreg_to_location(omv.content_reg(), reg_map);
385 oop *derived_loc = loc;
386 derived_oop_fn(base_loc, derived_loc);
387 }
388 oms.next();
389 } while (!oms.is_done());
390 }
391 }
392
393 // We want coop, value and oop oop_types
394 int mask = OopMapValue::oop_value | OopMapValue::value_value | OopMapValue::narrowoop_value;
395 {
396 for (OopMapStream oms(map,mask); !oms.is_done(); oms.next()) {
397 omv = oms.current();
398 oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
399 if ( loc != NULL ) {
400 if ( omv.type() == OopMapValue::oop_value ) {
401 #ifdef ASSERT
402 if (COMPILER2_PRESENT(!DoEscapeAnalysis &&)
403 (((uintptr_t)loc & (sizeof(*loc)-1)) != 0) ||
404 !Universe::heap()->is_in_or_null(*loc)) {
405 tty->print_cr("# Found non oop pointer. Dumping state at failure");
406 // try to dump out some helpful debugging information
407 trace_codeblob_maps(fr, reg_map);
408 omv.print();
409 tty->print_cr("register r");
410 omv.reg()->print();
411 tty->print_cr("loc = %p *loc = %p\n", loc, (address)*loc);
412 // do the real assert.
413 assert(Universe::heap()->is_in_or_null(*loc), "found non oop pointer");
414 }
415 #endif // ASSERT
416 oop_fn->do_oop(loc);
417 } else if ( omv.type() == OopMapValue::value_value ) {
418 value_fn->do_oop(loc);
419 } else if ( omv.type() == OopMapValue::narrowoop_value ) {
420 narrowOop *nl = (narrowOop*)loc;
421 #ifndef VM_LITTLE_ENDIAN
422 if (!omv.reg()->is_stack()) {
423 // compressed oops in registers only take up 4 bytes of an
424 // 8 byte register but they are in the wrong part of the
425 // word so adjust loc to point at the right place.
426 nl = (narrowOop*)((address)nl + 4);
427 }
428 #endif
429 oop_fn->do_oop(nl);
430 }
431 }
432 }
433 }
434
435 #ifdef COMPILER2
436 if (DoEscapeAnalysis) {
437 for (OopMapStream oms(map, OopMapValue::stack_obj); !oms.is_done(); oms.next()) {
438 omv = oms.current();
439 assert(omv.is_stack_loc(), "should refer to stack location");
440 oop loc = (oop) fr->oopmapreg_to_location(omv.reg(),reg_map);
441 oop_fn->do_oop(&loc);
442 }
443 }
444 #endif // COMPILER2
445 }
446
447
448 // Update callee-saved register info for the following frame
449 void OopMapSet::update_register_map(const frame *fr, RegisterMap *reg_map) {
450 ResourceMark rm;
451 CodeBlob* cb = fr->cb();
452 assert(cb != NULL, "no codeblob");
453
454 // Any reg might be saved by a safepoint handler (see generate_handler_blob).
455 const int max_saved_on_entry_reg_count = ConcreteRegisterImpl::number_of_registers;
456 assert( reg_map->_update_for_id == NULL || fr->is_older(reg_map->_update_for_id),
457 "already updated this map; do not 'update' it twice!" );
458 debug_only(reg_map->_update_for_id = fr->id());
459
460 // Check if caller must update oop argument
461 assert((reg_map->include_argument_oops() ||
462 !cb->caller_must_gc_arguments(reg_map->thread())),
463 "include_argument_oops should already be set");
464
523 void print_register_type(OopMapValue::oop_types x, VMReg optional,
524 outputStream* st) {
525 switch( x ) {
526 case OopMapValue::oop_value:
527 st->print("Oop");
528 break;
529 case OopMapValue::value_value:
530 st->print("Value" );
531 break;
532 case OopMapValue::narrowoop_value:
533 tty->print("NarrowOop" );
534 break;
535 case OopMapValue::callee_saved_value:
536 st->print("Callers_" );
537 optional->print_on(st);
538 break;
539 case OopMapValue::derived_oop_value:
540 st->print("Derived_oop_" );
541 optional->print_on(st);
542 break;
543 case OopMapValue::stack_obj:
544 st->print("Stack");
545 break;
546 default:
547 ShouldNotReachHere();
548 }
549 }
550
551
552 void OopMapValue::print_on(outputStream* st) const {
553 reg()->print_on(st);
554 st->print("=");
555 print_register_type(type(),content_reg(),st);
556 st->print(" ");
557 }
558
559
560 void OopMap::print_on(outputStream* st) const {
561 OopMapValue omv;
562 st->print("OopMap{");
563 for(OopMapStream oms((OopMap*)this); !oms.is_done(); oms.next()) {
564 omv = oms.current();
565 omv.print_on(st);
|
171
172 void OopMap::set_narrowoop(VMReg reg) {
173 set_xxx(reg, OopMapValue::narrowoop_value, VMRegImpl::Bad());
174 }
175
176
177 void OopMap::set_callee_saved(VMReg reg, VMReg caller_machine_register ) {
178 set_xxx(reg, OopMapValue::callee_saved_value, caller_machine_register);
179 }
180
181
182 void OopMap::set_derived_oop(VMReg reg, VMReg derived_from_local_register ) {
183 if( reg == derived_from_local_register ) {
184 // Actually an oop, derived shares storage with base,
185 set_oop(reg);
186 } else {
187 set_xxx(reg, OopMapValue::derived_oop_value, derived_from_local_register);
188 }
189 }
190
191 // OopMapSet
192
193 OopMapSet::OopMapSet() {
194 set_om_size(MinOopMapAllocation);
195 set_om_count(0);
196 OopMap** temp = NEW_RESOURCE_ARRAY(OopMap*, om_size());
197 set_om_data(temp);
198 }
199
200
201 void OopMapSet::grow_om_data() {
202 int new_size = om_size() * 2;
203 OopMap** new_data = NEW_RESOURCE_ARRAY(OopMap*, new_size);
204 memcpy(new_data,om_data(),om_size() * sizeof(OopMap*));
205 set_om_size(new_size);
206 set_om_data(new_data);
207 }
208
209
210 void OopMapSet::copy_to(address addr) {
378 oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
379 if ( loc != NULL ) {
380 oop *base_loc = fr->oopmapreg_to_location(omv.content_reg(), reg_map);
381 oop *derived_loc = loc;
382 derived_oop_fn(base_loc, derived_loc);
383 }
384 oms.next();
385 } while (!oms.is_done());
386 }
387 }
388
389 // We want coop, value and oop oop_types
390 int mask = OopMapValue::oop_value | OopMapValue::value_value | OopMapValue::narrowoop_value;
391 {
392 for (OopMapStream oms(map,mask); !oms.is_done(); oms.next()) {
393 omv = oms.current();
394 oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
395 if ( loc != NULL ) {
396 if ( omv.type() == OopMapValue::oop_value ) {
397 #ifdef ASSERT
398 if ((((uintptr_t)loc & (sizeof(*loc)-1)) != 0) ||
399 !Universe::heap()->is_in_or_null(*loc)) {
400 tty->print_cr("# Found non oop pointer. Dumping state at failure");
401 // try to dump out some helpful debugging information
402 trace_codeblob_maps(fr, reg_map);
403 omv.print();
404 tty->print_cr("register r");
405 omv.reg()->print();
406 tty->print_cr("loc = %p *loc = %p\n", loc, (address)*loc);
407 // do the real assert.
408 assert(Universe::heap()->is_in_or_null(*loc), "found non oop pointer");
409 }
410 #endif // ASSERT
411 oop_fn->do_oop(loc);
412 } else if ( omv.type() == OopMapValue::value_value ) {
413 value_fn->do_oop(loc);
414 } else if ( omv.type() == OopMapValue::narrowoop_value ) {
415 narrowOop *nl = (narrowOop*)loc;
416 #ifndef VM_LITTLE_ENDIAN
417 if (!omv.reg()->is_stack()) {
418 // compressed oops in registers only take up 4 bytes of an
419 // 8 byte register but they are in the wrong part of the
420 // word so adjust loc to point at the right place.
421 nl = (narrowOop*)((address)nl + 4);
422 }
423 #endif
424 oop_fn->do_oop(nl);
425 }
426 }
427 }
428 }
429 }
430
431
432 // Update callee-saved register info for the following frame
433 void OopMapSet::update_register_map(const frame *fr, RegisterMap *reg_map) {
434 ResourceMark rm;
435 CodeBlob* cb = fr->cb();
436 assert(cb != NULL, "no codeblob");
437
438 // Any reg might be saved by a safepoint handler (see generate_handler_blob).
439 const int max_saved_on_entry_reg_count = ConcreteRegisterImpl::number_of_registers;
440 assert( reg_map->_update_for_id == NULL || fr->is_older(reg_map->_update_for_id),
441 "already updated this map; do not 'update' it twice!" );
442 debug_only(reg_map->_update_for_id = fr->id());
443
444 // Check if caller must update oop argument
445 assert((reg_map->include_argument_oops() ||
446 !cb->caller_must_gc_arguments(reg_map->thread())),
447 "include_argument_oops should already be set");
448
507 void print_register_type(OopMapValue::oop_types x, VMReg optional,
508 outputStream* st) {
509 switch( x ) {
510 case OopMapValue::oop_value:
511 st->print("Oop");
512 break;
513 case OopMapValue::value_value:
514 st->print("Value" );
515 break;
516 case OopMapValue::narrowoop_value:
517 tty->print("NarrowOop" );
518 break;
519 case OopMapValue::callee_saved_value:
520 st->print("Callers_" );
521 optional->print_on(st);
522 break;
523 case OopMapValue::derived_oop_value:
524 st->print("Derived_oop_" );
525 optional->print_on(st);
526 break;
527 default:
528 ShouldNotReachHere();
529 }
530 }
531
532
533 void OopMapValue::print_on(outputStream* st) const {
534 reg()->print_on(st);
535 st->print("=");
536 print_register_type(type(),content_reg(),st);
537 st->print(" ");
538 }
539
540
541 void OopMap::print_on(outputStream* st) const {
542 OopMapValue omv;
543 st->print("OopMap{");
544 for(OopMapStream oms((OopMap*)this); !oms.is_done(); oms.next()) {
545 omv = oms.current();
546 omv.print_on(st);
|