Mercurial > hg > graal-jvmci-8
comparison src/share/vm/graal/graalCodeInstaller.cpp @ 17241:6fcb6691fe5f
Add safepoint checks during code installation
author | Tom Rodriguez <tom.rodriguez@oracle.com> |
---|---|
date | Fri, 26 Sep 2014 16:00:09 -0700 |
parents | 26f5733fb645 |
children | 508e88b5f1d3 |
comparison
equal
deleted
inserted
replaced
17240:136ba6d379f2 | 17241:6fcb6691fe5f |
---|---|
412 // Get instructions and constants CodeSections early because we need it. | 412 // Get instructions and constants CodeSections early because we need it. |
413 _instructions = buffer.insts(); | 413 _instructions = buffer.insts(); |
414 _constants = buffer.consts(); | 414 _constants = buffer.consts(); |
415 | 415 |
416 { | 416 { |
417 No_Safepoint_Verifier no_safepoint; | |
418 initialize_fields(JNIHandles::resolve(compiled_code_obj)); | 417 initialize_fields(JNIHandles::resolve(compiled_code_obj)); |
419 if (!initialize_buffer(buffer)) { | 418 if (!initialize_buffer(buffer)) { |
420 return GraalEnv::code_too_large; | 419 return GraalEnv::code_too_large; |
421 } | 420 } |
422 process_exception_handlers(); | 421 process_exception_handlers(); |
456 } | 455 } |
457 return result; | 456 return result; |
458 } | 457 } |
459 | 458 |
460 void CodeInstaller::initialize_fields(oop compiled_code) { | 459 void CodeInstaller::initialize_fields(oop compiled_code) { |
461 oop comp_result = HotSpotCompiledCode::comp(compiled_code); | 460 Handle comp_result = HotSpotCompiledCode::comp(compiled_code); |
462 if (compiled_code->is_a(HotSpotCompiledNmethod::klass())) { | 461 if (compiled_code->is_a(HotSpotCompiledNmethod::klass())) { |
463 oop hotspotJavaMethod = HotSpotCompiledNmethod::method(compiled_code); | 462 Handle hotspotJavaMethod = HotSpotCompiledNmethod::method(compiled_code); |
464 methodHandle method = getMethodFromHotSpotMethod(hotspotJavaMethod); | 463 methodHandle method = getMethodFromHotSpotMethod(hotspotJavaMethod()); |
465 _parameter_count = method->size_of_parameters(); | 464 _parameter_count = method->size_of_parameters(); |
466 TRACE_graal_1("installing code for %s", method->name_and_sig_as_C_string()); | 465 TRACE_graal_1("installing code for %s", method->name_and_sig_as_C_string()); |
467 } else { | 466 } else { |
468 assert(compiled_code->is_a(HotSpotCompiledRuntimeStub::klass()), "CCE"); | 467 assert(compiled_code->is_a(HotSpotCompiledRuntimeStub::klass()), "CCE"); |
469 // TODO (ds) not sure if this is correct - only used in OopMap constructor for non-product builds | 468 // TODO (ds) not sure if this is correct - only used in OopMap constructor for non-product builds |
470 _parameter_count = 0; | 469 _parameter_count = 0; |
471 } | 470 } |
472 _sites = (arrayOop) HotSpotCompiledCode::sites(compiled_code); | 471 _sites_handle = JNIHandles::make_global(HotSpotCompiledCode::sites(compiled_code)); |
473 _exception_handlers = (arrayOop) HotSpotCompiledCode::exceptionHandlers(compiled_code); | 472 _exception_handlers_handle = JNIHandles::make_global(HotSpotCompiledCode::exceptionHandlers(compiled_code)); |
474 | 473 |
475 _code = (arrayOop) CompilationResult::targetCode(comp_result); | 474 _code_handle = JNIHandles::make_global(CompilationResult::targetCode(comp_result)); |
476 _code_size = CompilationResult::targetCodeSize(comp_result); | 475 _code_size = CompilationResult::targetCodeSize(comp_result); |
477 _total_frame_size = CompilationResult::totalFrameSize(comp_result); | 476 _total_frame_size = CompilationResult::totalFrameSize(comp_result); |
478 _custom_stack_area_offset = CompilationResult::customStackAreaOffset(comp_result); | 477 _custom_stack_area_offset = CompilationResult::customStackAreaOffset(comp_result); |
479 | 478 |
480 // Pre-calculate the constants section size. This is required for PC-relative addressing. | 479 // Pre-calculate the constants section size. This is required for PC-relative addressing. |
481 _dataSection = HotSpotCompiledCode::dataSection(compiled_code); | 480 _data_section_handle = JNIHandles::make_global(HotSpotCompiledCode::dataSection(compiled_code)); |
482 guarantee(DataSection::sectionAlignment(_dataSection) <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin"); | 481 guarantee(DataSection::sectionAlignment(data_section()) <= _constants->alignment(), "Alignment inside constants section is restricted by alignment of section begin"); |
483 arrayOop data = (arrayOop) DataSection::data(_dataSection); | 482 arrayHandle data = (arrayOop) DataSection::data(data_section()); |
484 _constants_size = data->length(); | 483 _constants_size = data->length(); |
485 if (_constants_size > 0) { | 484 if (_constants_size > 0) { |
486 _constants_size = align_size_up(_constants_size, _constants->alignment()); | 485 _constants_size = align_size_up(_constants_size, _constants->alignment()); |
487 } | 486 } |
488 | 487 |
489 #ifndef PRODUCT | 488 #ifndef PRODUCT |
490 _comments = (arrayOop) HotSpotCompiledCode::comments(compiled_code); | 489 _comments_handle = JNIHandles::make_global((arrayOop) HotSpotCompiledCode::comments(compiled_code)); |
491 #endif | 490 #endif |
492 | 491 |
493 _next_call_type = INVOKE_INVALID; | 492 _next_call_type = INVOKE_INVALID; |
494 } | 493 } |
495 | 494 |
496 int CodeInstaller::estimate_stub_entries() { | 495 int CodeInstaller::estimate_stub_entries() { |
497 // Estimate the number of static call stubs that might be emitted. | 496 // Estimate the number of static call stubs that might be emitted. |
498 int static_call_stubs = 0; | 497 int static_call_stubs = 0; |
499 for (int i = 0; i < _sites->length(); i++) { | 498 objArrayOop sites = this->sites(); |
500 oop site = ((objArrayOop) (_sites))->obj_at(i); | 499 for (int i = 0; i < sites->length(); i++) { |
500 oop site = sites->obj_at(i); | |
501 if (site->is_a(CompilationResult_Mark::klass())) { | 501 if (site->is_a(CompilationResult_Mark::klass())) { |
502 oop id_obj = CompilationResult_Mark::id(site); | 502 oop id_obj = CompilationResult_Mark::id(site); |
503 if (id_obj != NULL) { | 503 if (id_obj != NULL) { |
504 assert(java_lang_boxing_object::is_instance(id_obj, T_INT), "Integer id expected"); | 504 assert(java_lang_boxing_object::is_instance(id_obj, T_INT), "Integer id expected"); |
505 jint id = id_obj->int_field(java_lang_boxing_object::value_offset_in_bytes(T_INT)); | 505 jint id = id_obj->int_field(java_lang_boxing_object::value_offset_in_bytes(T_INT)); |
512 return static_call_stubs; | 512 return static_call_stubs; |
513 } | 513 } |
514 | 514 |
515 // perform data and call relocation on the CodeBuffer | 515 // perform data and call relocation on the CodeBuffer |
516 bool CodeInstaller::initialize_buffer(CodeBuffer& buffer) { | 516 bool CodeInstaller::initialize_buffer(CodeBuffer& buffer) { |
517 int locs_buffer_size = _sites->length() * (relocInfo::length_limit + sizeof(relocInfo)); | 517 HandleMark hm; |
518 objArrayHandle sites = this->sites(); | |
519 int locs_buffer_size = sites->length() * (relocInfo::length_limit + sizeof(relocInfo)); | |
518 char* locs_buffer = NEW_RESOURCE_ARRAY(char, locs_buffer_size); | 520 char* locs_buffer = NEW_RESOURCE_ARRAY(char, locs_buffer_size); |
519 buffer.insts()->initialize_shared_locs((relocInfo*)locs_buffer, locs_buffer_size / sizeof(relocInfo)); | 521 buffer.insts()->initialize_shared_locs((relocInfo*)locs_buffer, locs_buffer_size / sizeof(relocInfo)); |
520 // Allocate enough space in the stub section for the static call | 522 // Allocate enough space in the stub section for the static call |
521 // stubs. Stubs have extra relocs but they are managed by the stub | 523 // stubs. Stubs have extra relocs but they are managed by the stub |
522 // section itself so they don't need to be accounted for in the | 524 // section itself so they don't need to be accounted for in the |
532 // copy the code into the newly created CodeBuffer | 534 // copy the code into the newly created CodeBuffer |
533 address end_pc = _instructions->start() + _code_size; | 535 address end_pc = _instructions->start() + _code_size; |
534 if (!_instructions->allocates2(end_pc)) { | 536 if (!_instructions->allocates2(end_pc)) { |
535 return false; | 537 return false; |
536 } | 538 } |
537 memcpy(_instructions->start(), _code->base(T_BYTE), _code_size); | 539 memcpy(_instructions->start(), code()->base(T_BYTE), _code_size); |
538 _instructions->set_end(end_pc); | 540 _instructions->set_end(end_pc); |
539 | 541 |
540 // copy the constant data into the newly created CodeBuffer | 542 // copy the constant data into the newly created CodeBuffer |
541 address end_data = _constants->start() + _constants_size; | 543 address end_data = _constants->start() + _constants_size; |
542 arrayOop data = (arrayOop) DataSection::data(_dataSection); | 544 typeArrayHandle data((typeArrayOop) DataSection::data(data_section())); |
543 memcpy(_constants->start(), data->base(T_BYTE), data->length()); | 545 memcpy(_constants->start(), data->base(T_BYTE), data->length()); |
544 _constants->set_end(end_data); | 546 _constants->set_end(end_data); |
545 | 547 |
546 objArrayOop patches = (objArrayOop) DataSection::patches(_dataSection); | 548 |
549 objArrayHandle patches = (objArrayOop) DataSection::patches(data_section()); | |
547 for (int i = 0; i < patches->length(); i++) { | 550 for (int i = 0; i < patches->length(); i++) { |
548 oop patch = patches->obj_at(i); | 551 Handle patch = patches->obj_at(i); |
549 oop data = CompilationResult_DataPatch::data(patch); | 552 Handle data = CompilationResult_DataPatch::data(patch); |
550 if (data->is_a(MetaspaceData::klass())) { | 553 if (data->is_a(MetaspaceData::klass())) { |
551 record_metadata_in_patch(data, _oop_recorder); | 554 record_metadata_in_patch(data(), _oop_recorder); |
552 } else if (data->is_a(OopData::klass())) { | 555 } else if (data->is_a(OopData::klass())) { |
553 Handle obj = OopData::object(data); | 556 Handle obj = OopData::object(data); |
554 jobject value = JNIHandles::make_local(obj()); | 557 jobject value = JNIHandles::make_local(obj()); |
555 int oop_index = _oop_recorder->find_index(value); | 558 int oop_index = _oop_recorder->find_index(value); |
556 | 559 |
560 } else { | 563 } else { |
561 ShouldNotReachHere(); | 564 ShouldNotReachHere(); |
562 } | 565 } |
563 } | 566 } |
564 jint last_pc_offset = -1; | 567 jint last_pc_offset = -1; |
565 for (int i = 0; i < _sites->length(); i++) { | 568 for (int i = 0; i < sites->length(); i++) { |
566 oop site = ((objArrayOop) (_sites))->obj_at(i); | 569 { |
567 jint pc_offset = CompilationResult_Site::pcOffset(site); | 570 No_Safepoint_Verifier no_safepoint; |
568 | 571 oop site = sites->obj_at(i); |
569 if (site->is_a(CompilationResult_Call::klass())) { | 572 jint pc_offset = CompilationResult_Site::pcOffset(site); |
570 TRACE_graal_4("call at %i", pc_offset); | 573 |
571 site_Call(buffer, pc_offset, site); | 574 if (site->is_a(CompilationResult_Call::klass())) { |
572 } else if (site->is_a(CompilationResult_Infopoint::klass())) { | 575 TRACE_graal_4("call at %i", pc_offset); |
573 // three reasons for infopoints denote actual safepoints | 576 site_Call(buffer, pc_offset, site); |
574 oop reason = CompilationResult_Infopoint::reason(site); | 577 } else if (site->is_a(CompilationResult_Infopoint::klass())) { |
575 if (InfopointReason::SAFEPOINT() == reason || InfopointReason::CALL() == reason || InfopointReason::IMPLICIT_EXCEPTION() == reason) { | 578 // three reasons for infopoints denote actual safepoints |
576 TRACE_graal_4("safepoint at %i", pc_offset); | 579 oop reason = CompilationResult_Infopoint::reason(site); |
577 site_Safepoint(buffer, pc_offset, site); | 580 if (InfopointReason::SAFEPOINT() == reason || InfopointReason::CALL() == reason || InfopointReason::IMPLICIT_EXCEPTION() == reason) { |
578 } else { | 581 TRACE_graal_4("safepoint at %i", pc_offset); |
579 // if the infopoint is not an actual safepoint, it must have one of the other reasons | 582 site_Safepoint(buffer, pc_offset, site); |
580 // (safeguard against new safepoint types that require handling above) | 583 } else { |
581 assert(InfopointReason::METHOD_START() == reason || InfopointReason::METHOD_END() == reason || InfopointReason::LINE_NUMBER() == reason, ""); | 584 // if the infopoint is not an actual safepoint, it must have one of the other reasons |
582 site_Infopoint(buffer, pc_offset, site); | 585 // (safeguard against new safepoint types that require handling above) |
583 } | 586 assert(InfopointReason::METHOD_START() == reason || InfopointReason::METHOD_END() == reason || InfopointReason::LINE_NUMBER() == reason, ""); |
584 } else if (site->is_a(CompilationResult_DataPatch::klass())) { | 587 site_Infopoint(buffer, pc_offset, site); |
585 TRACE_graal_4("datapatch at %i", pc_offset); | 588 } |
586 site_DataPatch(buffer, pc_offset, site); | 589 } else if (site->is_a(CompilationResult_DataPatch::klass())) { |
587 } else if (site->is_a(CompilationResult_Mark::klass())) { | 590 TRACE_graal_4("datapatch at %i", pc_offset); |
588 TRACE_graal_4("mark at %i", pc_offset); | 591 site_DataPatch(buffer, pc_offset, site); |
589 site_Mark(buffer, pc_offset, site); | 592 } else if (site->is_a(CompilationResult_Mark::klass())) { |
590 } else { | 593 TRACE_graal_4("mark at %i", pc_offset); |
591 fatal("unexpected Site subclass"); | 594 site_Mark(buffer, pc_offset, site); |
592 } | 595 } else { |
593 last_pc_offset = pc_offset; | 596 fatal("unexpected Site subclass"); |
597 } | |
598 last_pc_offset = pc_offset; | |
599 } | |
600 if (CodeInstallSafepointChecks && SafepointSynchronize::do_call_back()) { | |
601 // this is a hacky way to force a safepoint check but nothing else was jumping out at me. | |
602 ThreadToNativeFromVM ttnfv(JavaThread::current()); | |
603 } | |
594 } | 604 } |
595 | 605 |
596 #ifndef PRODUCT | 606 #ifndef PRODUCT |
597 if (_comments != NULL) { | 607 if (comments() != NULL) { |
598 for (int i = 0; i < _comments->length(); i++) { | 608 No_Safepoint_Verifier no_safepoint; |
599 oop comment = ((objArrayOop) (_comments))->obj_at(i); | 609 for (int i = 0; i < comments()->length(); i++) { |
610 oop comment = comments()->obj_at(i); | |
600 assert(comment->is_a(HotSpotCompiledCode_Comment::klass()), "cce"); | 611 assert(comment->is_a(HotSpotCompiledCode_Comment::klass()), "cce"); |
601 jint offset = HotSpotCompiledCode_Comment::pcOffset(comment); | 612 jint offset = HotSpotCompiledCode_Comment::pcOffset(comment); |
602 char* text = java_lang_String::as_utf8_string(HotSpotCompiledCode_Comment::text(comment)); | 613 char* text = java_lang_String::as_utf8_string(HotSpotCompiledCode_Comment::text(comment)); |
603 buffer.block_comment(offset, text); | 614 buffer.block_comment(offset, text); |
604 } | 615 } |
655 const int num_handlers = 5; | 666 const int num_handlers = 5; |
656 GrowableArray<intptr_t>* bcis = new GrowableArray<intptr_t> (num_handlers); | 667 GrowableArray<intptr_t>* bcis = new GrowableArray<intptr_t> (num_handlers); |
657 GrowableArray<intptr_t>* scope_depths = new GrowableArray<intptr_t> (num_handlers); | 668 GrowableArray<intptr_t>* scope_depths = new GrowableArray<intptr_t> (num_handlers); |
658 GrowableArray<intptr_t>* pcos = new GrowableArray<intptr_t> (num_handlers); | 669 GrowableArray<intptr_t>* pcos = new GrowableArray<intptr_t> (num_handlers); |
659 | 670 |
660 if (_exception_handlers != NULL) { | 671 if (exception_handlers() != NULL) { |
661 for (int i = 0; i < _exception_handlers->length(); i++) { | 672 objArrayOop handlers = exception_handlers(); |
662 oop exc=((objArrayOop) (_exception_handlers))->obj_at(i); | 673 for (int i = 0; i < handlers->length(); i++) { |
674 oop exc = handlers->obj_at(i); | |
663 jint pc_offset = CompilationResult_Site::pcOffset(exc); | 675 jint pc_offset = CompilationResult_Site::pcOffset(exc); |
664 jint handler_offset = CompilationResult_ExceptionHandler::handlerPos(exc); | 676 jint handler_offset = CompilationResult_ExceptionHandler::handlerPos(exc); |
665 | 677 |
666 // Subtable header | 678 // Subtable header |
667 _exception_handler_table.add_entry(HandlerTableEntry(1, pc_offset, 0)); | 679 _exception_handler_table.add_entry(HandlerTableEntry(1, pc_offset, 0)); |