Mercurial > hg > graal-compiler
comparison src/share/vm/runtime/deoptimization.cpp @ 4042:b20d64f83668
7090904: JSR 292: JRuby junit test crashes in PSScavengeRootsClosure::do_oop
Reviewed-by: kvn, never, jrose
author | twisti |
---|---|
date | Mon, 24 Oct 2011 07:53:17 -0700 |
parents | 5432047c7db7 |
children | e342a5110bed |
comparison
equal
deleted
inserted
replaced
4041:42783d1414b2 | 4042:b20d64f83668 |
---|---|
360 // Compute the vframes' sizes. Note that frame_sizes[] entries are ordered from outermost to innermost | 360 // Compute the vframes' sizes. Note that frame_sizes[] entries are ordered from outermost to innermost |
361 // virtual activation, which is the reverse of the elements in the vframes array. | 361 // virtual activation, which is the reverse of the elements in the vframes array. |
362 intptr_t* frame_sizes = NEW_C_HEAP_ARRAY(intptr_t, number_of_frames); | 362 intptr_t* frame_sizes = NEW_C_HEAP_ARRAY(intptr_t, number_of_frames); |
363 // +1 because we always have an interpreter return address for the final slot. | 363 // +1 because we always have an interpreter return address for the final slot. |
364 address* frame_pcs = NEW_C_HEAP_ARRAY(address, number_of_frames + 1); | 364 address* frame_pcs = NEW_C_HEAP_ARRAY(address, number_of_frames + 1); |
365 int callee_parameters = 0; | |
366 int callee_locals = 0; | |
367 int popframe_extra_args = 0; | 365 int popframe_extra_args = 0; |
368 // Create an interpreter return address for the stub to use as its return | 366 // Create an interpreter return address for the stub to use as its return |
369 // address so the skeletal frames are perfectly walkable | 367 // address so the skeletal frames are perfectly walkable |
370 frame_pcs[number_of_frames] = Interpreter::deopt_entry(vtos, 0); | 368 frame_pcs[number_of_frames] = Interpreter::deopt_entry(vtos, 0); |
371 | 369 |
385 // It's possible that the number of paramters at the call site is | 383 // It's possible that the number of paramters at the call site is |
386 // different than number of arguments in the callee when method | 384 // different than number of arguments in the callee when method |
387 // handles are used. If the caller is interpreted get the real | 385 // handles are used. If the caller is interpreted get the real |
388 // value so that the proper amount of space can be added to it's | 386 // value so that the proper amount of space can be added to it's |
389 // frame. | 387 // frame. |
390 int caller_actual_parameters = callee_parameters; | 388 bool caller_was_method_handle = false; |
391 if (deopt_sender.is_interpreted_frame()) { | 389 if (deopt_sender.is_interpreted_frame()) { |
392 methodHandle method = deopt_sender.interpreter_frame_method(); | 390 methodHandle method = deopt_sender.interpreter_frame_method(); |
393 Bytecode_invoke cur = Bytecode_invoke_check(method, | 391 Bytecode_invoke cur = Bytecode_invoke_check(method, |
394 deopt_sender.interpreter_frame_bci()); | 392 deopt_sender.interpreter_frame_bci()); |
395 Symbol* signature = method->constants()->signature_ref_at(cur.index()); | 393 if (cur.code() == Bytecodes::_invokedynamic || |
396 ArgumentSizeComputer asc(signature); | 394 (cur.code() == Bytecodes::_invokevirtual && |
397 caller_actual_parameters = asc.size() + (cur.has_receiver() ? 1 : 0); | 395 method->constants()->klass_ref_at_noresolve(cur.index()) == vmSymbols::java_lang_invoke_MethodHandle() && |
396 methodOopDesc::is_method_handle_invoke_name(cur.name()))) { | |
397 // Method handle invokes may involve fairly arbitrary chains of | |
398 // calls so it's impossible to know how much actual space the | |
399 // caller has for locals. | |
400 caller_was_method_handle = true; | |
401 } | |
398 } | 402 } |
399 | 403 |
400 // | 404 // |
401 // frame_sizes/frame_pcs[0] oldest frame (int or c2i) | 405 // frame_sizes/frame_pcs[0] oldest frame (int or c2i) |
402 // frame_sizes/frame_pcs[1] next oldest frame (int) | 406 // frame_sizes/frame_pcs[1] next oldest frame (int) |
409 // 0.._frames-1. Index 0 is the youngest frame and _frame - 1 is the oldest (root) frame. | 413 // 0.._frames-1. Index 0 is the youngest frame and _frame - 1 is the oldest (root) frame. |
410 // When we create the skeletal frames we need the oldest frame to be in the zero slot | 414 // When we create the skeletal frames we need the oldest frame to be in the zero slot |
411 // in the frame_sizes/frame_pcs so the assembly code can do a trivial walk. | 415 // in the frame_sizes/frame_pcs so the assembly code can do a trivial walk. |
412 // so things look a little strange in this loop. | 416 // so things look a little strange in this loop. |
413 // | 417 // |
418 int callee_parameters = 0; | |
419 int callee_locals = 0; | |
414 for (int index = 0; index < array->frames(); index++ ) { | 420 for (int index = 0; index < array->frames(); index++ ) { |
415 // frame[number_of_frames - 1 ] = on_stack_size(youngest) | 421 // frame[number_of_frames - 1 ] = on_stack_size(youngest) |
416 // frame[number_of_frames - 2 ] = on_stack_size(sender(youngest)) | 422 // frame[number_of_frames - 2 ] = on_stack_size(sender(youngest)) |
417 // frame[number_of_frames - 3 ] = on_stack_size(sender(sender(youngest))) | 423 // frame[number_of_frames - 3 ] = on_stack_size(sender(sender(youngest))) |
418 int caller_parms = callee_parameters; | 424 int caller_parms = callee_parameters; |
419 if (index == array->frames() - 1) { | 425 if ((index == array->frames() - 1) && caller_was_method_handle) { |
420 // Use the value from the interpreted caller | 426 caller_parms = 0; |
421 caller_parms = caller_actual_parameters; | |
422 } | 427 } |
423 frame_sizes[number_of_frames - 1 - index] = BytesPerWord * array->element(index)->on_stack_size(caller_parms, | 428 frame_sizes[number_of_frames - 1 - index] = BytesPerWord * array->element(index)->on_stack_size(caller_parms, |
424 callee_parameters, | 429 callee_parameters, |
425 callee_locals, | 430 callee_locals, |
426 index == 0, | 431 index == 0, |
458 // may not even be enough space). | 463 // may not even be enough space). |
459 | 464 |
460 // QQQ I'd rather see this pushed down into last_frame_adjust | 465 // QQQ I'd rather see this pushed down into last_frame_adjust |
461 // and have it take the sender (aka caller). | 466 // and have it take the sender (aka caller). |
462 | 467 |
463 if (deopt_sender.is_compiled_frame()) { | 468 if (deopt_sender.is_compiled_frame() || caller_was_method_handle) { |
464 caller_adjustment = last_frame_adjust(0, callee_locals); | 469 caller_adjustment = last_frame_adjust(0, callee_locals); |
465 } else if (callee_locals > caller_actual_parameters) { | 470 } else if (callee_locals > callee_parameters) { |
466 // The caller frame may need extending to accommodate | 471 // The caller frame may need extending to accommodate |
467 // non-parameter locals of the first unpacked interpreted frame. | 472 // non-parameter locals of the first unpacked interpreted frame. |
468 // Compute that adjustment. | 473 // Compute that adjustment. |
469 caller_adjustment = last_frame_adjust(caller_actual_parameters, callee_locals); | 474 caller_adjustment = last_frame_adjust(callee_parameters, callee_locals); |
470 } | 475 } |
471 | 476 |
472 // If the sender is deoptimized the we must retrieve the address of the handler | 477 // If the sender is deoptimized the we must retrieve the address of the handler |
473 // since the frame will "magically" show the original pc before the deopt | 478 // since the frame will "magically" show the original pc before the deopt |
474 // and we'd undo the deopt. | 479 // and we'd undo the deopt. |
479 assert(CodeCache::find_blob_unsafe(frame_pcs[0]) != NULL, "bad pc"); | 484 assert(CodeCache::find_blob_unsafe(frame_pcs[0]) != NULL, "bad pc"); |
480 #endif // SHARK | 485 #endif // SHARK |
481 | 486 |
482 UnrollBlock* info = new UnrollBlock(array->frame_size() * BytesPerWord, | 487 UnrollBlock* info = new UnrollBlock(array->frame_size() * BytesPerWord, |
483 caller_adjustment * BytesPerWord, | 488 caller_adjustment * BytesPerWord, |
484 caller_actual_parameters, | 489 caller_was_method_handle ? 0 : callee_parameters, |
485 number_of_frames, | 490 number_of_frames, |
486 frame_sizes, | 491 frame_sizes, |
487 frame_pcs, | 492 frame_pcs, |
488 return_type); | 493 return_type); |
489 // On some platforms, we need a way to pass some platform dependent | 494 // On some platforms, we need a way to pass some platform dependent |