< prev index next >

src/hotspot/cpu/x86/templateTable_x86.cpp

Print this page
rev 47596 : imported patch Interpreter-Poll-7
rev 47597 : imported patch Interpreter-Poll-Wide_Ret-8
rev 47598 : imported patch Interpreter-Poll-Switch-10
rev 47599 : imported patch Interpreter-Poll-Ret-11


2067   if (!is_wide) {
2068     __ sarl(rdx, 16);
2069   }
2070   LP64_ONLY(__ movl2ptr(rdx, rdx));
2071 
2072   // Handle all the JSR stuff here, then exit.
2073   // It's much shorter and cleaner than intermingling with the non-JSR
2074   // normal-branch stuff occurring below.
2075   if (is_jsr) {
2076     // Pre-load the next target bytecode into rbx
2077     __ load_unsigned_byte(rbx, Address(rbcp, rdx, Address::times_1, 0));
2078 
2079     // compute return address as bci in rax
2080     __ lea(rax, at_bcp((is_wide ? 5 : 3) -
2081                         in_bytes(ConstMethod::codes_offset())));
2082     __ subptr(rax, Address(rcx, Method::const_offset()));
2083     // Adjust the bcp in r13 by the displacement in rdx
2084     __ addptr(rbcp, rdx);
2085     // jsr returns atos that is not an oop
2086     __ push_i(rax);
2087     __ dispatch_only(vtos);
2088     return;
2089   }
2090 
2091   // Normal (non-jsr) branch handling
2092 
2093   // Adjust the bcp in r13 by the displacement in rdx
2094   __ addptr(rbcp, rdx);
2095 
2096   assert(UseLoopCounter || !UseOnStackReplacement,
2097          "on-stack-replacement requires loop counters");
2098   Label backedge_counter_overflow;
2099   Label profile_method;
2100   Label dispatch;
2101   if (UseLoopCounter) {
2102     // increment backedge counter for backward branches
2103     // rax: MDO
2104     // rbx: MDO bumped taken-count
2105     // rcx: method
2106     // rdx: target offset
2107     // r13: target bcp


2186       } else {
2187         if (UseOnStackReplacement) {
2188           // check for overflow against rax, which is the sum of the
2189           // counters
2190           __ cmp32(rax, Address(rcx, in_bytes(MethodCounters::interpreter_backward_branch_limit_offset())));
2191           __ jcc(Assembler::aboveEqual, backedge_counter_overflow);
2192 
2193         }
2194       }
2195     }
2196     __ bind(dispatch);
2197   }
2198 
2199   // Pre-load the next target bytecode into rbx
2200   __ load_unsigned_byte(rbx, Address(rbcp, 0));
2201 
2202   // continue with the bytecode @ target
2203   // rax: return bci for jsr's, unused otherwise
2204   // rbx: target bytecode
2205   // r13: target bcp
2206   __ dispatch_only(vtos);
2207 
2208   if (UseLoopCounter) {
2209     if (ProfileInterpreter) {
2210       // Out-of-line code to allocate method data oop.
2211       __ bind(profile_method);
2212       __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method));
2213       __ set_method_data_pointer_for_bcp();
2214       __ jmp(dispatch);
2215     }
2216 
2217     if (UseOnStackReplacement) {
2218       // invocation counter overflow
2219       __ bind(backedge_counter_overflow);
2220       __ negptr(rdx);
2221       __ addptr(rdx, rbcp); // branch bcp
2222       // IcoResult frequency_counter_overflow([JavaThread*], address branch_bcp)
2223       __ call_VM(noreg,
2224                  CAST_FROM_FN_PTR(address,
2225                                   InterpreterRuntime::frequency_counter_overflow),
2226                  rdx);


2315   // assume branch is more often taken than not (loops use backward branches)
2316   Label not_taken;
2317   __ pop_ptr(rdx);
2318   __ cmpoop(rdx, rax);
2319   __ jcc(j_not(cc), not_taken);
2320   branch(false, false);
2321   __ bind(not_taken);
2322   __ profile_not_taken_branch(rax);
2323 }
2324 
2325 void TemplateTable::ret() {
2326   transition(vtos, vtos);
2327   locals_index(rbx);
2328   LP64_ONLY(__ movslq(rbx, iaddress(rbx))); // get return bci, compute return bcp
2329   NOT_LP64(__ movptr(rbx, iaddress(rbx)));
2330   __ profile_ret(rbx, rcx);
2331   __ get_method(rax);
2332   __ movptr(rbcp, Address(rax, Method::const_offset()));
2333   __ lea(rbcp, Address(rbcp, rbx, Address::times_1,
2334                       ConstMethod::codes_offset()));
2335   __ dispatch_next(vtos);
2336 }
2337 
2338 void TemplateTable::wide_ret() {
2339   transition(vtos, vtos);
2340   locals_index_wide(rbx);
2341   __ movptr(rbx, aaddress(rbx)); // get return bci, compute return bcp
2342   __ profile_ret(rbx, rcx);
2343   __ get_method(rax);
2344   __ movptr(rbcp, Address(rax, Method::const_offset()));
2345   __ lea(rbcp, Address(rbcp, rbx, Address::times_1, ConstMethod::codes_offset()));
2346   __ dispatch_next(vtos);
2347 }
2348 
2349 void TemplateTable::tableswitch() {
2350   Label default_case, continue_execution;
2351   transition(itos, vtos);
2352 
2353   // align r13/rsi
2354   __ lea(rbx, at_bcp(BytesPerInt));
2355   __ andptr(rbx, -BytesPerInt);
2356   // load lo & hi
2357   __ movl(rcx, Address(rbx, BytesPerInt));
2358   __ movl(rdx, Address(rbx, 2 * BytesPerInt));
2359   __ bswapl(rcx);
2360   __ bswapl(rdx);
2361   // check against lo & hi
2362   __ cmpl(rax, rcx);
2363   __ jcc(Assembler::less, default_case);
2364   __ cmpl(rax, rdx);
2365   __ jcc(Assembler::greater, default_case);
2366   // lookup dispatch offset
2367   __ subl(rax, rcx);
2368   __ movl(rdx, Address(rbx, rax, Address::times_4, 3 * BytesPerInt));
2369   __ profile_switch_case(rax, rbx, rcx);
2370   // continue execution
2371   __ bind(continue_execution);
2372   __ bswapl(rdx);
2373   LP64_ONLY(__ movl2ptr(rdx, rdx));
2374   __ load_unsigned_byte(rbx, Address(rbcp, rdx, Address::times_1));
2375   __ addptr(rbcp, rdx);
2376   __ dispatch_only(vtos);
2377   // handle default
2378   __ bind(default_case);
2379   __ profile_switch_default(rax);
2380   __ movl(rdx, Address(rbx, 0));
2381   __ jmp(continue_execution);
2382 }
2383 
2384 void TemplateTable::lookupswitch() {
2385   transition(itos, itos);
2386   __ stop("lookupswitch bytecode should have been rewritten");
2387 }
2388 
2389 void TemplateTable::fast_linearswitch() {
2390   transition(itos, vtos);
2391   Label loop_entry, loop, found, continue_execution;
2392   // bswap rax so we can avoid bswapping the table entries
2393   __ bswapl(rax);
2394   // align r13
2395   __ lea(rbx, at_bcp(BytesPerInt)); // btw: should be able to get rid of
2396                                     // this instruction (change offsets


2404   __ bind(loop);
2405   __ cmpl(rax, Address(rbx, rcx, Address::times_8, 2 * BytesPerInt));
2406   __ jcc(Assembler::equal, found);
2407   __ bind(loop_entry);
2408   __ decrementl(rcx);
2409   __ jcc(Assembler::greaterEqual, loop);
2410   // default case
2411   __ profile_switch_default(rax);
2412   __ movl(rdx, Address(rbx, 0));
2413   __ jmp(continue_execution);
2414   // entry found -> get offset
2415   __ bind(found);
2416   __ movl(rdx, Address(rbx, rcx, Address::times_8, 3 * BytesPerInt));
2417   __ profile_switch_case(rcx, rax, rbx);
2418   // continue execution
2419   __ bind(continue_execution);
2420   __ bswapl(rdx);
2421   __ movl2ptr(rdx, rdx);
2422   __ load_unsigned_byte(rbx, Address(rbcp, rdx, Address::times_1));
2423   __ addptr(rbcp, rdx);
2424   __ dispatch_only(vtos);
2425 }
2426 
2427 void TemplateTable::fast_binaryswitch() {
2428   transition(itos, vtos);
2429   // Implementation using the following core algorithm:
2430   //
2431   // int binary_search(int key, LookupswitchPair* array, int n) {
2432   //   // Binary search according to "Methodik des Programmierens" by
2433   //   // Edsger W. Dijkstra and W.H.J. Feijen, Addison Wesley Germany 1985.
2434   //   int i = 0;
2435   //   int j = n;
2436   //   while (i+1 < j) {
2437   //     // invariant P: 0 <= i < j <= n and (a[i] <= key < a[j] or Q)
2438   //     // with      Q: for all i: 0 <= i < n: key < a[i]
2439   //     // where a stands for the array and assuming that the (inexisting)
2440   //     // element a[n] is infinitely big.
2441   //     int h = (i + j) >> 1;
2442   //     // i < h < j
2443   //     if (key < array[h].fast_match()) {
2444   //       j = h;


2508 
2509   // end of binary search, result index is i (must check again!)
2510   Label default_case;
2511   // Convert array[i].match to native byte-ordering before compare
2512   __ movl(temp, Address(array, i, Address::times_8));
2513   __ bswapl(temp);
2514   __ cmpl(key, temp);
2515   __ jcc(Assembler::notEqual, default_case);
2516 
2517   // entry found -> j = offset
2518   __ movl(j , Address(array, i, Address::times_8, BytesPerInt));
2519   __ profile_switch_case(i, key, array);
2520   __ bswapl(j);
2521   LP64_ONLY(__ movslq(j, j));
2522 
2523   NOT_LP64(__ restore_bcp());
2524   NOT_LP64(__ restore_locals());                           // restore rdi
2525 
2526   __ load_unsigned_byte(rbx, Address(rbcp, j, Address::times_1));
2527   __ addptr(rbcp, j);
2528   __ dispatch_only(vtos);
2529 
2530   // default case -> j = default offset
2531   __ bind(default_case);
2532   __ profile_switch_default(i);
2533   __ movl(j, Address(array, -2 * BytesPerInt));
2534   __ bswapl(j);
2535   LP64_ONLY(__ movslq(j, j));
2536 
2537   NOT_LP64(__ restore_bcp());
2538   NOT_LP64(__ restore_locals());
2539 
2540   __ load_unsigned_byte(rbx, Address(rbcp, j, Address::times_1));
2541   __ addptr(rbcp, j);
2542   __ dispatch_only(vtos);
2543 }
2544 
2545 void TemplateTable::_return(TosState state) {
2546   transition(state, state);














2547 
2548   assert(_desc->calls_vm(),
2549          "inconsistent calls_vm information"); // call in remove_activation
2550 
2551   if (_desc->bytecode() == Bytecodes::_return_register_finalizer) {
2552     assert(state == vtos, "only valid state");
2553     Register robj = LP64_ONLY(c_rarg1) NOT_LP64(rax);
2554     __ movptr(robj, aaddress(0));
2555     __ load_klass(rdi, robj);
2556     __ movl(rdi, Address(rdi, Klass::access_flags_offset()));
2557     __ testl(rdi, JVM_ACC_HAS_FINALIZER);
2558     Label skip_register_finalizer;
2559     __ jcc(Assembler::zero, skip_register_finalizer);
2560 
2561     __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::register_finalizer), robj);
2562 
2563     __ bind(skip_register_finalizer);
2564   }
2565 
2566   // Explicitly reset last_sp, for handling special case in TemplateInterpreter::deopt_reexecute_entry




2067   if (!is_wide) {
2068     __ sarl(rdx, 16);
2069   }
2070   LP64_ONLY(__ movl2ptr(rdx, rdx));
2071 
2072   // Handle all the JSR stuff here, then exit.
2073   // It's much shorter and cleaner than intermingling with the non-JSR
2074   // normal-branch stuff occurring below.
2075   if (is_jsr) {
2076     // Pre-load the next target bytecode into rbx
2077     __ load_unsigned_byte(rbx, Address(rbcp, rdx, Address::times_1, 0));
2078 
2079     // compute return address as bci in rax
2080     __ lea(rax, at_bcp((is_wide ? 5 : 3) -
2081                         in_bytes(ConstMethod::codes_offset())));
2082     __ subptr(rax, Address(rcx, Method::const_offset()));
2083     // Adjust the bcp in r13 by the displacement in rdx
2084     __ addptr(rbcp, rdx);
2085     // jsr returns atos that is not an oop
2086     __ push_i(rax);
2087     __ dispatch_only(vtos, true);
2088     return;
2089   }
2090 
2091   // Normal (non-jsr) branch handling
2092 
2093   // Adjust the bcp in r13 by the displacement in rdx
2094   __ addptr(rbcp, rdx);
2095 
2096   assert(UseLoopCounter || !UseOnStackReplacement,
2097          "on-stack-replacement requires loop counters");
2098   Label backedge_counter_overflow;
2099   Label profile_method;
2100   Label dispatch;
2101   if (UseLoopCounter) {
2102     // increment backedge counter for backward branches
2103     // rax: MDO
2104     // rbx: MDO bumped taken-count
2105     // rcx: method
2106     // rdx: target offset
2107     // r13: target bcp


2186       } else {
2187         if (UseOnStackReplacement) {
2188           // check for overflow against rax, which is the sum of the
2189           // counters
2190           __ cmp32(rax, Address(rcx, in_bytes(MethodCounters::interpreter_backward_branch_limit_offset())));
2191           __ jcc(Assembler::aboveEqual, backedge_counter_overflow);
2192 
2193         }
2194       }
2195     }
2196     __ bind(dispatch);
2197   }
2198 
2199   // Pre-load the next target bytecode into rbx
2200   __ load_unsigned_byte(rbx, Address(rbcp, 0));
2201 
2202   // continue with the bytecode @ target
2203   // rax: return bci for jsr's, unused otherwise
2204   // rbx: target bytecode
2205   // r13: target bcp
2206   __ dispatch_only(vtos, true);
2207 
2208   if (UseLoopCounter) {
2209     if (ProfileInterpreter) {
2210       // Out-of-line code to allocate method data oop.
2211       __ bind(profile_method);
2212       __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method));
2213       __ set_method_data_pointer_for_bcp();
2214       __ jmp(dispatch);
2215     }
2216 
2217     if (UseOnStackReplacement) {
2218       // invocation counter overflow
2219       __ bind(backedge_counter_overflow);
2220       __ negptr(rdx);
2221       __ addptr(rdx, rbcp); // branch bcp
2222       // IcoResult frequency_counter_overflow([JavaThread*], address branch_bcp)
2223       __ call_VM(noreg,
2224                  CAST_FROM_FN_PTR(address,
2225                                   InterpreterRuntime::frequency_counter_overflow),
2226                  rdx);


2315   // assume branch is more often taken than not (loops use backward branches)
2316   Label not_taken;
2317   __ pop_ptr(rdx);
2318   __ cmpoop(rdx, rax);
2319   __ jcc(j_not(cc), not_taken);
2320   branch(false, false);
2321   __ bind(not_taken);
2322   __ profile_not_taken_branch(rax);
2323 }
2324 
2325 void TemplateTable::ret() {
2326   transition(vtos, vtos);
2327   locals_index(rbx);
2328   LP64_ONLY(__ movslq(rbx, iaddress(rbx))); // get return bci, compute return bcp
2329   NOT_LP64(__ movptr(rbx, iaddress(rbx)));
2330   __ profile_ret(rbx, rcx);
2331   __ get_method(rax);
2332   __ movptr(rbcp, Address(rax, Method::const_offset()));
2333   __ lea(rbcp, Address(rbcp, rbx, Address::times_1,
2334                       ConstMethod::codes_offset()));
2335   __ dispatch_next(vtos, 0, true);
2336 }
2337 
2338 void TemplateTable::wide_ret() {
2339   transition(vtos, vtos);
2340   locals_index_wide(rbx);
2341   __ movptr(rbx, aaddress(rbx)); // get return bci, compute return bcp
2342   __ profile_ret(rbx, rcx);
2343   __ get_method(rax);
2344   __ movptr(rbcp, Address(rax, Method::const_offset()));
2345   __ lea(rbcp, Address(rbcp, rbx, Address::times_1, ConstMethod::codes_offset()));
2346   __ dispatch_next(vtos, 0, true);
2347 }
2348 
2349 void TemplateTable::tableswitch() {
2350   Label default_case, continue_execution;
2351   transition(itos, vtos);
2352 
2353   // align r13/rsi
2354   __ lea(rbx, at_bcp(BytesPerInt));
2355   __ andptr(rbx, -BytesPerInt);
2356   // load lo & hi
2357   __ movl(rcx, Address(rbx, BytesPerInt));
2358   __ movl(rdx, Address(rbx, 2 * BytesPerInt));
2359   __ bswapl(rcx);
2360   __ bswapl(rdx);
2361   // check against lo & hi
2362   __ cmpl(rax, rcx);
2363   __ jcc(Assembler::less, default_case);
2364   __ cmpl(rax, rdx);
2365   __ jcc(Assembler::greater, default_case);
2366   // lookup dispatch offset
2367   __ subl(rax, rcx);
2368   __ movl(rdx, Address(rbx, rax, Address::times_4, 3 * BytesPerInt));
2369   __ profile_switch_case(rax, rbx, rcx);
2370   // continue execution
2371   __ bind(continue_execution);
2372   __ bswapl(rdx);
2373   LP64_ONLY(__ movl2ptr(rdx, rdx));
2374   __ load_unsigned_byte(rbx, Address(rbcp, rdx, Address::times_1));
2375   __ addptr(rbcp, rdx);
2376   __ dispatch_only(vtos, true);
2377   // handle default
2378   __ bind(default_case);
2379   __ profile_switch_default(rax);
2380   __ movl(rdx, Address(rbx, 0));
2381   __ jmp(continue_execution);
2382 }
2383 
2384 void TemplateTable::lookupswitch() {
2385   transition(itos, itos);
2386   __ stop("lookupswitch bytecode should have been rewritten");
2387 }
2388 
2389 void TemplateTable::fast_linearswitch() {
2390   transition(itos, vtos);
2391   Label loop_entry, loop, found, continue_execution;
2392   // bswap rax so we can avoid bswapping the table entries
2393   __ bswapl(rax);
2394   // align r13
2395   __ lea(rbx, at_bcp(BytesPerInt)); // btw: should be able to get rid of
2396                                     // this instruction (change offsets


2404   __ bind(loop);
2405   __ cmpl(rax, Address(rbx, rcx, Address::times_8, 2 * BytesPerInt));
2406   __ jcc(Assembler::equal, found);
2407   __ bind(loop_entry);
2408   __ decrementl(rcx);
2409   __ jcc(Assembler::greaterEqual, loop);
2410   // default case
2411   __ profile_switch_default(rax);
2412   __ movl(rdx, Address(rbx, 0));
2413   __ jmp(continue_execution);
2414   // entry found -> get offset
2415   __ bind(found);
2416   __ movl(rdx, Address(rbx, rcx, Address::times_8, 3 * BytesPerInt));
2417   __ profile_switch_case(rcx, rax, rbx);
2418   // continue execution
2419   __ bind(continue_execution);
2420   __ bswapl(rdx);
2421   __ movl2ptr(rdx, rdx);
2422   __ load_unsigned_byte(rbx, Address(rbcp, rdx, Address::times_1));
2423   __ addptr(rbcp, rdx);
2424   __ dispatch_only(vtos, true);
2425 }
2426 
2427 void TemplateTable::fast_binaryswitch() {
2428   transition(itos, vtos);
2429   // Implementation using the following core algorithm:
2430   //
2431   // int binary_search(int key, LookupswitchPair* array, int n) {
2432   //   // Binary search according to "Methodik des Programmierens" by
2433   //   // Edsger W. Dijkstra and W.H.J. Feijen, Addison Wesley Germany 1985.
2434   //   int i = 0;
2435   //   int j = n;
2436   //   while (i+1 < j) {
2437   //     // invariant P: 0 <= i < j <= n and (a[i] <= key < a[j] or Q)
2438   //     // with      Q: for all i: 0 <= i < n: key < a[i]
2439   //     // where a stands for the array and assuming that the (inexisting)
2440   //     // element a[n] is infinitely big.
2441   //     int h = (i + j) >> 1;
2442   //     // i < h < j
2443   //     if (key < array[h].fast_match()) {
2444   //       j = h;


2508 
2509   // end of binary search, result index is i (must check again!)
2510   Label default_case;
2511   // Convert array[i].match to native byte-ordering before compare
2512   __ movl(temp, Address(array, i, Address::times_8));
2513   __ bswapl(temp);
2514   __ cmpl(key, temp);
2515   __ jcc(Assembler::notEqual, default_case);
2516 
2517   // entry found -> j = offset
2518   __ movl(j , Address(array, i, Address::times_8, BytesPerInt));
2519   __ profile_switch_case(i, key, array);
2520   __ bswapl(j);
2521   LP64_ONLY(__ movslq(j, j));
2522 
2523   NOT_LP64(__ restore_bcp());
2524   NOT_LP64(__ restore_locals());                           // restore rdi
2525 
2526   __ load_unsigned_byte(rbx, Address(rbcp, j, Address::times_1));
2527   __ addptr(rbcp, j);
2528   __ dispatch_only(vtos, true);
2529 
2530   // default case -> j = default offset
2531   __ bind(default_case);
2532   __ profile_switch_default(i);
2533   __ movl(j, Address(array, -2 * BytesPerInt));
2534   __ bswapl(j);
2535   LP64_ONLY(__ movslq(j, j));
2536 
2537   NOT_LP64(__ restore_bcp());
2538   NOT_LP64(__ restore_locals());
2539 
2540   __ load_unsigned_byte(rbx, Address(rbcp, j, Address::times_1));
2541   __ addptr(rbcp, j);
2542   __ dispatch_only(vtos, true);
2543 }
2544 
2545 void TemplateTable::_return(TosState state) {
2546   transition(state, state);
2547 
2548 #ifdef _LP64
2549   if (SafepointMechanism::uses_thread_local_poll()) {
2550     Label no_safepoint;
2551     NOT_PRODUCT(__ block_comment("Thread-local Safepoint poll"));
2552     __ testb(Address(r15_thread, Thread::polling_page_offset()), SafepointMechanism::poll_bit());
2553     __ jcc(Assembler::zero, no_safepoint);
2554     __ push(state);
2555     __ call_VM(noreg, CAST_FROM_FN_PTR(address,
2556                                     InterpreterRuntime::at_safepoint));
2557     __ pop(state);
2558     __ bind(no_safepoint);
2559   }
2560 #endif
2561 
2562   assert(_desc->calls_vm(),
2563          "inconsistent calls_vm information"); // call in remove_activation
2564 
2565   if (_desc->bytecode() == Bytecodes::_return_register_finalizer) {
2566     assert(state == vtos, "only valid state");
2567     Register robj = LP64_ONLY(c_rarg1) NOT_LP64(rax);
2568     __ movptr(robj, aaddress(0));
2569     __ load_klass(rdi, robj);
2570     __ movl(rdi, Address(rdi, Klass::access_flags_offset()));
2571     __ testl(rdi, JVM_ACC_HAS_FINALIZER);
2572     Label skip_register_finalizer;
2573     __ jcc(Assembler::zero, skip_register_finalizer);
2574 
2575     __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::register_finalizer), robj);
2576 
2577     __ bind(skip_register_finalizer);
2578   }
2579 
2580   // Explicitly reset last_sp, for handling special case in TemplateInterpreter::deopt_reexecute_entry


< prev index next >