comparison src/cpu/x86/vm/templateInterpreter_x86_32.cpp @ 10408:836a62f43af9

Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/
author Doug Simon <doug.simon@oracle.com>
date Wed, 19 Jun 2013 10:45:56 +0200
parents 603ca7e51354
children b800986664f4
comparison
equal deleted inserted replaced
10086:e0fb8a213650 10408:836a62f43af9
1 /* 1 /*
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
342 // 342 //
343 // rbx,: method 343 // rbx,: method
344 // rcx: invocation counter 344 // rcx: invocation counter
345 // 345 //
346 void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) { 346 void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) {
347 const Address invocation_counter(rbx, in_bytes(Method::invocation_counter_offset()) + 347 Label done;
348 in_bytes(InvocationCounter::counter_offset())); 348 // Note: In tiered we increment either counters in MethodCounters* or in MDO
349 // Note: In tiered we increment either counters in Method* or in MDO depending if we're profiling or not. 349 // depending if we're profiling or not.
350 if (TieredCompilation) { 350 if (TieredCompilation) {
351 int increment = InvocationCounter::count_increment; 351 int increment = InvocationCounter::count_increment;
352 int mask = ((1 << Tier0InvokeNotifyFreqLog) - 1) << InvocationCounter::count_shift; 352 int mask = ((1 << Tier0InvokeNotifyFreqLog) - 1) << InvocationCounter::count_shift;
353 Label no_mdo, done; 353 Label no_mdo;
354 if (ProfileInterpreter) { 354 if (ProfileInterpreter) {
355 // Are we profiling? 355 // Are we profiling?
356 __ movptr(rax, Address(rbx, Method::method_data_offset())); 356 __ movptr(rax, Address(rbx, Method::method_data_offset()));
357 __ testptr(rax, rax); 357 __ testptr(rax, rax);
358 __ jccb(Assembler::zero, no_mdo); 358 __ jccb(Assembler::zero, no_mdo);
359 // Increment counter in the MDO 359 // Increment counter in the MDO
360 const Address mdo_invocation_counter(rax, in_bytes(MethodData::invocation_counter_offset()) + 360 const Address mdo_invocation_counter(rax, in_bytes(MethodData::invocation_counter_offset()) +
361 in_bytes(InvocationCounter::counter_offset())); 361 in_bytes(InvocationCounter::counter_offset()));
362 __ increment_mask_and_jump(mdo_invocation_counter, increment, mask, rcx, false, Assembler::zero, overflow); 362 __ increment_mask_and_jump(mdo_invocation_counter, increment, mask, rcx, false, Assembler::zero, overflow);
363 __ jmpb(done); 363 __ jmp(done);
364 } 364 }
365 __ bind(no_mdo); 365 __ bind(no_mdo);
366 // Increment counter in Method* (we don't need to load it, it's in rcx). 366 // Increment counter in MethodCounters
367 __ increment_mask_and_jump(invocation_counter, increment, mask, rcx, true, Assembler::zero, overflow); 367 const Address invocation_counter(rax,
368 MethodCounters::invocation_counter_offset() +
369 InvocationCounter::counter_offset());
370
371 __ get_method_counters(rbx, rax, done);
372 __ increment_mask_and_jump(invocation_counter, increment, mask,
373 rcx, false, Assembler::zero, overflow);
368 __ bind(done); 374 __ bind(done);
369 } else { 375 } else {
370 const Address backedge_counter (rbx, Method::backedge_counter_offset() + 376 const Address backedge_counter (rax,
371 InvocationCounter::counter_offset()); 377 MethodCounters::backedge_counter_offset() +
372 378 InvocationCounter::counter_offset());
373 if (ProfileInterpreter) { // %%% Merge this into MethodData* 379 const Address invocation_counter(rax,
374 __ incrementl(Address(rbx,Method::interpreter_invocation_counter_offset())); 380 MethodCounters::invocation_counter_offset() +
381 InvocationCounter::counter_offset());
382
383 __ get_method_counters(rbx, rax, done);
384
385 if (ProfileInterpreter) {
386 __ incrementl(Address(rax,
387 MethodCounters::interpreter_invocation_counter_offset()));
375 } 388 }
389
376 // Update standard invocation counters 390 // Update standard invocation counters
391 __ movl(rcx, invocation_counter);
392 __ incrementl(rcx, InvocationCounter::count_increment);
393 __ movl(invocation_counter, rcx); // save invocation count
394
377 __ movl(rax, backedge_counter); // load backedge counter 395 __ movl(rax, backedge_counter); // load backedge counter
378
379 __ incrementl(rcx, InvocationCounter::count_increment);
380 __ andl(rax, InvocationCounter::count_mask_value); // mask out the status bits 396 __ andl(rax, InvocationCounter::count_mask_value); // mask out the status bits
381 397
382 __ movl(invocation_counter, rcx); // save invocation count
383 __ addl(rcx, rax); // add both counters 398 __ addl(rcx, rax); // add both counters
384 399
385 // profile_method is non-null only for interpreted method so 400 // profile_method is non-null only for interpreted method so
386 // profile_method != NULL == !native_call 401 // profile_method != NULL == !native_call
387 // BytecodeInterpreter only calls for native so code is elided. 402 // BytecodeInterpreter only calls for native so code is elided.
397 } 412 }
398 413
399 __ cmp32(rcx, 414 __ cmp32(rcx,
400 ExternalAddress((address)&InvocationCounter::InterpreterInvocationLimit)); 415 ExternalAddress((address)&InvocationCounter::InterpreterInvocationLimit));
401 __ jcc(Assembler::aboveEqual, *overflow); 416 __ jcc(Assembler::aboveEqual, *overflow);
417 __ bind(done);
402 } 418 }
403 } 419 }
404 420
405 void InterpreterGenerator::generate_counter_overflow(Label* do_continue) { 421 void InterpreterGenerator::generate_counter_overflow(Label* do_continue) {
406 422
866 // rsi: sender sp 882 // rsi: sender sp
867 // rsi: previous interpreter state (C++ interpreter) must preserve 883 // rsi: previous interpreter state (C++ interpreter) must preserve
868 address entry_point = __ pc(); 884 address entry_point = __ pc();
869 885
870 const Address constMethod (rbx, Method::const_offset()); 886 const Address constMethod (rbx, Method::const_offset());
871 const Address invocation_counter(rbx, Method::invocation_counter_offset() + InvocationCounter::counter_offset());
872 const Address access_flags (rbx, Method::access_flags_offset()); 887 const Address access_flags (rbx, Method::access_flags_offset());
873 const Address size_of_parameters(rcx, ConstMethod::size_of_parameters_offset()); 888 const Address size_of_parameters(rcx, ConstMethod::size_of_parameters_offset());
874 889
875 // get parameter size (always needed) 890 // get parameter size (always needed)
876 __ movptr(rcx, constMethod); 891 __ movptr(rcx, constMethod);
895 // NULL result handler 910 // NULL result handler
896 __ push((int32_t)NULL_WORD); 911 __ push((int32_t)NULL_WORD);
897 // NULL oop temp (mirror or jni oop result) 912 // NULL oop temp (mirror or jni oop result)
898 __ push((int32_t)NULL_WORD); 913 __ push((int32_t)NULL_WORD);
899 914
900 if (inc_counter) __ movl(rcx, invocation_counter); // (pre-)fetch invocation count
901 // initialize fixed part of activation frame 915 // initialize fixed part of activation frame
902
903 generate_fixed_frame(true); 916 generate_fixed_frame(true);
904 917
905 // make sure method is native & not abstract 918 // make sure method is native & not abstract
906 #ifdef ASSERT 919 #ifdef ASSERT
907 __ movl(rax, access_flags); 920 __ movl(rax, access_flags);
1284 // rbx,: Method* 1297 // rbx,: Method*
1285 // rsi: sender sp 1298 // rsi: sender sp
1286 address entry_point = __ pc(); 1299 address entry_point = __ pc();
1287 1300
1288 const Address constMethod (rbx, Method::const_offset()); 1301 const Address constMethod (rbx, Method::const_offset());
1289 const Address invocation_counter(rbx, Method::invocation_counter_offset() + InvocationCounter::counter_offset());
1290 const Address access_flags (rbx, Method::access_flags_offset()); 1302 const Address access_flags (rbx, Method::access_flags_offset());
1291 const Address size_of_parameters(rdx, ConstMethod::size_of_parameters_offset()); 1303 const Address size_of_parameters(rdx, ConstMethod::size_of_parameters_offset());
1292 const Address size_of_locals (rdx, ConstMethod::size_of_locals_offset()); 1304 const Address size_of_locals (rdx, ConstMethod::size_of_locals_offset());
1293 1305
1294 // get parameter size (always needed) 1306 // get parameter size (always needed)
1324 __ decrement(rdx); // until everything initialized 1336 __ decrement(rdx); // until everything initialized
1325 __ jcc(Assembler::greater, loop); 1337 __ jcc(Assembler::greater, loop);
1326 __ bind(exit); 1338 __ bind(exit);
1327 } 1339 }
1328 1340
1329 if (inc_counter) __ movl(rcx, invocation_counter); // (pre-)fetch invocation count
1330 // initialize fixed part of activation frame 1341 // initialize fixed part of activation frame
1331 generate_fixed_frame(false); 1342 generate_fixed_frame(false);
1332 1343
1333 // make sure method is not native & not abstract 1344 // make sure method is not native & not abstract
1334 #ifdef ASSERT 1345 #ifdef ASSERT
1552 1563
1553 // total overhead size: entry_size + (saved rbp, thru expr stack bottom). 1564 // total overhead size: entry_size + (saved rbp, thru expr stack bottom).
1554 // be sure to change this if you add/subtract anything to/from the overhead area 1565 // be sure to change this if you add/subtract anything to/from the overhead area
1555 const int overhead_size = -frame::interpreter_frame_initial_sp_offset; 1566 const int overhead_size = -frame::interpreter_frame_initial_sp_offset;
1556 1567
1557 const int extra_stack = Method::extra_stack_entries(); 1568 const int method_stack = (method->max_locals() + method->max_stack()) *
1558 const int method_stack = (method->max_locals() + method->max_stack() + extra_stack) *
1559 Interpreter::stackElementWords; 1569 Interpreter::stackElementWords;
1560 return overhead_size + method_stack + stub_code; 1570 return overhead_size + method_stack + stub_code;
1561 } 1571 }
1562 1572
1563 // asm based interpreter deoptimization helpers 1573 // asm based interpreter deoptimization helpers