Mercurial > hg > truffle
comparison src/share/vm/opto/compile.cpp @ 2008:2f644f85485d
6961690: load oops from constant table on SPARC
Summary: oops should be loaded from the constant table of an nmethod instead of materializing them with a long code sequence.
Reviewed-by: never, kvn
author | twisti |
---|---|
date | Fri, 03 Dec 2010 01:34:31 -0800 |
parents | 5ddfcf4b079e |
children | 51bd2d261853 |
comparison
equal
deleted
inserted
replaced
2007:5ddfcf4b079e | 2008:2f644f85485d |
---|---|
73 #endif | 73 #endif |
74 #ifdef TARGET_ARCH_MODEL_zero | 74 #ifdef TARGET_ARCH_MODEL_zero |
75 # include "adfiles/ad_zero.hpp" | 75 # include "adfiles/ad_zero.hpp" |
76 #endif | 76 #endif |
77 | 77 |
78 | |
79 // -------------------- Compile::mach_constant_base_node ----------------------- | |
80 // Constant table base node singleton. | |
81 MachConstantBaseNode* Compile::mach_constant_base_node() { | |
82 if (_mach_constant_base_node == NULL) { | |
83 _mach_constant_base_node = new (C) MachConstantBaseNode(); | |
84 _mach_constant_base_node->add_req(C->root()); | |
85 } | |
86 return _mach_constant_base_node; | |
87 } | |
88 | |
89 | |
78 /// Support for intrinsics. | 90 /// Support for intrinsics. |
79 | 91 |
80 // Return the index at which m must be inserted (or already exists). | 92 // Return the index at which m must be inserted (or already exists). |
81 // The sort order is by the address of the ciMethod, with is_virtual as minor key. | 93 // The sort order is by the address of the ciMethod, with is_virtual as minor key. |
82 int Compile::intrinsic_insertion_index(ciMethod* m, bool is_virtual) { | 94 int Compile::intrinsic_insertion_index(ciMethod* m, bool is_virtual) { |
430 } | 442 } |
431 #endif | 443 #endif |
432 } | 444 } |
433 | 445 |
434 | 446 |
435 void Compile::init_scratch_buffer_blob() { | 447 void Compile::init_scratch_buffer_blob(int const_size) { |
436 if( scratch_buffer_blob() != NULL ) return; | 448 if (scratch_buffer_blob() != NULL) return; |
437 | 449 |
438 // Construct a temporary CodeBuffer to have it construct a BufferBlob | 450 // Construct a temporary CodeBuffer to have it construct a BufferBlob |
439 // Cache this BufferBlob for this compile. | 451 // Cache this BufferBlob for this compile. |
440 ResourceMark rm; | 452 ResourceMark rm; |
441 int size = (MAX_inst_size + MAX_stubs_size + MAX_const_size); | 453 _scratch_const_size = const_size; |
454 int size = (MAX_inst_size + MAX_stubs_size + _scratch_const_size); | |
442 BufferBlob* blob = BufferBlob::create("Compile::scratch_buffer", size); | 455 BufferBlob* blob = BufferBlob::create("Compile::scratch_buffer", size); |
443 // Record the buffer blob for next time. | 456 // Record the buffer blob for next time. |
444 set_scratch_buffer_blob(blob); | 457 set_scratch_buffer_blob(blob); |
445 // Have we run out of code space? | 458 // Have we run out of code space? |
446 if (scratch_buffer_blob() == NULL) { | 459 if (scratch_buffer_blob() == NULL) { |
453 relocInfo* locs_buf = (relocInfo*) blob->content_end() - MAX_locs_size; | 466 relocInfo* locs_buf = (relocInfo*) blob->content_end() - MAX_locs_size; |
454 set_scratch_locs_memory(locs_buf); | 467 set_scratch_locs_memory(locs_buf); |
455 } | 468 } |
456 | 469 |
457 | 470 |
471 void Compile::clear_scratch_buffer_blob() { | |
472 assert(scratch_buffer_blob(), "no BufferBlob set"); | |
473 set_scratch_buffer_blob(NULL); | |
474 set_scratch_locs_memory(NULL); | |
475 } | |
476 | |
477 | |
458 //-----------------------scratch_emit_size------------------------------------- | 478 //-----------------------scratch_emit_size------------------------------------- |
459 // Helper function that computes size by emitting code | 479 // Helper function that computes size by emitting code |
460 uint Compile::scratch_emit_size(const Node* n) { | 480 uint Compile::scratch_emit_size(const Node* n) { |
481 // Start scratch_emit_size section. | |
482 set_in_scratch_emit_size(true); | |
483 | |
461 // Emit into a trash buffer and count bytes emitted. | 484 // Emit into a trash buffer and count bytes emitted. |
462 // This is a pretty expensive way to compute a size, | 485 // This is a pretty expensive way to compute a size, |
463 // but it works well enough if seldom used. | 486 // but it works well enough if seldom used. |
464 // All common fixed-size instructions are given a size | 487 // All common fixed-size instructions are given a size |
465 // method by the AD file. | 488 // method by the AD file. |
474 relocInfo* locs_buf = scratch_locs_memory(); | 497 relocInfo* locs_buf = scratch_locs_memory(); |
475 address blob_begin = blob->content_begin(); | 498 address blob_begin = blob->content_begin(); |
476 address blob_end = (address)locs_buf; | 499 address blob_end = (address)locs_buf; |
477 assert(blob->content_contains(blob_end), "sanity"); | 500 assert(blob->content_contains(blob_end), "sanity"); |
478 CodeBuffer buf(blob_begin, blob_end - blob_begin); | 501 CodeBuffer buf(blob_begin, blob_end - blob_begin); |
479 buf.initialize_consts_size(MAX_const_size); | 502 buf.initialize_consts_size(_scratch_const_size); |
480 buf.initialize_stubs_size(MAX_stubs_size); | 503 buf.initialize_stubs_size(MAX_stubs_size); |
481 assert(locs_buf != NULL, "sanity"); | 504 assert(locs_buf != NULL, "sanity"); |
482 int lsize = MAX_locs_size / 2; | 505 int lsize = MAX_locs_size / 3; |
483 buf.insts()->initialize_shared_locs(&locs_buf[0], lsize); | 506 buf.consts()->initialize_shared_locs(&locs_buf[lsize * 0], lsize); |
484 buf.stubs()->initialize_shared_locs(&locs_buf[lsize], lsize); | 507 buf.insts()->initialize_shared_locs( &locs_buf[lsize * 1], lsize); |
508 buf.stubs()->initialize_shared_locs( &locs_buf[lsize * 2], lsize); | |
509 | |
510 // Do the emission. | |
485 n->emit(buf, this->regalloc()); | 511 n->emit(buf, this->regalloc()); |
512 | |
513 // End scratch_emit_size section. | |
514 set_in_scratch_emit_size(false); | |
515 | |
486 return buf.insts_size(); | 516 return buf.insts_size(); |
487 } | 517 } |
488 | 518 |
489 | 519 |
490 // ============================================================================ | 520 // ============================================================================ |
514 _failure_reason(NULL), | 544 _failure_reason(NULL), |
515 _code_buffer("Compile::Fill_buffer"), | 545 _code_buffer("Compile::Fill_buffer"), |
516 _orig_pc_slot(0), | 546 _orig_pc_slot(0), |
517 _orig_pc_slot_offset_in_bytes(0), | 547 _orig_pc_slot_offset_in_bytes(0), |
518 _has_method_handle_invokes(false), | 548 _has_method_handle_invokes(false), |
549 _mach_constant_base_node(NULL), | |
519 _node_bundling_limit(0), | 550 _node_bundling_limit(0), |
520 _node_bundling_base(NULL), | 551 _node_bundling_base(NULL), |
521 _java_calls(0), | 552 _java_calls(0), |
522 _inner_loops(0), | 553 _inner_loops(0), |
554 _scratch_const_size(-1), | |
555 _in_scratch_emit_size(false), | |
523 #ifndef PRODUCT | 556 #ifndef PRODUCT |
524 _trace_opto_output(TraceOptoOutput || method()->has_option("TraceOptoOutput")), | 557 _trace_opto_output(TraceOptoOutput || method()->has_option("TraceOptoOutput")), |
525 _printer(IdealGraphPrinter::printer()), | 558 _printer(IdealGraphPrinter::printer()), |
526 #endif | 559 #endif |
527 _congraph(NULL) { | 560 _congraph(NULL) { |
781 _subsume_loads(true), | 814 _subsume_loads(true), |
782 _do_escape_analysis(false), | 815 _do_escape_analysis(false), |
783 _failure_reason(NULL), | 816 _failure_reason(NULL), |
784 _code_buffer("Compile::Fill_buffer"), | 817 _code_buffer("Compile::Fill_buffer"), |
785 _has_method_handle_invokes(false), | 818 _has_method_handle_invokes(false), |
819 _mach_constant_base_node(NULL), | |
786 _node_bundling_limit(0), | 820 _node_bundling_limit(0), |
787 _node_bundling_base(NULL), | 821 _node_bundling_base(NULL), |
788 _java_calls(0), | 822 _java_calls(0), |
789 _inner_loops(0), | 823 _inner_loops(0), |
790 #ifndef PRODUCT | 824 #ifndef PRODUCT |
2860 Compile::TracePhase::~TracePhase() { | 2894 Compile::TracePhase::~TracePhase() { |
2861 if (_log != NULL) { | 2895 if (_log != NULL) { |
2862 _log->done("phase nodes='%d'", C->unique()); | 2896 _log->done("phase nodes='%d'", C->unique()); |
2863 } | 2897 } |
2864 } | 2898 } |
2899 | |
2900 //============================================================================= | |
2901 // Two Constant's are equal when the type and the value are equal. | |
2902 bool Compile::Constant::operator==(const Constant& other) { | |
2903 if (type() != other.type() ) return false; | |
2904 if (can_be_reused() != other.can_be_reused()) return false; | |
2905 // For floating point values we compare the bit pattern. | |
2906 switch (type()) { | |
2907 case T_FLOAT: return (_value.i == other._value.i); | |
2908 case T_LONG: | |
2909 case T_DOUBLE: return (_value.j == other._value.j); | |
2910 case T_OBJECT: | |
2911 case T_ADDRESS: return (_value.l == other._value.l); | |
2912 case T_VOID: return (_value.l == other._value.l); // jump-table entries | |
2913 default: ShouldNotReachHere(); | |
2914 } | |
2915 return false; | |
2916 } | |
2917 | |
2918 // Emit constants grouped in the following order: | |
2919 static BasicType type_order[] = { | |
2920 T_FLOAT, // 32-bit | |
2921 T_OBJECT, // 32 or 64-bit | |
2922 T_ADDRESS, // 32 or 64-bit | |
2923 T_DOUBLE, // 64-bit | |
2924 T_LONG, // 64-bit | |
2925 T_VOID, // 32 or 64-bit (jump-tables are at the end of the constant table for code emission reasons) | |
2926 T_ILLEGAL | |
2927 }; | |
2928 | |
2929 static int type_to_size_in_bytes(BasicType t) { | |
2930 switch (t) { | |
2931 case T_LONG: return sizeof(jlong ); | |
2932 case T_FLOAT: return sizeof(jfloat ); | |
2933 case T_DOUBLE: return sizeof(jdouble); | |
2934 // We use T_VOID as marker for jump-table entries (labels) which | |
2935 // need an interal word relocation. | |
2936 case T_VOID: | |
2937 case T_ADDRESS: | |
2938 case T_OBJECT: return sizeof(jobject); | |
2939 } | |
2940 | |
2941 ShouldNotReachHere(); | |
2942 return -1; | |
2943 } | |
2944 | |
2945 void Compile::ConstantTable::calculate_offsets_and_size() { | |
2946 int size = 0; | |
2947 for (int t = 0; type_order[t] != T_ILLEGAL; t++) { | |
2948 BasicType type = type_order[t]; | |
2949 | |
2950 for (int i = 0; i < _constants.length(); i++) { | |
2951 Constant con = _constants.at(i); | |
2952 if (con.type() != type) continue; // Skip other types. | |
2953 | |
2954 // Align size for type. | |
2955 int typesize = type_to_size_in_bytes(con.type()); | |
2956 size = align_size_up(size, typesize); | |
2957 | |
2958 // Set offset. | |
2959 con.set_offset(size); | |
2960 _constants.at_put(i, con); | |
2961 | |
2962 // Add type size. | |
2963 size = size + typesize; | |
2964 } | |
2965 } | |
2966 | |
2967 // Align size up to the next section start (which is insts; see | |
2968 // CodeBuffer::align_at_start). | |
2969 assert(_size == -1, "already set?"); | |
2970 _size = align_size_up(size, CodeEntryAlignment); | |
2971 | |
2972 if (Matcher::constant_table_absolute_addressing) { | |
2973 set_table_base_offset(0); // No table base offset required | |
2974 } else { | |
2975 if (UseRDPCForConstantTableBase) { | |
2976 // table base offset is set in MachConstantBaseNode::emit | |
2977 } else { | |
2978 // When RDPC is not used, the table base is set into the middle of | |
2979 // the constant table. | |
2980 int half_size = _size / 2; | |
2981 assert(half_size * 2 == _size, "sanity"); | |
2982 set_table_base_offset(-half_size); | |
2983 } | |
2984 } | |
2985 } | |
2986 | |
2987 void Compile::ConstantTable::emit(CodeBuffer& cb) { | |
2988 MacroAssembler _masm(&cb); | |
2989 for (int t = 0; type_order[t] != T_ILLEGAL; t++) { | |
2990 BasicType type = type_order[t]; | |
2991 | |
2992 for (int i = 0; i < _constants.length(); i++) { | |
2993 Constant con = _constants.at(i); | |
2994 if (con.type() != type) continue; // Skip other types. | |
2995 | |
2996 address constant_addr; | |
2997 switch (con.type()) { | |
2998 case T_LONG: constant_addr = _masm.long_constant( con.get_jlong() ); break; | |
2999 case T_FLOAT: constant_addr = _masm.float_constant( con.get_jfloat() ); break; | |
3000 case T_DOUBLE: constant_addr = _masm.double_constant(con.get_jdouble()); break; | |
3001 case T_OBJECT: { | |
3002 jobject obj = con.get_jobject(); | |
3003 int oop_index = _masm.oop_recorder()->find_index(obj); | |
3004 constant_addr = _masm.address_constant((address) obj, oop_Relocation::spec(oop_index)); | |
3005 break; | |
3006 } | |
3007 case T_ADDRESS: { | |
3008 address addr = (address) con.get_jobject(); | |
3009 constant_addr = _masm.address_constant(addr); | |
3010 break; | |
3011 } | |
3012 // We use T_VOID as marker for jump-table entries (labels) which | |
3013 // need an interal word relocation. | |
3014 case T_VOID: { | |
3015 // Write a dummy word. The real value is filled in later | |
3016 // in fill_jump_table_in_constant_table. | |
3017 address addr = (address) con.get_jobject(); | |
3018 constant_addr = _masm.address_constant(addr); | |
3019 break; | |
3020 } | |
3021 default: ShouldNotReachHere(); | |
3022 } | |
3023 assert(constant_addr != NULL, "consts section too small"); | |
3024 assert((constant_addr - _masm.code()->consts()->start()) == con.offset(), err_msg("must be: %d == %d", constant_addr - _masm.code()->consts()->start(), con.offset())); | |
3025 } | |
3026 } | |
3027 } | |
3028 | |
3029 int Compile::ConstantTable::find_offset(Constant& con) const { | |
3030 int idx = _constants.find(con); | |
3031 assert(idx != -1, "constant must be in constant table"); | |
3032 int offset = _constants.at(idx).offset(); | |
3033 assert(offset != -1, "constant table not emitted yet?"); | |
3034 return offset; | |
3035 } | |
3036 | |
3037 void Compile::ConstantTable::add(Constant& con) { | |
3038 if (con.can_be_reused()) { | |
3039 int idx = _constants.find(con); | |
3040 if (idx != -1 && _constants.at(idx).can_be_reused()) { | |
3041 return; | |
3042 } | |
3043 } | |
3044 (void) _constants.append(con); | |
3045 } | |
3046 | |
3047 Compile::Constant Compile::ConstantTable::add(BasicType type, jvalue value) { | |
3048 Constant con(type, value); | |
3049 add(con); | |
3050 return con; | |
3051 } | |
3052 | |
3053 Compile::Constant Compile::ConstantTable::add(MachOper* oper) { | |
3054 jvalue value; | |
3055 BasicType type = oper->type()->basic_type(); | |
3056 switch (type) { | |
3057 case T_LONG: value.j = oper->constantL(); break; | |
3058 case T_FLOAT: value.f = oper->constantF(); break; | |
3059 case T_DOUBLE: value.d = oper->constantD(); break; | |
3060 case T_OBJECT: | |
3061 case T_ADDRESS: value.l = (jobject) oper->constant(); break; | |
3062 default: ShouldNotReachHere(); | |
3063 } | |
3064 return add(type, value); | |
3065 } | |
3066 | |
3067 Compile::Constant Compile::ConstantTable::allocate_jump_table(MachConstantNode* n) { | |
3068 jvalue value; | |
3069 // We can use the node pointer here to identify the right jump-table | |
3070 // as this method is called from Compile::Fill_buffer right before | |
3071 // the MachNodes are emitted and the jump-table is filled (means the | |
3072 // MachNode pointers do not change anymore). | |
3073 value.l = (jobject) n; | |
3074 Constant con(T_VOID, value, false); // Labels of a jump-table cannot be reused. | |
3075 for (uint i = 0; i < n->outcnt(); i++) { | |
3076 add(con); | |
3077 } | |
3078 return con; | |
3079 } | |
3080 | |
3081 void Compile::ConstantTable::fill_jump_table(CodeBuffer& cb, MachConstantNode* n, GrowableArray<Label*> labels) const { | |
3082 // If called from Compile::scratch_emit_size do nothing. | |
3083 if (Compile::current()->in_scratch_emit_size()) return; | |
3084 | |
3085 assert(labels.is_nonempty(), "must be"); | |
3086 assert((uint) labels.length() == n->outcnt(), err_msg("must be equal: %d == %d", labels.length(), n->outcnt())); | |
3087 | |
3088 // Since MachConstantNode::constant_offset() also contains | |
3089 // table_base_offset() we need to subtract the table_base_offset() | |
3090 // to get the plain offset into the constant table. | |
3091 int offset = n->constant_offset() - table_base_offset(); | |
3092 | |
3093 MacroAssembler _masm(&cb); | |
3094 address* jump_table_base = (address*) (_masm.code()->consts()->start() + offset); | |
3095 | |
3096 for (int i = 0; i < labels.length(); i++) { | |
3097 address* constant_addr = &jump_table_base[i]; | |
3098 assert(*constant_addr == (address) n, "all jump-table entries must contain node pointer"); | |
3099 *constant_addr = cb.consts()->target(*labels.at(i), (address) constant_addr); | |
3100 cb.consts()->relocate((address) constant_addr, relocInfo::internal_word_type); | |
3101 } | |
3102 } |