comparison src/cpu/x86/vm/templateInterpreter_x86_64.cpp @ 10105:aeaca88565e6

8010862: The Method counter fields used for profiling can be allocated lazily. Summary: Allocate the method's profiling related metadata until they are needed. Reviewed-by: coleenp, roland
author jiangli
date Tue, 09 Apr 2013 17:17:41 -0400
parents e961c11b85fe
children 47766e2d2527
comparison
equal deleted inserted replaced
9055:dcdeb150988c 10105:aeaca88565e6
1 /* 1 /*
2 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 2003, 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.
298 // 298 //
299 void InterpreterGenerator::generate_counter_incr( 299 void InterpreterGenerator::generate_counter_incr(
300 Label* overflow, 300 Label* overflow,
301 Label* profile_method, 301 Label* profile_method,
302 Label* profile_method_continue) { 302 Label* profile_method_continue) {
303 const Address invocation_counter(rbx, in_bytes(Method::invocation_counter_offset()) + 303 Label done;
304 in_bytes(InvocationCounter::counter_offset()));
305 // Note: In tiered we increment either counters in Method* or in MDO depending if we're profiling or not. 304 // Note: In tiered we increment either counters in Method* or in MDO depending if we're profiling or not.
306 if (TieredCompilation) { 305 if (TieredCompilation) {
307 int increment = InvocationCounter::count_increment; 306 int increment = InvocationCounter::count_increment;
308 int mask = ((1 << Tier0InvokeNotifyFreqLog) - 1) << InvocationCounter::count_shift; 307 int mask = ((1 << Tier0InvokeNotifyFreqLog) - 1) << InvocationCounter::count_shift;
309 Label no_mdo, done; 308 Label no_mdo;
310 if (ProfileInterpreter) { 309 if (ProfileInterpreter) {
311 // Are we profiling? 310 // Are we profiling?
312 __ movptr(rax, Address(rbx, Method::method_data_offset())); 311 __ movptr(rax, Address(rbx, Method::method_data_offset()));
313 __ testptr(rax, rax); 312 __ testptr(rax, rax);
314 __ jccb(Assembler::zero, no_mdo); 313 __ jccb(Assembler::zero, no_mdo);
317 in_bytes(InvocationCounter::counter_offset())); 316 in_bytes(InvocationCounter::counter_offset()));
318 __ increment_mask_and_jump(mdo_invocation_counter, increment, mask, rcx, false, Assembler::zero, overflow); 317 __ increment_mask_and_jump(mdo_invocation_counter, increment, mask, rcx, false, Assembler::zero, overflow);
319 __ jmpb(done); 318 __ jmpb(done);
320 } 319 }
321 __ bind(no_mdo); 320 __ bind(no_mdo);
322 // Increment counter in Method* (we don't need to load it, it's in ecx). 321 // Increment counter in MethodCounters
323 __ increment_mask_and_jump(invocation_counter, increment, mask, rcx, true, Assembler::zero, overflow); 322 const Address invocation_counter(rax,
323 MethodCounters::invocation_counter_offset() +
324 InvocationCounter::counter_offset());
325 __ get_method_counters(rbx, rax, done);
326 __ increment_mask_and_jump(invocation_counter, increment, mask, rcx,
327 false, Assembler::zero, overflow);
324 __ bind(done); 328 __ bind(done);
325 } else { 329 } else {
326 const Address backedge_counter(rbx, 330 const Address backedge_counter(rax,
327 Method::backedge_counter_offset() + 331 MethodCounters::backedge_counter_offset() +
328 InvocationCounter::counter_offset()); 332 InvocationCounter::counter_offset());
329 333 const Address invocation_counter(rax,
330 if (ProfileInterpreter) { // %%% Merge this into MethodData* 334 MethodCounters::invocation_counter_offset() +
331 __ incrementl(Address(rbx, 335 InvocationCounter::counter_offset());
332 Method::interpreter_invocation_counter_offset())); 336
337 __ get_method_counters(rbx, rax, done);
338
339 if (ProfileInterpreter) {
340 __ incrementl(Address(rax,
341 MethodCounters::interpreter_invocation_counter_offset()));
333 } 342 }
334 // Update standard invocation counters 343 // Update standard invocation counters
344 __ movl(rcx, invocation_counter);
345 __ incrementl(rcx, InvocationCounter::count_increment);
346 __ movl(invocation_counter, rcx); // save invocation count
347
335 __ movl(rax, backedge_counter); // load backedge counter 348 __ movl(rax, backedge_counter); // load backedge counter
336
337 __ incrementl(rcx, InvocationCounter::count_increment);
338 __ andl(rax, InvocationCounter::count_mask_value); // mask out the status bits 349 __ andl(rax, InvocationCounter::count_mask_value); // mask out the status bits
339 350
340 __ movl(invocation_counter, rcx); // save invocation count
341 __ addl(rcx, rax); // add both counters 351 __ addl(rcx, rax); // add both counters
342 352
343 // profile_method is non-null only for interpreted method so 353 // profile_method is non-null only for interpreted method so
344 // profile_method != NULL == !native_call 354 // profile_method != NULL == !native_call
345 355
352 __ test_method_data_pointer(rax, *profile_method); 362 __ test_method_data_pointer(rax, *profile_method);
353 } 363 }
354 364
355 __ cmp32(rcx, ExternalAddress((address)&InvocationCounter::InterpreterInvocationLimit)); 365 __ cmp32(rcx, ExternalAddress((address)&InvocationCounter::InterpreterInvocationLimit));
356 __ jcc(Assembler::aboveEqual, *overflow); 366 __ jcc(Assembler::aboveEqual, *overflow);
367 __ bind(done);
357 } 368 }
358 } 369 }
359 370
360 void InterpreterGenerator::generate_counter_overflow(Label* do_continue) { 371 void InterpreterGenerator::generate_counter_overflow(Label* do_continue) {
361 372
841 // r13: sender sp 852 // r13: sender sp
842 853
843 address entry_point = __ pc(); 854 address entry_point = __ pc();
844 855
845 const Address constMethod (rbx, Method::const_offset()); 856 const Address constMethod (rbx, Method::const_offset());
846 const Address invocation_counter(rbx, Method::
847 invocation_counter_offset() +
848 InvocationCounter::counter_offset());
849 const Address access_flags (rbx, Method::access_flags_offset()); 857 const Address access_flags (rbx, Method::access_flags_offset());
850 const Address size_of_parameters(rcx, ConstMethod:: 858 const Address size_of_parameters(rcx, ConstMethod::
851 size_of_parameters_offset()); 859 size_of_parameters_offset());
852 860
853 861
873 // initialize result_handler slot 881 // initialize result_handler slot
874 __ push((int) NULL_WORD); 882 __ push((int) NULL_WORD);
875 // slot for oop temp 883 // slot for oop temp
876 // (static native method holder mirror/jni oop result) 884 // (static native method holder mirror/jni oop result)
877 __ push((int) NULL_WORD); 885 __ push((int) NULL_WORD);
878
879 if (inc_counter) {
880 __ movl(rcx, invocation_counter); // (pre-)fetch invocation count
881 }
882 886
883 // initialize fixed part of activation frame 887 // initialize fixed part of activation frame
884 generate_fixed_frame(true); 888 generate_fixed_frame(true);
885 889
886 // make sure method is native & not abstract 890 // make sure method is native & not abstract
1294 // ebx: Method* 1298 // ebx: Method*
1295 // r13: sender sp 1299 // r13: sender sp
1296 address entry_point = __ pc(); 1300 address entry_point = __ pc();
1297 1301
1298 const Address constMethod(rbx, Method::const_offset()); 1302 const Address constMethod(rbx, Method::const_offset());
1299 const Address invocation_counter(rbx,
1300 Method::invocation_counter_offset() +
1301 InvocationCounter::counter_offset());
1302 const Address access_flags(rbx, Method::access_flags_offset()); 1303 const Address access_flags(rbx, Method::access_flags_offset());
1303 const Address size_of_parameters(rdx, 1304 const Address size_of_parameters(rdx,
1304 ConstMethod::size_of_parameters_offset()); 1305 ConstMethod::size_of_parameters_offset());
1305 const Address size_of_locals(rdx, ConstMethod::size_of_locals_offset()); 1306 const Address size_of_locals(rdx, ConstMethod::size_of_locals_offset());
1306 1307
1341 __ decrementl(rdx); // until everything initialized 1342 __ decrementl(rdx); // until everything initialized
1342 __ jcc(Assembler::greater, loop); 1343 __ jcc(Assembler::greater, loop);
1343 __ bind(exit); 1344 __ bind(exit);
1344 } 1345 }
1345 1346
1346 // (pre-)fetch invocation count
1347 if (inc_counter) {
1348 __ movl(rcx, invocation_counter);
1349 }
1350 // initialize fixed part of activation frame 1347 // initialize fixed part of activation frame
1351 generate_fixed_frame(false); 1348 generate_fixed_frame(false);
1352 1349
1353 // make sure method is not native & not abstract 1350 // make sure method is not native & not abstract
1354 #ifdef ASSERT 1351 #ifdef ASSERT