Mercurial > hg > truffle
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 |