comparison src/share/vm/compiler/oopMap.cpp @ 113:ba764ed4b6f2

6420645: Create a vm that uses compressed oops for up to 32gb heapsizes Summary: Compressed oops in instances, arrays, and headers. Code contributors are coleenp, phh, never, swamyv Reviewed-by: jmasa, kamg, acorn, tbell, kvn, rasbold
author coleenp
date Sun, 13 Apr 2008 17:43:42 -0400
parents c7c777385a15
children d1605aabd0a1 524eca34ea76
comparison
equal deleted inserted replaced
110:a49a647afe9a 113:ba764ed4b6f2
167 if (ZapDeadCompiledLocals) 167 if (ZapDeadCompiledLocals)
168 set_xxx(reg, OopMapValue::value_value, VMRegImpl::Bad()); 168 set_xxx(reg, OopMapValue::value_value, VMRegImpl::Bad());
169 } 169 }
170 170
171 171
172 void OopMap::set_dead(VMReg reg) { 172 void OopMap::set_narrowoop(VMReg reg) {
173 // At this time, we only need dead entries in our OopMap when ZapDeadCompiledLocals is active. 173 set_xxx(reg, OopMapValue::narrowoop_value, VMRegImpl::Bad());
174 if (ZapDeadCompiledLocals) {
175 set_xxx(reg, OopMapValue::dead_value, VMRegImpl::Bad());
176 }
177 } 174 }
178 175
179 176
180 void OopMap::set_callee_saved(VMReg reg, VMReg caller_machine_register ) { 177 void OopMap::set_callee_saved(VMReg reg, VMReg caller_machine_register ) {
181 set_xxx(reg, OopMapValue::callee_saved_value, caller_machine_register); 178 set_xxx(reg, OopMapValue::callee_saved_value, caller_machine_register);
303 assert( m->offset() == pc_offset, "oopmap not found" ); 300 assert( m->offset() == pc_offset, "oopmap not found" );
304 return m; 301 return m;
305 } 302 }
306 303
307 class DoNothingClosure: public OopClosure { 304 class DoNothingClosure: public OopClosure {
308 public: void do_oop(oop* p) {} 305 public:
306 void do_oop(oop* p) {}
307 void do_oop(narrowOop* p) {}
309 }; 308 };
310 static DoNothingClosure do_nothing; 309 static DoNothingClosure do_nothing;
311 310
312 static void add_derived_oop(oop* base, oop* derived) { 311 static void add_derived_oop(oop* base, oop* derived) {
313 #ifndef TIERED 312 #ifndef TIERED
347 } 346 }
348 #endif // PRODUCT 347 #endif // PRODUCT
349 348
350 void OopMapSet::oops_do(const frame *fr, const RegisterMap* reg_map, OopClosure* f) { 349 void OopMapSet::oops_do(const frame *fr, const RegisterMap* reg_map, OopClosure* f) {
351 // add derived oops to a table 350 // add derived oops to a table
352 all_do(fr, reg_map, f, add_derived_oop, &do_nothing, &do_nothing); 351 all_do(fr, reg_map, f, add_derived_oop, &do_nothing);
353 } 352 }
354 353
355 354
356 void OopMapSet::all_do(const frame *fr, const RegisterMap *reg_map, 355 void OopMapSet::all_do(const frame *fr, const RegisterMap *reg_map,
357 OopClosure* oop_fn, void derived_oop_fn(oop*, oop*), 356 OopClosure* oop_fn, void derived_oop_fn(oop*, oop*),
358 OopClosure* value_fn, OopClosure* dead_fn) { 357 OopClosure* value_fn) {
359 CodeBlob* cb = fr->cb(); 358 CodeBlob* cb = fr->cb();
360 { 359 assert(cb != NULL, "no codeblob");
361 assert(cb != NULL, "no codeblob");
362 }
363 360
364 NOT_PRODUCT(if (TraceCodeBlobStacks) trace_codeblob_maps(fr, reg_map);) 361 NOT_PRODUCT(if (TraceCodeBlobStacks) trace_codeblob_maps(fr, reg_map);)
365 362
366 OopMapSet* maps = cb->oop_maps(); 363 OopMapSet* maps = cb->oop_maps();
367 OopMap* map = cb->oop_map_for_return_address(fr->pc()); 364 OopMap* map = cb->oop_map_for_return_address(fr->pc());
368 assert(map != NULL, " no ptr map found"); 365 assert(map != NULL, "no ptr map found");
369 366
370 // handle derived pointers first (otherwise base pointer may be 367 // handle derived pointers first (otherwise base pointer may be
371 // changed before derived pointer offset has been collected) 368 // changed before derived pointer offset has been collected)
372 OopMapValue omv; 369 OopMapValue omv;
373 { 370 {
391 oms.next(); 388 oms.next();
392 } while (!oms.is_done()); 389 } while (!oms.is_done());
393 } 390 }
394 } 391 }
395 392
396 // We want dead, value and oop oop_types 393 // We want coop, value and oop oop_types
397 int mask = OopMapValue::oop_value | OopMapValue::value_value | OopMapValue::dead_value; 394 int mask = OopMapValue::oop_value | OopMapValue::value_value | OopMapValue::narrowoop_value;
398 { 395 {
399 for (OopMapStream oms(map,mask); !oms.is_done(); oms.next()) { 396 for (OopMapStream oms(map,mask); !oms.is_done(); oms.next()) {
400 omv = oms.current(); 397 omv = oms.current();
401 oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map); 398 oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
402 if ( loc != NULL ) { 399 if ( loc != NULL ) {
403 if ( omv.type() == OopMapValue::oop_value ) { 400 if ( omv.type() == OopMapValue::oop_value ) {
404 #ifdef ASSERT 401 #ifdef ASSERT
405 if (COMPILER2_PRESENT(!DoEscapeAnalysis &&) !Universe::heap()->is_in_or_null(*loc)) { 402 if (COMPILER2_PRESENT(!DoEscapeAnalysis &&)
403 (((uintptr_t)loc & (sizeof(*loc)-1)) != 0) ||
404 !Universe::heap()->is_in_or_null(*loc)) {
406 tty->print_cr("# Found non oop pointer. Dumping state at failure"); 405 tty->print_cr("# Found non oop pointer. Dumping state at failure");
407 // try to dump out some helpful debugging information 406 // try to dump out some helpful debugging information
408 trace_codeblob_maps(fr, reg_map); 407 trace_codeblob_maps(fr, reg_map);
409 omv.print(); 408 omv.print();
409 tty->print_cr("register r");
410 omv.reg()->print();
410 tty->print_cr("loc = %p *loc = %p\n", loc, (address)*loc); 411 tty->print_cr("loc = %p *loc = %p\n", loc, (address)*loc);
411 // do the real assert. 412 // do the real assert.
412 assert(Universe::heap()->is_in_or_null(*loc), "found non oop pointer"); 413 assert(Universe::heap()->is_in_or_null(*loc), "found non oop pointer");
413 } 414 }
414 #endif // ASSERT 415 #endif // ASSERT
415 oop_fn->do_oop(loc); 416 oop_fn->do_oop(loc);
416 } else if ( omv.type() == OopMapValue::value_value ) { 417 } else if ( omv.type() == OopMapValue::value_value ) {
417 value_fn->do_oop(loc); 418 value_fn->do_oop(loc);
418 } else if ( omv.type() == OopMapValue::dead_value ) { 419 } else if ( omv.type() == OopMapValue::narrowoop_value ) {
419 dead_fn->do_oop(loc); 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);
420 } 430 }
421 } 431 }
422 } 432 }
423 } 433 }
424 434
517 st->print("Oop"); 527 st->print("Oop");
518 break; 528 break;
519 case OopMapValue::value_value: 529 case OopMapValue::value_value:
520 st->print("Value" ); 530 st->print("Value" );
521 break; 531 break;
522 case OopMapValue::dead_value: 532 case OopMapValue::narrowoop_value:
523 st->print("Dead" ); 533 tty->print("NarrowOop" );
524 break; 534 break;
525 case OopMapValue::callee_saved_value: 535 case OopMapValue::callee_saved_value:
526 st->print("Callers_" ); 536 st->print("Callers_" );
527 optional->print_on(st); 537 optional->print_on(st);
528 break; 538 break;