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 }