Mercurial > hg > truffle
comparison src/share/vm/opto/library_call.cpp @ 17474:6fa574bfd32a
Merge
author | chegar |
---|---|
date | Thu, 03 Oct 2013 19:13:12 +0100 |
parents | 1b64d46620a3 |
children | c9ccd7b85f20 |
comparison
equal
deleted
inserted
replaced
17473:9b4ce069642e | 17474:6fa574bfd32a |
---|---|
541 JVMState* LibraryIntrinsic::generate(JVMState* jvms) { | 541 JVMState* LibraryIntrinsic::generate(JVMState* jvms) { |
542 LibraryCallKit kit(jvms, this); | 542 LibraryCallKit kit(jvms, this); |
543 Compile* C = kit.C; | 543 Compile* C = kit.C; |
544 int nodes = C->unique(); | 544 int nodes = C->unique(); |
545 #ifndef PRODUCT | 545 #ifndef PRODUCT |
546 if ((PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) && Verbose) { | 546 if ((C->print_intrinsics() || C->print_inlining()) && Verbose) { |
547 char buf[1000]; | 547 char buf[1000]; |
548 const char* str = vmIntrinsics::short_name_as_C_string(intrinsic_id(), buf, sizeof(buf)); | 548 const char* str = vmIntrinsics::short_name_as_C_string(intrinsic_id(), buf, sizeof(buf)); |
549 tty->print_cr("Intrinsic %s", str); | 549 tty->print_cr("Intrinsic %s", str); |
550 } | 550 } |
551 #endif | 551 #endif |
552 ciMethod* callee = kit.callee(); | 552 ciMethod* callee = kit.callee(); |
553 const int bci = kit.bci(); | 553 const int bci = kit.bci(); |
554 | 554 |
555 // Try to inline the intrinsic. | 555 // Try to inline the intrinsic. |
556 if (kit.try_to_inline()) { | 556 if (kit.try_to_inline()) { |
557 if (PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) { | 557 if (C->print_intrinsics() || C->print_inlining()) { |
558 C->print_inlining(callee, jvms->depth() - 1, bci, is_virtual() ? "(intrinsic, virtual)" : "(intrinsic)"); | 558 C->print_inlining(callee, jvms->depth() - 1, bci, is_virtual() ? "(intrinsic, virtual)" : "(intrinsic)"); |
559 } | 559 } |
560 C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_worked); | 560 C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_worked); |
561 if (C->log()) { | 561 if (C->log()) { |
562 C->log()->elem("intrinsic id='%s'%s nodes='%d'", | 562 C->log()->elem("intrinsic id='%s'%s nodes='%d'", |
568 kit.push_result(); | 568 kit.push_result(); |
569 return kit.transfer_exceptions_into_jvms(); | 569 return kit.transfer_exceptions_into_jvms(); |
570 } | 570 } |
571 | 571 |
572 // The intrinsic bailed out | 572 // The intrinsic bailed out |
573 if (PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) { | 573 if (C->print_intrinsics() || C->print_inlining()) { |
574 if (jvms->has_method()) { | 574 if (jvms->has_method()) { |
575 // Not a root compile. | 575 // Not a root compile. |
576 const char* msg = is_virtual() ? "failed to inline (intrinsic, virtual)" : "failed to inline (intrinsic)"; | 576 const char* msg = is_virtual() ? "failed to inline (intrinsic, virtual)" : "failed to inline (intrinsic)"; |
577 C->print_inlining(callee, jvms->depth() - 1, bci, msg); | 577 C->print_inlining(callee, jvms->depth() - 1, bci, msg); |
578 } else { | 578 } else { |
590 LibraryCallKit kit(jvms, this); | 590 LibraryCallKit kit(jvms, this); |
591 Compile* C = kit.C; | 591 Compile* C = kit.C; |
592 int nodes = C->unique(); | 592 int nodes = C->unique(); |
593 #ifndef PRODUCT | 593 #ifndef PRODUCT |
594 assert(is_predicted(), "sanity"); | 594 assert(is_predicted(), "sanity"); |
595 if ((PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) && Verbose) { | 595 if ((C->print_intrinsics() || C->print_inlining()) && Verbose) { |
596 char buf[1000]; | 596 char buf[1000]; |
597 const char* str = vmIntrinsics::short_name_as_C_string(intrinsic_id(), buf, sizeof(buf)); | 597 const char* str = vmIntrinsics::short_name_as_C_string(intrinsic_id(), buf, sizeof(buf)); |
598 tty->print_cr("Predicate for intrinsic %s", str); | 598 tty->print_cr("Predicate for intrinsic %s", str); |
599 } | 599 } |
600 #endif | 600 #endif |
601 ciMethod* callee = kit.callee(); | 601 ciMethod* callee = kit.callee(); |
602 const int bci = kit.bci(); | 602 const int bci = kit.bci(); |
603 | 603 |
604 Node* slow_ctl = kit.try_to_predicate(); | 604 Node* slow_ctl = kit.try_to_predicate(); |
605 if (!kit.failing()) { | 605 if (!kit.failing()) { |
606 if (PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) { | 606 if (C->print_intrinsics() || C->print_inlining()) { |
607 C->print_inlining(callee, jvms->depth() - 1, bci, is_virtual() ? "(intrinsic, virtual)" : "(intrinsic)"); | 607 C->print_inlining(callee, jvms->depth() - 1, bci, is_virtual() ? "(intrinsic, virtual)" : "(intrinsic)"); |
608 } | 608 } |
609 C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_worked); | 609 C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_worked); |
610 if (C->log()) { | 610 if (C->log()) { |
611 C->log()->elem("predicate_intrinsic id='%s'%s nodes='%d'", | 611 C->log()->elem("predicate_intrinsic id='%s'%s nodes='%d'", |
615 } | 615 } |
616 return slow_ctl; // Could be NULL if the check folds. | 616 return slow_ctl; // Could be NULL if the check folds. |
617 } | 617 } |
618 | 618 |
619 // The intrinsic bailed out | 619 // The intrinsic bailed out |
620 if (PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) { | 620 if (C->print_intrinsics() || C->print_inlining()) { |
621 if (jvms->has_method()) { | 621 if (jvms->has_method()) { |
622 // Not a root compile. | 622 // Not a root compile. |
623 const char* msg = "failed to generate predicate for intrinsic"; | 623 const char* msg = "failed to generate predicate for intrinsic"; |
624 C->print_inlining(kit.callee(), jvms->depth() - 1, bci, msg); | 624 C->print_inlining(kit.callee(), jvms->depth() - 1, bci, msg); |
625 } else { | 625 } else { |
1278 Node* target = _gvn.transform( makecon(TypeOopPtr::make_from_constant(target_array, true))); | 1278 Node* target = _gvn.transform( makecon(TypeOopPtr::make_from_constant(target_array, true))); |
1279 jint target_length = target_array->length(); | 1279 jint target_length = target_array->length(); |
1280 const TypeAry* target_array_type = TypeAry::make(TypeInt::CHAR, TypeInt::make(0, target_length, Type::WidenMin)); | 1280 const TypeAry* target_array_type = TypeAry::make(TypeInt::CHAR, TypeInt::make(0, target_length, Type::WidenMin)); |
1281 const TypeAryPtr* target_type = TypeAryPtr::make(TypePtr::BotPTR, target_array_type, target_array->klass(), true, Type::OffsetBot); | 1281 const TypeAryPtr* target_type = TypeAryPtr::make(TypePtr::BotPTR, target_array_type, target_array->klass(), true, Type::OffsetBot); |
1282 | 1282 |
1283 // String.value field is known to be @Stable. | |
1284 if (UseImplicitStableValues) { | |
1285 target = cast_array_to_stable(target, target_type); | |
1286 } | |
1287 | |
1283 IdealKit kit(this, false, true); | 1288 IdealKit kit(this, false, true); |
1284 #define __ kit. | 1289 #define __ kit. |
1285 Node* zero = __ ConI(0); | 1290 Node* zero = __ ConI(0); |
1286 Node* one = __ ConI(1); | 1291 Node* one = __ ConI(1); |
1287 Node* cache = __ ConI(cache_i); | 1292 Node* cache = __ ConI(cache_i); |
2292 // contraint in place. | 2297 // contraint in place. |
2293 if (sharpened_klass != NULL && sharpened_klass->is_loaded()) { | 2298 if (sharpened_klass != NULL && sharpened_klass->is_loaded()) { |
2294 const TypeOopPtr* tjp = TypeOopPtr::make_from_klass(sharpened_klass); | 2299 const TypeOopPtr* tjp = TypeOopPtr::make_from_klass(sharpened_klass); |
2295 | 2300 |
2296 #ifndef PRODUCT | 2301 #ifndef PRODUCT |
2297 if (PrintIntrinsics || PrintInlining || PrintOptoInlining) { | 2302 if (C->print_intrinsics() || C->print_inlining()) { |
2298 tty->print(" from base type: "); adr_type->dump(); | 2303 tty->print(" from base type: "); adr_type->dump(); |
2299 tty->print(" sharpened value: "); tjp->dump(); | 2304 tty->print(" sharpened value: "); tjp->dump(); |
2300 } | 2305 } |
2301 #endif | 2306 #endif |
2302 // Sharpen the value type. | 2307 // Sharpen the value type. |
3253 | 3258 |
3254 const TypeInstPtr* mirror_con = _gvn.type(mirror)->isa_instptr(); | 3259 const TypeInstPtr* mirror_con = _gvn.type(mirror)->isa_instptr(); |
3255 if (mirror_con == NULL) return false; // cannot happen? | 3260 if (mirror_con == NULL) return false; // cannot happen? |
3256 | 3261 |
3257 #ifndef PRODUCT | 3262 #ifndef PRODUCT |
3258 if (PrintIntrinsics || PrintInlining || PrintOptoInlining) { | 3263 if (C->print_intrinsics() || C->print_inlining()) { |
3259 ciType* k = mirror_con->java_mirror_type(); | 3264 ciType* k = mirror_con->java_mirror_type(); |
3260 if (k) { | 3265 if (k) { |
3261 tty->print("Inlining %s on constant Class ", vmIntrinsics::name_at(intrinsic_id())); | 3266 tty->print("Inlining %s on constant Class ", vmIntrinsics::name_at(intrinsic_id())); |
3262 k->print_name(); | 3267 k->print_name(); |
3263 tty->cr(); | 3268 tty->cr(); |
3727 // Helper for hashCode and clone. Peeks inside the vtable to avoid a call. | 3732 // Helper for hashCode and clone. Peeks inside the vtable to avoid a call. |
3728 Node* LibraryCallKit::generate_virtual_guard(Node* obj_klass, | 3733 Node* LibraryCallKit::generate_virtual_guard(Node* obj_klass, |
3729 RegionNode* slow_region) { | 3734 RegionNode* slow_region) { |
3730 ciMethod* method = callee(); | 3735 ciMethod* method = callee(); |
3731 int vtable_index = method->vtable_index(); | 3736 int vtable_index = method->vtable_index(); |
3737 assert(vtable_index >= 0 || vtable_index == Method::nonvirtual_vtable_index, | |
3738 err_msg_res("bad index %d", vtable_index)); | |
3732 // Get the Method* out of the appropriate vtable entry. | 3739 // Get the Method* out of the appropriate vtable entry. |
3733 int entry_offset = (InstanceKlass::vtable_start_offset() + | 3740 int entry_offset = (InstanceKlass::vtable_start_offset() + |
3734 vtable_index*vtableEntry::size()) * wordSize + | 3741 vtable_index*vtableEntry::size()) * wordSize + |
3735 vtableEntry::method_offset_in_bytes(); | 3742 vtableEntry::method_offset_in_bytes(); |
3736 Node* entry_addr = basic_plus_adr(obj_klass, entry_offset); | 3743 Node* entry_addr = basic_plus_adr(obj_klass, entry_offset); |
3777 } else { | 3784 } else { |
3778 // hashCode and clone are not a miranda methods, | 3785 // hashCode and clone are not a miranda methods, |
3779 // so the vtable index is fixed. | 3786 // so the vtable index is fixed. |
3780 // No need to use the linkResolver to get it. | 3787 // No need to use the linkResolver to get it. |
3781 vtable_index = method->vtable_index(); | 3788 vtable_index = method->vtable_index(); |
3789 assert(vtable_index >= 0 || vtable_index == Method::nonvirtual_vtable_index, | |
3790 err_msg_res("bad index %d", vtable_index)); | |
3782 } | 3791 } |
3783 slow_call = new(C) CallDynamicJavaNode(tf, | 3792 slow_call = new(C) CallDynamicJavaNode(tf, |
3784 SharedRuntime::get_resolve_virtual_call_stub(), | 3793 SharedRuntime::get_resolve_virtual_call_stub(), |
3785 method, vtable_index, bci()); | 3794 method, vtable_index, bci()); |
3786 } else { // neither virtual nor static: opt_virtual | 3795 } else { // neither virtual nor static: opt_virtual |
3941 // NOTE: This code must perform the same logic as JVM_GetCallerClass | 3950 // NOTE: This code must perform the same logic as JVM_GetCallerClass |
3942 // in that it must skip particular security frames and checks for | 3951 // in that it must skip particular security frames and checks for |
3943 // caller sensitive methods. | 3952 // caller sensitive methods. |
3944 bool LibraryCallKit::inline_native_Reflection_getCallerClass() { | 3953 bool LibraryCallKit::inline_native_Reflection_getCallerClass() { |
3945 #ifndef PRODUCT | 3954 #ifndef PRODUCT |
3946 if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { | 3955 if ((C->print_intrinsics() || C->print_inlining()) && Verbose) { |
3947 tty->print_cr("Attempting to inline sun.reflect.Reflection.getCallerClass"); | 3956 tty->print_cr("Attempting to inline sun.reflect.Reflection.getCallerClass"); |
3948 } | 3957 } |
3949 #endif | 3958 #endif |
3950 | 3959 |
3951 if (!jvms()->has_method()) { | 3960 if (!jvms()->has_method()) { |
3952 #ifndef PRODUCT | 3961 #ifndef PRODUCT |
3953 if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { | 3962 if ((C->print_intrinsics() || C->print_inlining()) && Verbose) { |
3954 tty->print_cr(" Bailing out because intrinsic was inlined at top level"); | 3963 tty->print_cr(" Bailing out because intrinsic was inlined at top level"); |
3955 } | 3964 } |
3956 #endif | 3965 #endif |
3957 return false; | 3966 return false; |
3958 } | 3967 } |
3972 break; | 3981 break; |
3973 case 1: | 3982 case 1: |
3974 // Frame 0 and 1 must be caller sensitive (see JVM_GetCallerClass). | 3983 // Frame 0 and 1 must be caller sensitive (see JVM_GetCallerClass). |
3975 if (!m->caller_sensitive()) { | 3984 if (!m->caller_sensitive()) { |
3976 #ifndef PRODUCT | 3985 #ifndef PRODUCT |
3977 if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { | 3986 if ((C->print_intrinsics() || C->print_inlining()) && Verbose) { |
3978 tty->print_cr(" Bailing out: CallerSensitive annotation expected at frame %d", n); | 3987 tty->print_cr(" Bailing out: CallerSensitive annotation expected at frame %d", n); |
3979 } | 3988 } |
3980 #endif | 3989 #endif |
3981 return false; // bail-out; let JVM_GetCallerClass do the work | 3990 return false; // bail-out; let JVM_GetCallerClass do the work |
3982 } | 3991 } |
3988 ciInstanceKlass* caller_klass = caller_jvms->method()->holder(); | 3997 ciInstanceKlass* caller_klass = caller_jvms->method()->holder(); |
3989 ciInstance* caller_mirror = caller_klass->java_mirror(); | 3998 ciInstance* caller_mirror = caller_klass->java_mirror(); |
3990 set_result(makecon(TypeInstPtr::make(caller_mirror))); | 3999 set_result(makecon(TypeInstPtr::make(caller_mirror))); |
3991 | 4000 |
3992 #ifndef PRODUCT | 4001 #ifndef PRODUCT |
3993 if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { | 4002 if ((C->print_intrinsics() || C->print_inlining()) && Verbose) { |
3994 tty->print_cr(" Succeeded: caller = %d) %s.%s, JVMS depth = %d", n, caller_klass->name()->as_utf8(), caller_jvms->method()->name()->as_utf8(), jvms()->depth()); | 4003 tty->print_cr(" Succeeded: caller = %d) %s.%s, JVMS depth = %d", n, caller_klass->name()->as_utf8(), caller_jvms->method()->name()->as_utf8(), jvms()->depth()); |
3995 tty->print_cr(" JVM state at this point:"); | 4004 tty->print_cr(" JVM state at this point:"); |
3996 for (int i = jvms()->depth(), n = 1; i >= 1; i--, n++) { | 4005 for (int i = jvms()->depth(), n = 1; i >= 1; i--, n++) { |
3997 ciMethod* m = jvms()->of_depth(i)->method(); | 4006 ciMethod* m = jvms()->of_depth(i)->method(); |
3998 tty->print_cr(" %d) %s.%s", n, m->holder()->name()->as_utf8(), m->name()->as_utf8()); | 4007 tty->print_cr(" %d) %s.%s", n, m->holder()->name()->as_utf8(), m->name()->as_utf8()); |
4004 break; | 4013 break; |
4005 } | 4014 } |
4006 } | 4015 } |
4007 | 4016 |
4008 #ifndef PRODUCT | 4017 #ifndef PRODUCT |
4009 if ((PrintIntrinsics || PrintInlining || PrintOptoInlining) && Verbose) { | 4018 if ((C->print_intrinsics() || C->print_inlining()) && Verbose) { |
4010 tty->print_cr(" Bailing out because caller depth exceeded inlining depth = %d", jvms()->depth()); | 4019 tty->print_cr(" Bailing out because caller depth exceeded inlining depth = %d", jvms()->depth()); |
4011 tty->print_cr(" JVM state at this point:"); | 4020 tty->print_cr(" JVM state at this point:"); |
4012 for (int i = jvms()->depth(), n = 1; i >= 1; i--, n++) { | 4021 for (int i = jvms()->depth(), n = 1; i >= 1; i--, n++) { |
4013 ciMethod* m = jvms()->of_depth(i)->method(); | 4022 ciMethod* m = jvms()->of_depth(i)->method(); |
4014 tty->print_cr(" %d) %s.%s", n, m->holder()->name()->as_utf8(), m->name()->as_utf8()); | 4023 tty->print_cr(" %d) %s.%s", n, m->holder()->name()->as_utf8(), m->name()->as_utf8()); |
4197 // base_off: | 4206 // base_off: |
4198 // 8 - 32-bit VM | 4207 // 8 - 32-bit VM |
4199 // 12 - 64-bit VM, compressed klass | 4208 // 12 - 64-bit VM, compressed klass |
4200 // 16 - 64-bit VM, normal klass | 4209 // 16 - 64-bit VM, normal klass |
4201 if (base_off % BytesPerLong != 0) { | 4210 if (base_off % BytesPerLong != 0) { |
4202 assert(UseCompressedKlassPointers, ""); | 4211 assert(UseCompressedClassPointers, ""); |
4203 if (is_array) { | 4212 if (is_array) { |
4204 // Exclude length to copy by 8 bytes words. | 4213 // Exclude length to copy by 8 bytes words. |
4205 base_off += sizeof(int); | 4214 base_off += sizeof(int); |
4206 } else { | 4215 } else { |
4207 // Include klass to copy by 8 bytes words. | 4216 // Include klass to copy by 8 bytes words. |