Print this page


Split Close
Expand all
Collapse all
          --- old/src/cpu/x86/vm/stubGenerator_x86_32.cpp
          +++ new/src/cpu/x86/vm/stubGenerator_x86_32.cpp
↓ open down ↓ 361 lines elided ↑ open up ↑
 362  362      return start;
 363  363    }
 364  364  
 365  365  
 366  366    //------------------------------------------------------------------------------------------------------------------------
 367  367    // Continuation point for runtime calls returning with a pending exception.
 368  368    // The pending exception check happened in the runtime or native call stub.
 369  369    // The pending exception in Thread is converted into a Java-level exception.
 370  370    //
 371  371    // Contract with Java-level exception handlers:
 372      -  // rax,: exception
      372 +  // rax: exception
 373  373    // rdx: throwing pc
 374  374    //
 375  375    // NOTE: At entry of this stub, exception-pc must be on stack !!
 376  376  
 377  377    address generate_forward_exception() {
 378  378      StubCodeMark mark(this, "StubRoutines", "forward exception");
 379  379      address start = __ pc();
      380 +    const Register thread = rcx;
      381 +
      382 +    // other registers used in this stub
      383 +    const Register exception_oop = rax;
      384 +    const Register handler_addr  = rbx;
      385 +    const Register exception_pc  = rdx;
 380  386  
 381  387      // Upon entry, the sp points to the return address returning into Java
 382  388      // (interpreted or compiled) code; i.e., the return address becomes the
 383  389      // throwing pc.
 384  390      //
 385  391      // Arguments pushed before the runtime call are still on the stack but
 386  392      // the exception handler will reset the stack pointer -> ignore them.
 387  393      // A potential result in registers can be ignored as well.
 388  394  
 389  395  #ifdef ASSERT
 390  396      // make sure this code is only executed if there is a pending exception
 391  397      { Label L;
 392      -      __ get_thread(rcx);
 393      -      __ cmpptr(Address(rcx, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
      398 +      __ get_thread(thread);
      399 +      __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD);
 394  400        __ jcc(Assembler::notEqual, L);
 395  401        __ stop("StubRoutines::forward exception: no pending exception (1)");
 396  402        __ bind(L);
 397  403      }
 398  404  #endif
 399  405  
 400  406      // compute exception handler into rbx,
 401      -    __ movptr(rax, Address(rsp, 0));
      407 +    __ get_thread(thread);
      408 +    __ movptr(exception_pc, Address(rsp, 0));
 402  409      BLOCK_COMMENT("call exception_handler_for_return_address");
 403      -    __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), rax);
 404      -    __ mov(rbx, rax);
      410 +    __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), thread, exception_pc);
      411 +    __ mov(handler_addr, rax);
 405  412  
 406      -    // setup rax, & rdx, remove return address & clear pending exception
 407      -    __ get_thread(rcx);
 408      -    __ pop(rdx);
 409      -    __ movptr(rax, Address(rcx, Thread::pending_exception_offset()));
 410      -    __ movptr(Address(rcx, Thread::pending_exception_offset()), NULL_WORD);
      413 +    // setup rax & rdx, remove return address & clear pending exception
      414 +    __ get_thread(thread);
      415 +    __ pop(exception_pc);
      416 +    __ movptr(exception_oop, Address(thread, Thread::pending_exception_offset()));
      417 +    __ movptr(Address(thread, Thread::pending_exception_offset()), NULL_WORD);
 411  418  
 412  419  #ifdef ASSERT
 413  420      // make sure exception is set
 414  421      { Label L;
 415      -      __ testptr(rax, rax);
      422 +      __ testptr(exception_oop, exception_oop);
 416  423        __ jcc(Assembler::notEqual, L);
 417  424        __ stop("StubRoutines::forward exception: no pending exception (2)");
 418  425        __ bind(L);
 419  426      }
 420  427  #endif
 421  428  
      429 +    // Verify that there is really a valid exception in RAX.
      430 +    __ verify_oop(exception_oop);
      431 +
      432 +    // Restore SP from BP if the exception PC is a MethodHandle call site.
      433 +    __ cmpl(Address(thread, JavaThread::is_method_handle_exception_offset()), 0);
      434 +    __ cmovptr(Assembler::notEqual, rsp, rbp);
      435 +
 422  436      // continue at exception handler (return address removed)
 423      -    // rax,: exception
 424      -    // rbx,: exception handler
      437 +    // rax: exception
      438 +    // rbx: exception handler
 425  439      // rdx: throwing pc
 426      -    __ verify_oop(rax);
 427      -    __ jmp(rbx);
      440 +    __ jmp(handler_addr);
 428  441  
 429  442      return start;
 430  443    }
 431  444  
 432  445  
 433  446    //----------------------------------------------------------------------------------------------------
 434  447    // Support for jint Atomic::xchg(jint exchange_value, volatile jint* dest)
 435  448    //
 436  449    // xchg exists as far back as 8086, lock needed for MP only
 437  450    // Stack layout immediately after call:
↓ open down ↓ 1856 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX