< prev index next >

src/hotspot/cpu/x86/templateTable_x86.cpp

Print this page

2545   __ dispatch_only(vtos, true);
2546 
2547   // default case -> j = default offset
2548   __ bind(default_case);
2549   __ profile_switch_default(i);
2550   __ movl(j, Address(array, -2 * BytesPerInt));
2551   __ bswapl(j);
2552   LP64_ONLY(__ movslq(j, j));
2553 
2554   NOT_LP64(__ restore_bcp());
2555   NOT_LP64(__ restore_locals());
2556 
2557   __ load_unsigned_byte(rbx, Address(rbcp, j, Address::times_1));
2558   __ addptr(rbcp, j);
2559   __ dispatch_only(vtos, true);
2560 }
2561 
2562 void TemplateTable::_return(TosState state) {
2563   transition(state, state);
2564 











2565   assert(_desc->calls_vm(),
2566          "inconsistent calls_vm information"); // call in remove_activation
2567 
2568   if (_desc->bytecode() == Bytecodes::_return_register_finalizer) {
2569     assert(state == vtos, "only valid state");
2570     Register robj = LP64_ONLY(c_rarg1) NOT_LP64(rax);
2571     __ movptr(robj, aaddress(0));
2572     Register tmp_load_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);
2573     __ load_klass(rdi, robj, tmp_load_klass);
2574     __ movl(rdi, Address(rdi, Klass::access_flags_offset()));
2575     __ testl(rdi, JVM_ACC_HAS_FINALIZER);
2576     Label skip_register_finalizer;
2577     __ jcc(Assembler::zero, skip_register_finalizer);
2578 
2579     __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::register_finalizer), robj);
2580 
2581     __ bind(skip_register_finalizer);
2582   }
2583 
2584   if (_desc->bytecode() != Bytecodes::_return_register_finalizer) {
2585     Label no_safepoint;
2586     NOT_PRODUCT(__ block_comment("Thread-local Safepoint poll"));
2587 #ifdef _LP64
2588     __ testb(Address(r15_thread, JavaThread::polling_word_offset()), SafepointMechanism::poll_bit());
2589 #else
2590     const Register thread = rdi;
2591     __ get_thread(thread);
2592     __ testb(Address(thread, JavaThread::polling_word_offset()), SafepointMechanism::poll_bit());
2593 #endif
2594     __ jcc(Assembler::zero, no_safepoint);
2595     __ push(state);

2596     __ call_VM(noreg, CAST_FROM_FN_PTR(address,
2597                                        InterpreterRuntime::at_safepoint));


2598     __ pop(state);
2599     __ bind(no_safepoint);
2600   }
2601 
2602   // Narrow result if state is itos but result type is smaller.
2603   // Need to narrow in the return bytecode rather than in generate_return_entry
2604   // since compiled code callers expect the result to already be narrowed.
2605   if (state == itos) {
2606     __ narrow(rax);
2607   }
2608   __ remove_activation(state, rbcp);
2609 
2610   __ jmp(rbcp);
2611 }
2612 
2613 // ----------------------------------------------------------------------------
2614 // Volatile variables demand their effects be made known to all CPU's
2615 // in order.  Store buffers on most chips allow reads & writes to
2616 // reorder; the JMM's ReadAfterWrite.java test fails in -Xint mode
2617 // without some kind of memory barrier (i.e., it's not sufficient that

4345     __ bind(entry);
4346     __ cmpptr(rtop, rmon);                      // check if bottom reached
4347     __ jcc(Assembler::notEqual, loop);          // if not at bottom then
4348                                                 // copy next word
4349   }
4350 
4351   // call run-time routine
4352   // rmon: points to monitor entry
4353   __ bind(allocated);
4354 
4355   // Increment bcp to point to the next bytecode, so exception
4356   // handling for async. exceptions work correctly.
4357   // The object has already been poped from the stack, so the
4358   // expression stack looks correct.
4359   __ increment(rbcp);
4360 
4361   // store object
4362   __ movptr(Address(rmon, BasicObjectLock::obj_offset_in_bytes()), rax);
4363   __ lock_object(rmon);
4364 





4365   // check to make sure this monitor doesn't cause stack overflow after locking
4366   __ save_bcp();  // in case of exception
4367   __ generate_stack_overflow_check(0);
4368 
4369   // The bcp has already been incremented. Just need to dispatch to
4370   // next instruction.
4371   __ dispatch_next(vtos);
4372 }
4373 
4374 void TemplateTable::monitorexit() {
4375   transition(atos, vtos);
4376 
4377   // check for NULL object
4378   __ null_check(rax);
4379 
4380   const Address monitor_block_top(
4381         rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize);
4382   const Address monitor_block_bot(
4383         rbp, frame::interpreter_frame_initial_sp_offset * wordSize);
4384   const int entry_size = frame::interpreter_frame_monitor_size() * wordSize;

4403     // if same object then stop searching
4404     __ jcc(Assembler::equal, found);
4405     // otherwise advance to next entry
4406     __ addptr(rtop, entry_size);
4407     __ bind(entry);
4408     // check if bottom reached
4409     __ cmpptr(rtop, rbot);
4410     // if not at bottom then check this entry
4411     __ jcc(Assembler::notEqual, loop);
4412   }
4413 
4414   // error handling. Unlocking was not block-structured
4415   __ call_VM(noreg, CAST_FROM_FN_PTR(address,
4416                    InterpreterRuntime::throw_illegal_monitor_state_exception));
4417   __ should_not_reach_here();
4418 
4419   // call run-time routine
4420   __ bind(found);
4421   __ push_ptr(rax); // make sure object is on stack (contract with oopMaps)
4422   __ unlock_object(rtop);





4423   __ pop_ptr(rax); // discard object
4424 }
4425 
4426 // Wide instructions
4427 void TemplateTable::wide() {
4428   transition(vtos, vtos);
4429   __ load_unsigned_byte(rbx, at_bcp(1));
4430   ExternalAddress wtable((address)Interpreter::_wentry_point);
4431   __ jump(ArrayAddress(wtable, Address(noreg, rbx, Address::times_ptr)));
4432   // Note: the rbcp increment step is part of the individual wide bytecode implementations
4433 }
4434 
4435 // Multi arrays
4436 void TemplateTable::multianewarray() {
4437   transition(vtos, atos);
4438 
4439   Register rarg = LP64_ONLY(c_rarg1) NOT_LP64(rax);
4440   __ load_unsigned_byte(rax, at_bcp(3)); // get number of dimensions
4441   // last dim is on top of stack; we want address of first one:
4442   // first_addr = last_addr + (ndims - 1) * stackElementSize - 1*wordsize

2545   __ dispatch_only(vtos, true);
2546 
2547   // default case -> j = default offset
2548   __ bind(default_case);
2549   __ profile_switch_default(i);
2550   __ movl(j, Address(array, -2 * BytesPerInt));
2551   __ bswapl(j);
2552   LP64_ONLY(__ movslq(j, j));
2553 
2554   NOT_LP64(__ restore_bcp());
2555   NOT_LP64(__ restore_locals());
2556 
2557   __ load_unsigned_byte(rbx, Address(rbcp, j, Address::times_1));
2558   __ addptr(rbcp, j);
2559   __ dispatch_only(vtos, true);
2560 }
2561 
2562 void TemplateTable::_return(TosState state) {
2563   transition(state, state);
2564 
2565   // {
2566   //   Label not_rb;
2567   //   Register aa = rcx, bb = rdi;
2568   //   __ movptr(aa, Address(rsp, 0));
2569   //   __ lea(bb, ExternalAddress(StubRoutines::cont_returnBarrier()));
2570   //   __ cmpq(aa, bb);
2571   //   // __ cmpq(ExternalAddress(StubRoutines::cont_returnBarrier()).addr(), aa);
2572   //   __ jcc(Assembler::notZero, not_rb);
2573   //   __ stop("WQWWQWQW");
2574   //   __ bind(not_rb);
2575   // }
2576   assert(_desc->calls_vm(),
2577          "inconsistent calls_vm information"); // call in remove_activation
2578 
2579   if (_desc->bytecode() == Bytecodes::_return_register_finalizer) {
2580     assert(state == vtos, "only valid state");
2581     Register robj = LP64_ONLY(c_rarg1) NOT_LP64(rax);
2582     __ movptr(robj, aaddress(0));
2583     Register tmp_load_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);
2584     __ load_klass(rdi, robj, tmp_load_klass);
2585     __ movl(rdi, Address(rdi, Klass::access_flags_offset()));
2586     __ testl(rdi, JVM_ACC_HAS_FINALIZER);
2587     Label skip_register_finalizer;
2588     __ jcc(Assembler::zero, skip_register_finalizer);
2589 
2590     __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::register_finalizer), robj);
2591 
2592     __ bind(skip_register_finalizer);
2593   }
2594 
2595   if (_desc->bytecode() != Bytecodes::_return_register_finalizer) {
2596     Label no_safepoint;
2597     NOT_PRODUCT(__ block_comment("Thread-local Safepoint poll"));
2598 #ifdef _LP64
2599     __ testb(Address(r15_thread, JavaThread::polling_word_offset()), SafepointMechanism::poll_bit());
2600 #else
2601     const Register thread = rdi;
2602     __ get_thread(thread);
2603     __ testb(Address(thread, JavaThread::polling_word_offset()), SafepointMechanism::poll_bit());
2604 #endif
2605     __ jcc(Assembler::zero, no_safepoint);
2606     __ push(state);
2607     __ push_cont_fastpath(NOT_LP64(thread) LP64_ONLY(r15_thread));
2608     __ call_VM(noreg, CAST_FROM_FN_PTR(address,
2609                                        InterpreterRuntime::at_safepoint));
2610     NOT_LP64(__ get_thread(thread);)
2611     __ pop_cont_fastpath(NOT_LP64(thread) LP64_ONLY(r15_thread));
2612     __ pop(state);
2613     __ bind(no_safepoint);
2614   }
2615 
2616   // Narrow result if state is itos but result type is smaller.
2617   // Need to narrow in the return bytecode rather than in generate_return_entry
2618   // since compiled code callers expect the result to already be narrowed.
2619   if (state == itos) {
2620     __ narrow(rax);
2621   }
2622   __ remove_activation(state, rbcp);
2623 
2624   __ jmp(rbcp);
2625 }
2626 
2627 // ----------------------------------------------------------------------------
2628 // Volatile variables demand their effects be made known to all CPU's
2629 // in order.  Store buffers on most chips allow reads & writes to
2630 // reorder; the JMM's ReadAfterWrite.java test fails in -Xint mode
2631 // without some kind of memory barrier (i.e., it's not sufficient that

4359     __ bind(entry);
4360     __ cmpptr(rtop, rmon);                      // check if bottom reached
4361     __ jcc(Assembler::notEqual, loop);          // if not at bottom then
4362                                                 // copy next word
4363   }
4364 
4365   // call run-time routine
4366   // rmon: points to monitor entry
4367   __ bind(allocated);
4368 
4369   // Increment bcp to point to the next bytecode, so exception
4370   // handling for async. exceptions work correctly.
4371   // The object has already been poped from the stack, so the
4372   // expression stack looks correct.
4373   __ increment(rbcp);
4374 
4375   // store object
4376   __ movptr(Address(rmon, BasicObjectLock::obj_offset_in_bytes()), rax);
4377   __ lock_object(rmon);
4378 
4379   // The object is stored so counter should be increased even if stackoverflow is generated
4380   Register rthread = LP64_ONLY(r15_thread) NOT_LP64(rbx);
4381   NOT_LP64(__ get_thread(rthread);)
4382   __ inc_held_monitor_count(rthread);
4383 
4384   // check to make sure this monitor doesn't cause stack overflow after locking
4385   __ save_bcp();  // in case of exception
4386   __ generate_stack_overflow_check(0);
4387 
4388   // The bcp has already been incremented. Just need to dispatch to
4389   // next instruction.
4390   __ dispatch_next(vtos);
4391 }
4392 
4393 void TemplateTable::monitorexit() {
4394   transition(atos, vtos);
4395 
4396   // check for NULL object
4397   __ null_check(rax);
4398 
4399   const Address monitor_block_top(
4400         rbp, frame::interpreter_frame_monitor_block_top_offset * wordSize);
4401   const Address monitor_block_bot(
4402         rbp, frame::interpreter_frame_initial_sp_offset * wordSize);
4403   const int entry_size = frame::interpreter_frame_monitor_size() * wordSize;

4422     // if same object then stop searching
4423     __ jcc(Assembler::equal, found);
4424     // otherwise advance to next entry
4425     __ addptr(rtop, entry_size);
4426     __ bind(entry);
4427     // check if bottom reached
4428     __ cmpptr(rtop, rbot);
4429     // if not at bottom then check this entry
4430     __ jcc(Assembler::notEqual, loop);
4431   }
4432 
4433   // error handling. Unlocking was not block-structured
4434   __ call_VM(noreg, CAST_FROM_FN_PTR(address,
4435                    InterpreterRuntime::throw_illegal_monitor_state_exception));
4436   __ should_not_reach_here();
4437 
4438   // call run-time routine
4439   __ bind(found);
4440   __ push_ptr(rax); // make sure object is on stack (contract with oopMaps)
4441   __ unlock_object(rtop);
4442   
4443   Register rthread = LP64_ONLY(r15_thread) NOT_LP64(rax);
4444   NOT_LP64(__ get_thread(rthread);)
4445   __ dec_held_monitor_count(rthread);
4446 
4447   __ pop_ptr(rax); // discard object
4448 }
4449 
4450 // Wide instructions
4451 void TemplateTable::wide() {
4452   transition(vtos, vtos);
4453   __ load_unsigned_byte(rbx, at_bcp(1));
4454   ExternalAddress wtable((address)Interpreter::_wentry_point);
4455   __ jump(ArrayAddress(wtable, Address(noreg, rbx, Address::times_ptr)));
4456   // Note: the rbcp increment step is part of the individual wide bytecode implementations
4457 }
4458 
4459 // Multi arrays
4460 void TemplateTable::multianewarray() {
4461   transition(vtos, atos);
4462 
4463   Register rarg = LP64_ONLY(c_rarg1) NOT_LP64(rax);
4464   __ load_unsigned_byte(rax, at_bcp(3)); // get number of dimensions
4465   // last dim is on top of stack; we want address of first one:
4466   // first_addr = last_addr + (ndims - 1) * stackElementSize - 1*wordsize
< prev index next >