Mercurial > hg > graal-jvmci-8
comparison src/share/vm/jvmci/jvmciCodeInstaller.cpp @ 22773:9273bb6ba33e
Simplify code installation interface: Use CompiledCode class instead of CompilationResult and DataSection.
author | Roland Schatz <roland.schatz@oracle.com> |
---|---|
date | Fri, 15 Jan 2016 16:50:19 +0100 |
parents | f41ed1d87d68 |
children | b4ff1a18d19c |
comparison
equal
deleted
inserted
replaced
22772:f16c1266b0de | 22773:9273bb6ba33e |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2011, 2016, 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. |
388 void CodeInstaller::initialize_dependencies(oop compiled_code, TRAPS) { | 388 void CodeInstaller::initialize_dependencies(oop compiled_code, TRAPS) { |
389 JavaThread* thread = JavaThread::current(); | 389 JavaThread* thread = JavaThread::current(); |
390 CompilerThread* compilerThread = thread->is_Compiler_thread() ? thread->as_CompilerThread() : NULL; | 390 CompilerThread* compilerThread = thread->is_Compiler_thread() ? thread->as_CompilerThread() : NULL; |
391 _oop_recorder = new OopRecorder(&_arena, true); | 391 _oop_recorder = new OopRecorder(&_arena, true); |
392 _dependencies = new Dependencies(&_arena, _oop_recorder, compilerThread != NULL ? compilerThread->log() : NULL); | 392 _dependencies = new Dependencies(&_arena, _oop_recorder, compilerThread != NULL ? compilerThread->log() : NULL); |
393 objArrayHandle assumptions = HotSpotCompiledCode::assumptions(compiled_code); | 393 objArrayHandle assumptions = CompiledCode::assumptions(compiled_code); |
394 if (!assumptions.is_null()) { | 394 if (!assumptions.is_null()) { |
395 int length = assumptions->length(); | 395 int length = assumptions->length(); |
396 for (int i = 0; i < length; ++i) { | 396 for (int i = 0; i < length; ++i) { |
397 Handle assumption = assumptions->obj_at(i); | 397 Handle assumption = assumptions->obj_at(i); |
398 if (!assumption.is_null()) { | 398 if (!assumption.is_null()) { |
411 } | 411 } |
412 } | 412 } |
413 } | 413 } |
414 } | 414 } |
415 if (JvmtiExport::can_hotswap_or_post_breakpoint()) { | 415 if (JvmtiExport::can_hotswap_or_post_breakpoint()) { |
416 objArrayHandle methods = HotSpotCompiledCode::methods(compiled_code); | 416 objArrayHandle methods = CompiledCode::methods(compiled_code); |
417 if (!methods.is_null()) { | 417 if (!methods.is_null()) { |
418 int length = methods->length(); | 418 int length = methods->length(); |
419 for (int i = 0; i < length; ++i) { | 419 for (int i = 0; i < length; ++i) { |
420 Handle method_handle = methods->obj_at(i); | 420 Handle method_handle = methods->obj_at(i); |
421 methodHandle method = getMethodFromHotSpotMethod(method_handle()); | 421 methodHandle method = getMethodFromHotSpotMethod(method_handle()); |
438 initialize_fields(target(), JNIHandles::resolve(compiled_code_obj), CHECK_OK); | 438 initialize_fields(target(), JNIHandles::resolve(compiled_code_obj), CHECK_OK); |
439 JVMCIEnv::CodeInstallResult result = initialize_buffer(buffer, CHECK_OK); | 439 JVMCIEnv::CodeInstallResult result = initialize_buffer(buffer, CHECK_OK); |
440 if (result != JVMCIEnv::ok) { | 440 if (result != JVMCIEnv::ok) { |
441 return result; | 441 return result; |
442 } | 442 } |
443 process_exception_handlers(); | |
444 | 443 |
445 int stack_slots = _total_frame_size / HeapWordSize; // conversion to words | 444 int stack_slots = _total_frame_size / HeapWordSize; // conversion to words |
446 | 445 |
447 if (!compiled_code->is_a(HotSpotCompiledNmethod::klass())) { | 446 if (!compiled_code->is_a(HotSpotCompiledNmethod::klass())) { |
448 oop stubName = HotSpotCompiledCode::name(compiled_code_obj); | 447 oop stubName = CompiledCode::name(compiled_code_obj); |
449 char* name = strdup(java_lang_String::as_utf8_string(stubName)); | 448 char* name = strdup(java_lang_String::as_utf8_string(stubName)); |
450 cb = RuntimeStub::new_runtime_stub(name, | 449 cb = RuntimeStub::new_runtime_stub(name, |
451 &buffer, | 450 &buffer, |
452 CodeOffsets::frame_never_safe, | 451 CodeOffsets::frame_never_safe, |
453 stack_slots, | 452 stack_slots, |
488 } else { | 487 } else { |
489 // Must be a HotSpotCompiledRuntimeStub. | 488 // Must be a HotSpotCompiledRuntimeStub. |
490 // Only used in OopMap constructor for non-product builds | 489 // Only used in OopMap constructor for non-product builds |
491 _parameter_count = 0; | 490 _parameter_count = 0; |
492 } | 491 } |
493 _sites_handle = JNIHandles::make_local(HotSpotCompiledCode::sites(compiled_code)); | 492 _sites_handle = JNIHandles::make_local(CompiledCode::sites(compiled_code)); |
494 _exception_handlers_handle = JNIHandles::make_local(HotSpotCompiledCode::exceptionHandlers(compiled_code)); | 493 |
495 | 494 _code_handle = JNIHandles::make_local(CompiledCode::targetCode(compiled_code)); |
496 _code_handle = JNIHandles::make_local(HotSpotCompiledCode::targetCode(compiled_code)); | 495 _code_size = CompiledCode::targetCodeSize(compiled_code); |
497 _code_size = HotSpotCompiledCode::targetCodeSize(compiled_code); | |
498 _total_frame_size = HotSpotCompiledCode::totalFrameSize(compiled_code); | 496 _total_frame_size = HotSpotCompiledCode::totalFrameSize(compiled_code); |
499 _custom_stack_area_offset = HotSpotCompiledCode::customStackAreaOffset(compiled_code); | 497 _custom_stack_area_offset = HotSpotCompiledCode::customStackAreaOffset(compiled_code); |
500 | 498 |
501 // Pre-calculate the constants section size. This is required for PC-relative addressing. | 499 // Pre-calculate the constants section size. This is required for PC-relative addressing. |
502 _data_section_handle = JNIHandles::make_local(HotSpotCompiledCode::dataSection(compiled_code)); | 500 _data_section_handle = JNIHandles::make_local(HotSpotCompiledCode::dataSection(compiled_code)); |
523 // Estimate the number of static call stubs that might be emitted. | 521 // Estimate the number of static call stubs that might be emitted. |
524 int static_call_stubs = 0; | 522 int static_call_stubs = 0; |
525 objArrayOop sites = this->sites(); | 523 objArrayOop sites = this->sites(); |
526 for (int i = 0; i < sites->length(); i++) { | 524 for (int i = 0; i < sites->length(); i++) { |
527 oop site = sites->obj_at(i); | 525 oop site = sites->obj_at(i); |
528 if (site->is_a(CompilationResult_Mark::klass())) { | 526 if (site->is_a(site_Mark::klass())) { |
529 oop id_obj = CompilationResult_Mark::id(site); | 527 oop id_obj = site_Mark::id(site); |
530 if (id_obj != NULL) { | 528 if (id_obj != NULL) { |
531 if (!java_lang_boxing_object::is_instance(id_obj, T_INT)) { | 529 if (!java_lang_boxing_object::is_instance(id_obj, T_INT)) { |
532 JVMCI_ERROR_0("expected Integer id, got %s", id_obj->klass()->signature_name()); | 530 JVMCI_ERROR_0("expected Integer id, got %s", id_obj->klass()->signature_name()); |
533 } | 531 } |
534 jint id = id_obj->int_field(java_lang_boxing_object::value_offset_in_bytes(T_INT)); | 532 jint id = id_obj->int_field(java_lang_boxing_object::value_offset_in_bytes(T_INT)); |
581 memcpy(_instructions->start(), code()->base(T_BYTE), _code_size); | 579 memcpy(_instructions->start(), code()->base(T_BYTE), _code_size); |
582 _instructions->set_end(end_pc); | 580 _instructions->set_end(end_pc); |
583 | 581 |
584 for (int i = 0; i < data_section_patches()->length(); i++) { | 582 for (int i = 0; i < data_section_patches()->length(); i++) { |
585 Handle patch = data_section_patches()->obj_at(i); | 583 Handle patch = data_section_patches()->obj_at(i); |
586 Handle reference = CompilationResult_DataPatch::reference(patch); | 584 Handle reference = site_DataPatch::reference(patch); |
587 if (!reference->is_a(CompilationResult_ConstantReference::klass())) { | 585 if (!reference->is_a(site_ConstantReference::klass())) { |
588 JVMCI_ERROR_OK("invalid patch in data section: %s", reference->klass()->signature_name()); | 586 JVMCI_ERROR_OK("invalid patch in data section: %s", reference->klass()->signature_name()); |
589 } | 587 } |
590 Handle constant = CompilationResult_ConstantReference::constant(reference); | 588 Handle constant = site_ConstantReference::constant(reference); |
591 address dest = _constants->start() + CompilationResult_Site::pcOffset(patch); | 589 address dest = _constants->start() + site_Site::pcOffset(patch); |
592 if (constant->is_a(HotSpotMetaspaceConstantImpl::klass())) { | 590 if (constant->is_a(HotSpotMetaspaceConstantImpl::klass())) { |
593 if (HotSpotMetaspaceConstantImpl::compressed(constant)) { | 591 if (HotSpotMetaspaceConstantImpl::compressed(constant)) { |
594 #ifdef _LP64 | 592 #ifdef _LP64 |
595 *((narrowKlass*) dest) = record_narrow_metadata_reference(constant, CHECK_OK); | 593 *((narrowKlass*) dest) = record_narrow_metadata_reference(constant, CHECK_OK); |
596 #else | 594 #else |
618 } | 616 } |
619 } | 617 } |
620 jint last_pc_offset = -1; | 618 jint last_pc_offset = -1; |
621 for (int i = 0; i < sites->length(); i++) { | 619 for (int i = 0; i < sites->length(); i++) { |
622 Handle site = sites->obj_at(i); | 620 Handle site = sites->obj_at(i); |
623 jint pc_offset = CompilationResult_Site::pcOffset(site); | 621 jint pc_offset = site_Site::pcOffset(site); |
624 | 622 |
625 if (site->is_a(CompilationResult_Call::klass())) { | 623 if (site->is_a(site_Call::klass())) { |
626 TRACE_jvmci_4("call at %i", pc_offset); | 624 TRACE_jvmci_4("call at %i", pc_offset); |
627 site_Call(buffer, pc_offset, site, CHECK_OK); | 625 site_Call(buffer, pc_offset, site, CHECK_OK); |
628 } else if (site->is_a(CompilationResult_Infopoint::klass())) { | 626 } else if (site->is_a(site_Infopoint::klass())) { |
629 // three reasons for infopoints denote actual safepoints | 627 // three reasons for infopoints denote actual safepoints |
630 oop reason = CompilationResult_Infopoint::reason(site); | 628 oop reason = site_Infopoint::reason(site); |
631 if (InfopointReason::SAFEPOINT() == reason || InfopointReason::CALL() == reason || InfopointReason::IMPLICIT_EXCEPTION() == reason) { | 629 if (site_InfopointReason::SAFEPOINT() == reason || site_InfopointReason::CALL() == reason || site_InfopointReason::IMPLICIT_EXCEPTION() == reason) { |
632 TRACE_jvmci_4("safepoint at %i", pc_offset); | 630 TRACE_jvmci_4("safepoint at %i", pc_offset); |
633 site_Safepoint(buffer, pc_offset, site, CHECK_OK); | 631 site_Safepoint(buffer, pc_offset, site, CHECK_OK); |
634 } else { | 632 } else { |
635 TRACE_jvmci_4("infopoint at %i", pc_offset); | 633 TRACE_jvmci_4("infopoint at %i", pc_offset); |
636 site_Infopoint(buffer, pc_offset, site, CHECK_OK); | 634 site_Infopoint(buffer, pc_offset, site, CHECK_OK); |
637 } | 635 } |
638 } else if (site->is_a(CompilationResult_DataPatch::klass())) { | 636 } else if (site->is_a(site_DataPatch::klass())) { |
639 TRACE_jvmci_4("datapatch at %i", pc_offset); | 637 TRACE_jvmci_4("datapatch at %i", pc_offset); |
640 site_DataPatch(buffer, pc_offset, site, CHECK_OK); | 638 site_DataPatch(buffer, pc_offset, site, CHECK_OK); |
641 } else if (site->is_a(CompilationResult_Mark::klass())) { | 639 } else if (site->is_a(site_Mark::klass())) { |
642 TRACE_jvmci_4("mark at %i", pc_offset); | 640 TRACE_jvmci_4("mark at %i", pc_offset); |
643 site_Mark(buffer, pc_offset, site, CHECK_OK); | 641 site_Mark(buffer, pc_offset, site, CHECK_OK); |
642 } else if (site->is_a(site_ExceptionHandler::klass())) { | |
643 TRACE_jvmci_4("exceptionhandler at %i", pc_offset); | |
644 site_ExceptionHandler(pc_offset, site); | |
644 } else { | 645 } else { |
645 JVMCI_ERROR_OK("unexpected site subclass: %s", site->klass()->signature_name()); | 646 JVMCI_ERROR_OK("unexpected site subclass: %s", site->klass()->signature_name()); |
646 } | 647 } |
647 last_pc_offset = pc_offset; | 648 last_pc_offset = pc_offset; |
648 | 649 |
704 Handle methodHandle = Assumptions_CallSiteTargetValue::methodHandle(assumption()); | 705 Handle methodHandle = Assumptions_CallSiteTargetValue::methodHandle(assumption()); |
705 | 706 |
706 _dependencies->assert_call_site_target_value(callSite(), methodHandle()); | 707 _dependencies->assert_call_site_target_value(callSite(), methodHandle()); |
707 } | 708 } |
708 | 709 |
709 void CodeInstaller::process_exception_handlers() { | 710 void CodeInstaller::site_ExceptionHandler(jint pc_offset, Handle exc) { |
710 if (exception_handlers() != NULL) { | 711 jint handler_offset = site_ExceptionHandler::handlerPos(exc); |
711 objArrayOop handlers = exception_handlers(); | 712 |
712 for (int i = 0; i < handlers->length(); i++) { | 713 // Subtable header |
713 oop exc = handlers->obj_at(i); | 714 _exception_handler_table.add_entry(HandlerTableEntry(1, pc_offset, 0)); |
714 jint pc_offset = CompilationResult_Site::pcOffset(exc); | 715 |
715 jint handler_offset = CompilationResult_ExceptionHandler::handlerPos(exc); | 716 // Subtable entry |
716 | 717 _exception_handler_table.add_entry(HandlerTableEntry(-1, handler_offset, 0)); |
717 // Subtable header | |
718 _exception_handler_table.add_entry(HandlerTableEntry(1, pc_offset, 0)); | |
719 | |
720 // Subtable entry | |
721 _exception_handler_table.add_entry(HandlerTableEntry(-1, handler_offset, 0)); | |
722 } | |
723 } | |
724 } | 718 } |
725 | 719 |
726 // If deoptimization happens, the interpreter should reexecute these bytecodes. | 720 // If deoptimization happens, the interpreter should reexecute these bytecodes. |
727 // This function mainly helps the compilers to set up the reexecute bit. | 721 // This function mainly helps the compilers to set up the reexecute bit. |
728 static bool bytecode_should_reexecute(Bytecodes::Code code) { | 722 static bool bytecode_should_reexecute(Bytecodes::Code code) { |
887 _debug_recorder->describe_scope(pc_offset, method, NULL, bci, reexecute, throw_exception, false, false, | 881 _debug_recorder->describe_scope(pc_offset, method, NULL, bci, reexecute, throw_exception, false, false, |
888 locals_token, expressions_token, monitors_token); | 882 locals_token, expressions_token, monitors_token); |
889 } | 883 } |
890 | 884 |
891 void CodeInstaller::site_Safepoint(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS) { | 885 void CodeInstaller::site_Safepoint(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS) { |
892 Handle debug_info = CompilationResult_Infopoint::debugInfo(site); | 886 Handle debug_info = site_Infopoint::debugInfo(site); |
893 if (debug_info.is_null()) { | 887 if (debug_info.is_null()) { |
894 JVMCI_ERROR("debug info expected at safepoint at %i", pc_offset); | 888 JVMCI_ERROR("debug info expected at safepoint at %i", pc_offset); |
895 } | 889 } |
896 | 890 |
897 // address instruction = _instructions->start() + pc_offset; | 891 // address instruction = _instructions->start() + pc_offset; |
901 record_scope(pc_offset, debug_info, CodeInstaller::FullFrame, CHECK); | 895 record_scope(pc_offset, debug_info, CodeInstaller::FullFrame, CHECK); |
902 _debug_recorder->end_safepoint(pc_offset); | 896 _debug_recorder->end_safepoint(pc_offset); |
903 } | 897 } |
904 | 898 |
905 void CodeInstaller::site_Infopoint(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS) { | 899 void CodeInstaller::site_Infopoint(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS) { |
906 Handle debug_info = CompilationResult_Infopoint::debugInfo(site); | 900 Handle debug_info = site_Infopoint::debugInfo(site); |
907 if (debug_info.is_null()) { | 901 if (debug_info.is_null()) { |
908 JVMCI_ERROR("debug info expected at infopoint at %i", pc_offset); | 902 JVMCI_ERROR("debug info expected at infopoint at %i", pc_offset); |
909 } | 903 } |
910 | 904 |
911 // We'd like to check that pc_offset is greater than the | 905 // We'd like to check that pc_offset is greater than the |
916 record_scope(pc_offset, debug_info, CodeInstaller::BytecodePosition, CHECK); | 910 record_scope(pc_offset, debug_info, CodeInstaller::BytecodePosition, CHECK); |
917 _debug_recorder->end_non_safepoint(pc_offset); | 911 _debug_recorder->end_non_safepoint(pc_offset); |
918 } | 912 } |
919 | 913 |
920 void CodeInstaller::site_Call(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS) { | 914 void CodeInstaller::site_Call(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS) { |
921 Handle target = CompilationResult_Call::target(site); | 915 Handle target = site_Call::target(site); |
922 InstanceKlass* target_klass = InstanceKlass::cast(target->klass()); | 916 InstanceKlass* target_klass = InstanceKlass::cast(target->klass()); |
923 | 917 |
924 Handle hotspot_method; // JavaMethod | 918 Handle hotspot_method; // JavaMethod |
925 Handle foreign_call; | 919 Handle foreign_call; |
926 | 920 |
928 foreign_call = target; | 922 foreign_call = target; |
929 } else { | 923 } else { |
930 hotspot_method = target; | 924 hotspot_method = target; |
931 } | 925 } |
932 | 926 |
933 Handle debug_info = CompilationResult_Call::debugInfo(site); | 927 Handle debug_info = site_Call::debugInfo(site); |
934 | 928 |
935 assert(hotspot_method.not_null() ^ foreign_call.not_null(), "Call site needs exactly one type"); | 929 assert(hotspot_method.not_null() ^ foreign_call.not_null(), "Call site needs exactly one type"); |
936 | 930 |
937 NativeInstruction* inst = nativeInstruction_at(_instructions->start() + pc_offset); | 931 NativeInstruction* inst = nativeInstruction_at(_instructions->start() + pc_offset); |
938 jint next_pc_offset = CodeInstaller::pd_next_offset(inst, pc_offset, hotspot_method, CHECK); | 932 jint next_pc_offset = CodeInstaller::pd_next_offset(inst, pc_offset, hotspot_method, CHECK); |
965 _debug_recorder->end_safepoint(next_pc_offset); | 959 _debug_recorder->end_safepoint(next_pc_offset); |
966 } | 960 } |
967 } | 961 } |
968 | 962 |
969 void CodeInstaller::site_DataPatch(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS) { | 963 void CodeInstaller::site_DataPatch(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS) { |
970 Handle reference = CompilationResult_DataPatch::reference(site); | 964 Handle reference = site_DataPatch::reference(site); |
971 if (reference->is_a(CompilationResult_ConstantReference::klass())) { | 965 if (reference->is_a(site_ConstantReference::klass())) { |
972 Handle constant = CompilationResult_ConstantReference::constant(reference); | 966 Handle constant = site_ConstantReference::constant(reference); |
973 if (constant->is_a(HotSpotObjectConstantImpl::klass())) { | 967 if (constant->is_a(HotSpotObjectConstantImpl::klass())) { |
974 pd_patch_OopConstant(pc_offset, constant, CHECK); | 968 pd_patch_OopConstant(pc_offset, constant, CHECK); |
975 } else if (constant->is_a(HotSpotMetaspaceConstantImpl::klass())) { | 969 } else if (constant->is_a(HotSpotMetaspaceConstantImpl::klass())) { |
976 pd_patch_MetaspaceConstant(pc_offset, constant, CHECK); | 970 pd_patch_MetaspaceConstant(pc_offset, constant, CHECK); |
977 } else { | 971 } else { |
978 JVMCI_ERROR("unknown constant type in data patch: %s", constant->klass()->signature_name()); | 972 JVMCI_ERROR("unknown constant type in data patch: %s", constant->klass()->signature_name()); |
979 } | 973 } |
980 } else if (reference->is_a(CompilationResult_DataSectionReference::klass())) { | 974 } else if (reference->is_a(site_DataSectionReference::klass())) { |
981 int data_offset = CompilationResult_DataSectionReference::offset(reference); | 975 int data_offset = site_DataSectionReference::offset(reference); |
982 if (0 <= data_offset && data_offset < _constants_size) { | 976 if (0 <= data_offset && data_offset < _constants_size) { |
983 pd_patch_DataSectionReference(pc_offset, data_offset); | 977 pd_patch_DataSectionReference(pc_offset, data_offset); |
984 } else { | 978 } else { |
985 JVMCI_ERROR("data offset 0x%X points outside data section (size 0x%X)", data_offset, _constants_size); | 979 JVMCI_ERROR("data offset 0x%X points outside data section (size 0x%X)", data_offset, _constants_size); |
986 } | 980 } |
988 JVMCI_ERROR("unknown data patch type: %s", reference->klass()->signature_name()); | 982 JVMCI_ERROR("unknown data patch type: %s", reference->klass()->signature_name()); |
989 } | 983 } |
990 } | 984 } |
991 | 985 |
992 void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS) { | 986 void CodeInstaller::site_Mark(CodeBuffer& buffer, jint pc_offset, Handle site, TRAPS) { |
993 Handle id_obj = CompilationResult_Mark::id(site); | 987 Handle id_obj = site_Mark::id(site); |
994 | 988 |
995 if (id_obj.not_null()) { | 989 if (id_obj.not_null()) { |
996 if (!java_lang_boxing_object::is_instance(id_obj(), T_INT)) { | 990 if (!java_lang_boxing_object::is_instance(id_obj(), T_INT)) { |
997 JVMCI_ERROR("expected Integer id, got %s", id_obj->klass()->signature_name()); | 991 JVMCI_ERROR("expected Integer id, got %s", id_obj->klass()->signature_name()); |
998 } | 992 } |