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));