Mercurial > hg > truffle
comparison src/cpu/x86/vm/templateInterpreter_x86_32.cpp @ 1783:d5d065957597
6953144: Tiered compilation
Summary: Infrastructure for tiered compilation support (interpreter + c1 + c2) for 32 and 64 bit. Simple tiered policy implementation.
Reviewed-by: kvn, never, phh, twisti
author | iveresov |
---|---|
date | Fri, 03 Sep 2010 17:51:07 -0700 |
parents | e9ff18c4ace7 |
children | f95d63e2154a |
comparison
equal
deleted
inserted
replaced
1782:f353275af40e | 1783:d5d065957597 |
---|---|
357 // | 357 // |
358 // rbx,: method | 358 // rbx,: method |
359 // rcx: invocation counter | 359 // rcx: invocation counter |
360 // | 360 // |
361 void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) { | 361 void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) { |
362 | 362 const Address invocation_counter(rbx, in_bytes(methodOopDesc::invocation_counter_offset()) + |
363 const Address invocation_counter(rbx, methodOopDesc::invocation_counter_offset() + InvocationCounter::counter_offset()); | 363 in_bytes(InvocationCounter::counter_offset())); |
364 const Address backedge_counter (rbx, methodOopDesc::backedge_counter_offset() + InvocationCounter::counter_offset()); | 364 // Note: In tiered we increment either counters in methodOop or in MDO depending if we're profiling or not. |
365 | 365 if (TieredCompilation) { |
366 if (ProfileInterpreter) { // %%% Merge this into methodDataOop | 366 int increment = InvocationCounter::count_increment; |
367 __ incrementl(Address(rbx,methodOopDesc::interpreter_invocation_counter_offset())); | 367 int mask = ((1 << Tier0InvokeNotifyFreqLog) - 1) << InvocationCounter::count_shift; |
368 } | 368 Label no_mdo, done; |
369 // Update standard invocation counters | 369 if (ProfileInterpreter) { |
370 __ movl(rax, backedge_counter); // load backedge counter | 370 // Are we profiling? |
371 | 371 __ movptr(rax, Address(rbx, methodOopDesc::method_data_offset())); |
372 __ incrementl(rcx, InvocationCounter::count_increment); | 372 __ testptr(rax, rax); |
373 __ andl(rax, InvocationCounter::count_mask_value); // mask out the status bits | 373 __ jccb(Assembler::zero, no_mdo); |
374 | 374 // Increment counter in the MDO |
375 __ movl(invocation_counter, rcx); // save invocation count | 375 const Address mdo_invocation_counter(rax, in_bytes(methodDataOopDesc::invocation_counter_offset()) + |
376 __ addl(rcx, rax); // add both counters | 376 in_bytes(InvocationCounter::counter_offset())); |
377 | 377 __ increment_mask_and_jump(mdo_invocation_counter, increment, mask, rcx, false, Assembler::zero, overflow); |
378 // profile_method is non-null only for interpreted method so | 378 __ jmpb(done); |
379 // profile_method != NULL == !native_call | 379 } |
380 // BytecodeInterpreter only calls for native so code is elided. | 380 __ bind(no_mdo); |
381 | 381 // Increment counter in methodOop (we don't need to load it, it's in rcx). |
382 if (ProfileInterpreter && profile_method != NULL) { | 382 __ increment_mask_and_jump(invocation_counter, increment, mask, rcx, true, Assembler::zero, overflow); |
383 // Test to see if we should create a method data oop | 383 __ bind(done); |
384 } else { | |
385 const Address backedge_counter (rbx, methodOopDesc::backedge_counter_offset() + | |
386 InvocationCounter::counter_offset()); | |
387 | |
388 if (ProfileInterpreter) { // %%% Merge this into methodDataOop | |
389 __ incrementl(Address(rbx,methodOopDesc::interpreter_invocation_counter_offset())); | |
390 } | |
391 // Update standard invocation counters | |
392 __ movl(rax, backedge_counter); // load backedge counter | |
393 | |
394 __ incrementl(rcx, InvocationCounter::count_increment); | |
395 __ andl(rax, InvocationCounter::count_mask_value); // mask out the status bits | |
396 | |
397 __ movl(invocation_counter, rcx); // save invocation count | |
398 __ addl(rcx, rax); // add both counters | |
399 | |
400 // profile_method is non-null only for interpreted method so | |
401 // profile_method != NULL == !native_call | |
402 // BytecodeInterpreter only calls for native so code is elided. | |
403 | |
404 if (ProfileInterpreter && profile_method != NULL) { | |
405 // Test to see if we should create a method data oop | |
406 __ cmp32(rcx, | |
407 ExternalAddress((address)&InvocationCounter::InterpreterProfileLimit)); | |
408 __ jcc(Assembler::less, *profile_method_continue); | |
409 | |
410 // if no method data exists, go to profile_method | |
411 __ test_method_data_pointer(rax, *profile_method); | |
412 } | |
413 | |
384 __ cmp32(rcx, | 414 __ cmp32(rcx, |
385 ExternalAddress((address)&InvocationCounter::InterpreterProfileLimit)); | 415 ExternalAddress((address)&InvocationCounter::InterpreterInvocationLimit)); |
386 __ jcc(Assembler::less, *profile_method_continue); | 416 __ jcc(Assembler::aboveEqual, *overflow); |
387 | 417 } |
388 // if no method data exists, go to profile_method | |
389 __ test_method_data_pointer(rax, *profile_method); | |
390 } | |
391 | |
392 __ cmp32(rcx, | |
393 ExternalAddress((address)&InvocationCounter::InterpreterInvocationLimit)); | |
394 __ jcc(Assembler::aboveEqual, *overflow); | |
395 | |
396 } | 418 } |
397 | 419 |
398 void InterpreterGenerator::generate_counter_overflow(Label* do_continue) { | 420 void InterpreterGenerator::generate_counter_overflow(Label* do_continue) { |
399 | 421 |
400 // Asm interpreter on entry | 422 // Asm interpreter on entry |