Mercurial > hg > graal-jvmci-8
comparison src/cpu/x86/vm/templateInterpreter_x86_32.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) 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); |
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 __ jmpb(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 |