Mercurial > hg > graal-jvmci-8
comparison src/cpu/x86/vm/templateInterpreter_x86_64.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 | c6a1ffc707ff 603ca7e51354 |
children | 3489047ffea2 |
comparison
equal
deleted
inserted
replaced
10086:e0fb8a213650 | 10408:836a62f43af9 |
---|---|
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. |
302 // | 302 // |
303 | 303 |
304 #ifdef GRAAL | 304 #ifdef GRAAL |
305 | 305 |
306 void graal_initialize_time(JavaThread* thread) { | 306 void graal_initialize_time(JavaThread* thread) { |
307 assert(ProfileInterpreter, "must be profiling interpreter"); | |
307 frame fr = thread->last_frame(); | 308 frame fr = thread->last_frame(); |
308 assert(fr.is_interpreted_frame(), "must come from interpreter"); | 309 assert(fr.is_interpreted_frame(), "must come from interpreter"); |
309 fr.interpreter_frame_method()->set_graal_invocation_time(os::javaTimeNanos()); | 310 assert(fr.interpreter_frame_method()->method_counters() != NULL, "need to initialize method counters"); |
311 fr.interpreter_frame_method()->method_counters()->set_graal_invocation_time(os::javaTimeNanos()); | |
310 } | 312 } |
311 | 313 |
312 #endif // GRAAL | 314 #endif // GRAAL |
313 | 315 |
314 // increment invocation count & check for overflow | 316 // increment invocation count & check for overflow |
321 // | 323 // |
322 void InterpreterGenerator::generate_counter_incr( | 324 void InterpreterGenerator::generate_counter_incr( |
323 Label* overflow, | 325 Label* overflow, |
324 Label* profile_method, | 326 Label* profile_method, |
325 Label* profile_method_continue) { | 327 Label* profile_method_continue) { |
326 const Address invocation_counter(rbx, in_bytes(Method::invocation_counter_offset()) + | 328 Label done; |
327 in_bytes(InvocationCounter::counter_offset())); | |
328 // Note: In tiered we increment either counters in Method* or in MDO depending if we're profiling or not. | 329 // Note: In tiered we increment either counters in Method* or in MDO depending if we're profiling or not. |
329 if (TieredCompilation) { | 330 if (TieredCompilation) { |
330 int increment = InvocationCounter::count_increment; | 331 int increment = InvocationCounter::count_increment; |
331 int mask = ((1 << Tier0InvokeNotifyFreqLog) - 1) << InvocationCounter::count_shift; | 332 int mask = ((1 << Tier0InvokeNotifyFreqLog) - 1) << InvocationCounter::count_shift; |
332 Label no_mdo, done; | 333 Label no_mdo; |
333 if (ProfileInterpreter) { | 334 if (ProfileInterpreter) { |
334 // Are we profiling? | 335 // Are we profiling? |
335 __ movptr(rax, Address(rbx, Method::method_data_offset())); | 336 __ movptr(rax, Address(rbx, Method::method_data_offset())); |
336 __ testptr(rax, rax); | 337 __ testptr(rax, rax); |
337 __ jccb(Assembler::zero, no_mdo); | 338 __ jccb(Assembler::zero, no_mdo); |
338 // Increment counter in the MDO | 339 // Increment counter in the MDO |
339 const Address mdo_invocation_counter(rax, in_bytes(MethodData::invocation_counter_offset()) + | 340 const Address mdo_invocation_counter(rax, in_bytes(MethodData::invocation_counter_offset()) + |
340 in_bytes(InvocationCounter::counter_offset())); | 341 in_bytes(InvocationCounter::counter_offset())); |
341 __ increment_mask_and_jump(mdo_invocation_counter, increment, mask, rcx, false, Assembler::zero, overflow); | 342 __ increment_mask_and_jump(mdo_invocation_counter, increment, mask, rcx, false, Assembler::zero, overflow); |
342 __ jmpb(done); | 343 __ jmp(done); |
343 } | 344 } |
344 __ bind(no_mdo); | 345 __ bind(no_mdo); |
345 // Increment counter in Method* (we don't need to load it, it's in ecx). | 346 // Increment counter in MethodCounters |
346 __ increment_mask_and_jump(invocation_counter, increment, mask, rcx, true, Assembler::zero, overflow); | 347 const Address invocation_counter(rax, |
348 MethodCounters::invocation_counter_offset() + | |
349 InvocationCounter::counter_offset()); | |
350 __ get_method_counters(rbx, rax, done); | |
351 __ increment_mask_and_jump(invocation_counter, increment, mask, rcx, | |
352 false, Assembler::zero, overflow); | |
347 __ bind(done); | 353 __ bind(done); |
348 } else { | 354 } else { |
349 const Address backedge_counter(rbx, | 355 const Address backedge_counter(rax, |
350 Method::backedge_counter_offset() + | 356 MethodCounters::backedge_counter_offset() + |
351 InvocationCounter::counter_offset()); | 357 InvocationCounter::counter_offset()); |
352 | 358 const Address invocation_counter(rax, |
353 if (ProfileInterpreter) { // %%% Merge this into MethodData* | 359 MethodCounters::invocation_counter_offset() + |
354 __ incrementl(Address(rbx, | 360 InvocationCounter::counter_offset()); |
355 Method::interpreter_invocation_counter_offset())); | 361 |
362 __ get_method_counters(rbx, rax, done); | |
363 | |
364 if (ProfileInterpreter) { | |
365 __ incrementl(Address(rax, | |
366 MethodCounters::interpreter_invocation_counter_offset())); | |
356 } | 367 } |
357 | 368 |
358 #ifdef GRAAL | 369 #ifdef GRAAL |
359 if (CompilationPolicyChoice == 4) { | 370 if (CompilationPolicyChoice == 4) { |
360 Label not_zero; | 371 Label not_zero; |
374 __ bind(not_zero); | 385 __ bind(not_zero); |
375 } | 386 } |
376 #endif // GRAAL | 387 #endif // GRAAL |
377 | 388 |
378 // Update standard invocation counters | 389 // Update standard invocation counters |
390 __ movl(rcx, invocation_counter); | |
391 __ incrementl(rcx, InvocationCounter::count_increment); | |
392 __ movl(invocation_counter, rcx); // save invocation count | |
393 | |
379 __ movl(rax, backedge_counter); // load backedge counter | 394 __ movl(rax, backedge_counter); // load backedge counter |
380 | |
381 __ incrementl(rcx, InvocationCounter::count_increment); | |
382 __ andl(rax, InvocationCounter::count_mask_value); // mask out the status bits | 395 __ andl(rax, InvocationCounter::count_mask_value); // mask out the status bits |
383 | 396 |
384 __ movl(invocation_counter, rcx); // save invocation count | |
385 __ addl(rcx, rax); // add both counters | 397 __ addl(rcx, rax); // add both counters |
386 | 398 |
387 // profile_method is non-null only for interpreted method so | 399 // profile_method is non-null only for interpreted method so |
388 // profile_method != NULL == !native_call | 400 // profile_method != NULL == !native_call |
389 | 401 |
396 __ test_method_data_pointer(rax, *profile_method); | 408 __ test_method_data_pointer(rax, *profile_method); |
397 } | 409 } |
398 | 410 |
399 __ cmp32(rcx, ExternalAddress((address)&InvocationCounter::InterpreterInvocationLimit)); | 411 __ cmp32(rcx, ExternalAddress((address)&InvocationCounter::InterpreterInvocationLimit)); |
400 __ jcc(Assembler::aboveEqual, *overflow); | 412 __ jcc(Assembler::aboveEqual, *overflow); |
413 __ bind(done); | |
401 } | 414 } |
402 } | 415 } |
403 | 416 |
404 void InterpreterGenerator::generate_counter_overflow(Label* do_continue) { | 417 void InterpreterGenerator::generate_counter_overflow(Label* do_continue) { |
405 | 418 |
925 // r13: sender sp | 938 // r13: sender sp |
926 | 939 |
927 address entry_point = __ pc(); | 940 address entry_point = __ pc(); |
928 | 941 |
929 const Address constMethod (rbx, Method::const_offset()); | 942 const Address constMethod (rbx, Method::const_offset()); |
930 const Address invocation_counter(rbx, Method:: | |
931 invocation_counter_offset() + | |
932 InvocationCounter::counter_offset()); | |
933 const Address access_flags (rbx, Method::access_flags_offset()); | 943 const Address access_flags (rbx, Method::access_flags_offset()); |
934 const Address size_of_parameters(rcx, ConstMethod:: | 944 const Address size_of_parameters(rcx, ConstMethod:: |
935 size_of_parameters_offset()); | 945 size_of_parameters_offset()); |
936 | 946 |
937 | 947 |
957 // initialize result_handler slot | 967 // initialize result_handler slot |
958 __ push((int) NULL_WORD); | 968 __ push((int) NULL_WORD); |
959 // slot for oop temp | 969 // slot for oop temp |
960 // (static native method holder mirror/jni oop result) | 970 // (static native method holder mirror/jni oop result) |
961 __ push((int) NULL_WORD); | 971 __ push((int) NULL_WORD); |
962 | |
963 if (inc_counter) { | |
964 __ movl(rcx, invocation_counter); // (pre-)fetch invocation count | |
965 } | |
966 | 972 |
967 // initialize fixed part of activation frame | 973 // initialize fixed part of activation frame |
968 generate_fixed_frame(true); | 974 generate_fixed_frame(true); |
969 | 975 |
970 // make sure method is native & not abstract | 976 // make sure method is native & not abstract |
1378 // ebx: Method* | 1384 // ebx: Method* |
1379 // r13: sender sp | 1385 // r13: sender sp |
1380 address entry_point = __ pc(); | 1386 address entry_point = __ pc(); |
1381 | 1387 |
1382 const Address constMethod(rbx, Method::const_offset()); | 1388 const Address constMethod(rbx, Method::const_offset()); |
1383 const Address invocation_counter(rbx, | |
1384 Method::invocation_counter_offset() + | |
1385 InvocationCounter::counter_offset()); | |
1386 const Address access_flags(rbx, Method::access_flags_offset()); | 1389 const Address access_flags(rbx, Method::access_flags_offset()); |
1387 const Address size_of_parameters(rdx, | 1390 const Address size_of_parameters(rdx, |
1388 ConstMethod::size_of_parameters_offset()); | 1391 ConstMethod::size_of_parameters_offset()); |
1389 const Address size_of_locals(rdx, ConstMethod::size_of_locals_offset()); | 1392 const Address size_of_locals(rdx, ConstMethod::size_of_locals_offset()); |
1390 | 1393 |
1425 __ decrementl(rdx); // until everything initialized | 1428 __ decrementl(rdx); // until everything initialized |
1426 __ jcc(Assembler::greater, loop); | 1429 __ jcc(Assembler::greater, loop); |
1427 __ bind(exit); | 1430 __ bind(exit); |
1428 } | 1431 } |
1429 | 1432 |
1430 // (pre-)fetch invocation count | |
1431 if (inc_counter) { | |
1432 __ movl(rcx, invocation_counter); | |
1433 } | |
1434 // initialize fixed part of activation frame | 1433 // initialize fixed part of activation frame |
1435 generate_fixed_frame(false); | 1434 generate_fixed_frame(false); |
1436 | 1435 |
1437 // make sure method is not native & not abstract | 1436 // make sure method is not native & not abstract |
1438 #ifdef ASSERT | 1437 #ifdef ASSERT |
1662 // to/from the overhead area | 1661 // to/from the overhead area |
1663 const int overhead_size = | 1662 const int overhead_size = |
1664 -(frame::interpreter_frame_initial_sp_offset) + entry_size; | 1663 -(frame::interpreter_frame_initial_sp_offset) + entry_size; |
1665 | 1664 |
1666 const int stub_code = frame::entry_frame_after_call_words; | 1665 const int stub_code = frame::entry_frame_after_call_words; |
1667 const int extra_stack = Method::extra_stack_entries(); | 1666 const int method_stack = (method->max_locals() + method->max_stack()) * |
1668 const int method_stack = (method->max_locals() + method->max_stack() + extra_stack) * | |
1669 Interpreter::stackElementWords; | 1667 Interpreter::stackElementWords; |
1670 return (overhead_size + method_stack + stub_code); | 1668 return (overhead_size + method_stack + stub_code); |
1671 } | 1669 } |
1672 | 1670 |
1673 int AbstractInterpreter::layout_activation(Method* method, | 1671 int AbstractInterpreter::layout_activation(Method* method, |