src/share/vm/opto/compile.cpp

Print this page
rev 3361 : 7173584: Implement arraycopy as a macro node
Summary: delay the conversion of arraycopy to stub calls to macro expansion
Reviewed-by:


3226   if (Compile::current()->in_scratch_emit_size())  return;
3227 
3228   assert(labels.is_nonempty(), "must be");
3229   assert((uint) labels.length() == n->outcnt(), err_msg("must be equal: %d == %d", labels.length(), n->outcnt()));
3230 
3231   // Since MachConstantNode::constant_offset() also contains
3232   // table_base_offset() we need to subtract the table_base_offset()
3233   // to get the plain offset into the constant table.
3234   int offset = n->constant_offset() - table_base_offset();
3235 
3236   MacroAssembler _masm(&cb);
3237   address* jump_table_base = (address*) (_masm.code()->consts()->start() + offset);
3238 
3239   for (uint i = 0; i < n->outcnt(); i++) {
3240     address* constant_addr = &jump_table_base[i];
3241     assert(*constant_addr == (((address) n) + i), err_msg("all jump-table entries must contain adjusted node pointer: " INTPTR_FORMAT " == " INTPTR_FORMAT, *constant_addr, (((address) n) + i)));
3242     *constant_addr = cb.consts()->target(*labels.at(i), (address) constant_addr);
3243     cb.consts()->relocate((address) constant_addr, relocInfo::internal_word_type);
3244   }
3245 }




















































3226   if (Compile::current()->in_scratch_emit_size())  return;
3227 
3228   assert(labels.is_nonempty(), "must be");
3229   assert((uint) labels.length() == n->outcnt(), err_msg("must be equal: %d == %d", labels.length(), n->outcnt()));
3230 
3231   // Since MachConstantNode::constant_offset() also contains
3232   // table_base_offset() we need to subtract the table_base_offset()
3233   // to get the plain offset into the constant table.
3234   int offset = n->constant_offset() - table_base_offset();
3235 
3236   MacroAssembler _masm(&cb);
3237   address* jump_table_base = (address*) (_masm.code()->consts()->start() + offset);
3238 
3239   for (uint i = 0; i < n->outcnt(); i++) {
3240     address* constant_addr = &jump_table_base[i];
3241     assert(*constant_addr == (((address) n) + i), err_msg("all jump-table entries must contain adjusted node pointer: " INTPTR_FORMAT " == " INTPTR_FORMAT, *constant_addr, (((address) n) + i)));
3242     *constant_addr = cb.consts()->target(*labels.at(i), (address) constant_addr);
3243     cb.consts()->relocate((address) constant_addr, relocInfo::internal_word_type);
3244   }
3245 }
3246 
3247 //----------------------------static_subtype_check-----------------------------
3248 // Shortcut important common cases when superklass is exact:
3249 // (0) superklass is java.lang.Object (can occur in reflective code)
3250 // (1) subklass is already limited to a subtype of superklass => always ok
3251 // (2) subklass does not overlap with superklass => always fail
3252 // (3) superklass has NO subtypes and we can check with a simple compare.
3253 int Compile::static_subtype_check(ciKlass* superk, ciKlass* subk) {
3254   if (StressReflectiveCode) {
3255     return SSC_full_test;       // Let caller generate the general case.
3256   }
3257 
3258   if (superk == env()->Object_klass()) {
3259     return SSC_always_true;     // (0) this test cannot fail
3260   }
3261 
3262   ciType* superelem = superk;
3263   if (superelem->is_array_klass())
3264     superelem = superelem->as_array_klass()->base_element_type();
3265 
3266   if (!subk->is_interface()) {  // cannot trust static interface types yet
3267     if (subk->is_subtype_of(superk)) {
3268       return SSC_always_true;   // (1) false path dead; no dynamic test needed
3269     }
3270     if (!(superelem->is_klass() && superelem->as_klass()->is_interface()) &&
3271         !superk->is_subtype_of(subk)) {
3272       return SSC_always_false;
3273     }
3274   }
3275 
3276   // If casting to an instance klass, it must have no subtypes
3277   if (superk->is_interface()) {
3278     // Cannot trust interfaces yet.
3279     // %%% S.B. superk->nof_implementors() == 1
3280   } else if (superelem->is_instance_klass()) {
3281     ciInstanceKlass* ik = superelem->as_instance_klass();
3282     if (!ik->has_subklass() && !ik->is_interface()) {
3283       if (!ik->is_final()) {
3284         // Add a dependency if there is a chance of a later subclass.
3285         dependencies()->assert_leaf_type(ik);
3286       }
3287       return SSC_easy_test;     // (3) caller can do a simple ptr comparison
3288     }
3289   } else {
3290     // A primitive array type has no subtypes.
3291     return SSC_easy_test;       // (3) caller can do a simple ptr comparison
3292   }
3293 
3294   return SSC_full_test;
3295 }