Mercurial > hg > truffle
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; |