src/share/vm/c1/c1_Runtime1.cpp

Print this page




  43 }
  44 
  45 
  46 void StubAssembler::set_frame_size(int size) {
  47   if (_frame_size == no_frame_size) {
  48     _frame_size = size;
  49   }
  50   assert(_frame_size == size, "can't change the frame size");
  51 }
  52 
  53 
  54 void StubAssembler::set_num_rt_args(int args) {
  55   if (_num_rt_args == 0) {
  56     _num_rt_args = args;
  57   }
  58   assert(_num_rt_args == args, "can't change the number of args");
  59 }
  60 
  61 // Implementation of Runtime1
  62 
  63 bool      Runtime1::_is_initialized = false;
  64 CodeBlob* Runtime1::_blobs[Runtime1::number_of_ids];
  65 const char *Runtime1::_blob_names[] = {
  66   RUNTIME1_STUBS(STUB_NAME, LAST_STUB_NAME)
  67 };
  68 
  69 #ifndef PRODUCT
  70 // statistics
  71 int Runtime1::_generic_arraycopy_cnt = 0;
  72 int Runtime1::_primitive_arraycopy_cnt = 0;
  73 int Runtime1::_oop_arraycopy_cnt = 0;
  74 int Runtime1::_arraycopy_slowcase_cnt = 0;
  75 int Runtime1::_new_type_array_slowcase_cnt = 0;
  76 int Runtime1::_new_object_array_slowcase_cnt = 0;
  77 int Runtime1::_new_instance_slowcase_cnt = 0;
  78 int Runtime1::_new_multi_array_slowcase_cnt = 0;
  79 int Runtime1::_monitorenter_slowcase_cnt = 0;
  80 int Runtime1::_monitorexit_slowcase_cnt = 0;
  81 int Runtime1::_patch_code_slowcase_cnt = 0;
  82 int Runtime1::_throw_range_check_exception_count = 0;
  83 int Runtime1::_throw_index_exception_count = 0;
  84 int Runtime1::_throw_div0_exception_count = 0;
  85 int Runtime1::_throw_null_pointer_exception_count = 0;
  86 int Runtime1::_throw_class_cast_exception_count = 0;
  87 int Runtime1::_throw_incompatible_class_change_error_count = 0;
  88 int Runtime1::_throw_array_store_exception_count = 0;
  89 int Runtime1::_throw_count = 0;
  90 #endif
  91 
  92 BufferBlob* Runtime1::_buffer_blob  = NULL;
  93 
  94 // Simple helper to see if the caller of a runtime stub which
  95 // entered the VM has been deoptimized
  96 
  97 static bool caller_is_deopted() {
  98   JavaThread* thread = JavaThread::current();
  99   RegisterMap reg_map(thread, false);
 100   frame runtime_frame = thread->last_frame();
 101   frame caller_frame = runtime_frame.sender(&reg_map);
 102   assert(caller_frame.is_compiled_frame(), "must be compiled");
 103   return caller_frame.is_deoptimized_frame();
 104 }
 105 
 106 // Stress deoptimization
 107 static void deopt_caller() {
 108   if ( !caller_is_deopted()) {
 109     JavaThread* thread = JavaThread::current();
 110     RegisterMap reg_map(thread, false);
 111     frame runtime_frame = thread->last_frame();
 112     frame caller_frame = runtime_frame.sender(&reg_map);
 113     // bypass VM_DeoptimizeFrame and deoptimize the frame directly
 114     Deoptimization::deoptimize_frame(thread, caller_frame.id());
 115     assert(caller_is_deopted(), "Must be deoptimized");
 116   }
 117 }
 118 
 119 
 120 BufferBlob* Runtime1::get_buffer_blob() {
 121   // Allocate code buffer space only once
 122   BufferBlob* blob = _buffer_blob;
 123   if (blob == NULL) {
 124     // setup CodeBuffer.  Preallocate a BufferBlob of size
 125     // NMethodSizeLimit plus some extra space for constants.
 126     int code_buffer_size = desired_max_code_buffer_size() + desired_max_constant_size();
 127     blob = BufferBlob::create("Compiler1 temporary CodeBuffer",
 128                               code_buffer_size);
 129     guarantee(blob != NULL, "must create initial code buffer");
 130     _buffer_blob = blob;
 131   }
 132   return _buffer_blob;
 133 }
 134 
 135 void Runtime1::setup_code_buffer(CodeBuffer* code, int call_stub_estimate) {
 136   // Preinitialize the consts section to some large size:
 137   int locs_buffer_size = 20 * (relocInfo::length_limit + sizeof(relocInfo));
 138   char* locs_buffer = NEW_RESOURCE_ARRAY(char, locs_buffer_size);
 139   code->insts()->initialize_shared_locs((relocInfo*)locs_buffer,
 140                                         locs_buffer_size / sizeof(relocInfo));
 141   code->initialize_consts_size(desired_max_constant_size());
 142   // Call stubs + deopt/exception handler
 143   code->initialize_stubs_size((call_stub_estimate * LIR_Assembler::call_stub_size) +
 144                               LIR_Assembler::exception_handler_size +
 145                               LIR_Assembler::deopt_handler_size);
 146 }
 147 
 148 
 149 void Runtime1::generate_blob_for(StubID id) {
 150   assert(0 <= id && id < number_of_ids, "illegal stub id");
 151   ResourceMark rm;
 152   // create code buffer for code storage
 153   CodeBuffer code(get_buffer_blob()->instructions_begin(),
 154                   get_buffer_blob()->instructions_size());
 155 
 156   setup_code_buffer(&code, 0);
 157 
 158   // create assembler for code generation
 159   StubAssembler* sasm = new StubAssembler(&code, name_for(id), id);
 160   // generate code for runtime stub
 161   OopMapSet* oop_maps;
 162   oop_maps = generate_code_for(id, sasm);
 163   assert(oop_maps == NULL || sasm->frame_size() != no_frame_size,
 164          "if stub has an oop map it must have a valid frame size");
 165 
 166 #ifdef ASSERT
 167   // Make sure that stubs that need oopmaps have them
 168   switch (id) {
 169     // These stubs don't need to have an oopmap
 170     case dtrace_object_alloc_id:
 171     case g1_pre_barrier_slow_id:
 172     case g1_post_barrier_slow_id:
 173     case slow_subtype_check_id:
 174     case fpu2long_stub_id:
 175     case unwind_exception_id:
 176 #ifndef TIERED


 187   }
 188 #endif
 189 
 190   // align so printing shows nop's instead of random code at the end (SimpleStubs are aligned)
 191   sasm->align(BytesPerWord);
 192   // make sure all code is in code buffer
 193   sasm->flush();
 194   // create blob - distinguish a few special cases
 195   CodeBlob* blob = RuntimeStub::new_runtime_stub(name_for(id),
 196                                                  &code,
 197                                                  CodeOffsets::frame_never_safe,
 198                                                  sasm->frame_size(),
 199                                                  oop_maps,
 200                                                  sasm->must_gc_arguments());
 201   // install blob
 202   assert(blob != NULL, "blob must exist");
 203   _blobs[id] = blob;
 204 }
 205 
 206 
 207 void Runtime1::initialize() {
 208   // Warning: If we have more than one compilation running in parallel, we
 209   //          need a lock here with the current setup (lazy initialization).
 210   if (!is_initialized()) {
 211     _is_initialized = true;
 212 
 213     // platform-dependent initialization
 214     initialize_pd();
 215     // generate stubs
 216     for (int id = 0; id < number_of_ids; id++) generate_blob_for((StubID)id);
 217     // printing
 218 #ifndef PRODUCT
 219     if (PrintSimpleStubs) {
 220       ResourceMark rm;
 221       for (int id = 0; id < number_of_ids; id++) {
 222         _blobs[id]->print();
 223         if (_blobs[id]->oop_maps() != NULL) {
 224           _blobs[id]->oop_maps()->print();
 225         }
 226       }
 227     }
 228 #endif
 229   }
 230 }
 231 
 232 
 233 CodeBlob* Runtime1::blob_for(StubID id) {
 234   assert(0 <= id && id < number_of_ids, "illegal stub id");
 235   if (!is_initialized()) initialize();
 236   return _blobs[id];
 237 }
 238 
 239 
 240 const char* Runtime1::name_for(StubID id) {
 241   assert(0 <= id && id < number_of_ids, "illegal stub id");
 242   return _blob_names[id];
 243 }
 244 
 245 const char* Runtime1::name_for_address(address entry) {
 246   for (int id = 0; id < number_of_ids; id++) {
 247     if (entry == entry_for((StubID)id)) return name_for((StubID)id);
 248   }
 249 
 250 #define FUNCTION_CASE(a, f) \
 251   if ((intptr_t)a == CAST_FROM_FN_PTR(intptr_t, f))  return #f
 252 
 253   FUNCTION_CASE(entry, os::javaTimeMillis);
 254   FUNCTION_CASE(entry, os::javaTimeNanos);
 255   FUNCTION_CASE(entry, SharedRuntime::OSR_migration_end);




  43 }
  44 
  45 
  46 void StubAssembler::set_frame_size(int size) {
  47   if (_frame_size == no_frame_size) {
  48     _frame_size = size;
  49   }
  50   assert(_frame_size == size, "can't change the frame size");
  51 }
  52 
  53 
  54 void StubAssembler::set_num_rt_args(int args) {
  55   if (_num_rt_args == 0) {
  56     _num_rt_args = args;
  57   }
  58   assert(_num_rt_args == args, "can't change the number of args");
  59 }
  60 
  61 // Implementation of Runtime1
  62 

  63 CodeBlob* Runtime1::_blobs[Runtime1::number_of_ids];
  64 const char *Runtime1::_blob_names[] = {
  65   RUNTIME1_STUBS(STUB_NAME, LAST_STUB_NAME)
  66 };
  67 
  68 #ifndef PRODUCT
  69 // statistics
  70 int Runtime1::_generic_arraycopy_cnt = 0;
  71 int Runtime1::_primitive_arraycopy_cnt = 0;
  72 int Runtime1::_oop_arraycopy_cnt = 0;
  73 int Runtime1::_arraycopy_slowcase_cnt = 0;
  74 int Runtime1::_new_type_array_slowcase_cnt = 0;
  75 int Runtime1::_new_object_array_slowcase_cnt = 0;
  76 int Runtime1::_new_instance_slowcase_cnt = 0;
  77 int Runtime1::_new_multi_array_slowcase_cnt = 0;
  78 int Runtime1::_monitorenter_slowcase_cnt = 0;
  79 int Runtime1::_monitorexit_slowcase_cnt = 0;
  80 int Runtime1::_patch_code_slowcase_cnt = 0;
  81 int Runtime1::_throw_range_check_exception_count = 0;
  82 int Runtime1::_throw_index_exception_count = 0;
  83 int Runtime1::_throw_div0_exception_count = 0;
  84 int Runtime1::_throw_null_pointer_exception_count = 0;
  85 int Runtime1::_throw_class_cast_exception_count = 0;
  86 int Runtime1::_throw_incompatible_class_change_error_count = 0;
  87 int Runtime1::_throw_array_store_exception_count = 0;
  88 int Runtime1::_throw_count = 0;
  89 #endif
  90 


  91 // Simple helper to see if the caller of a runtime stub which
  92 // entered the VM has been deoptimized
  93 
  94 static bool caller_is_deopted() {
  95   JavaThread* thread = JavaThread::current();
  96   RegisterMap reg_map(thread, false);
  97   frame runtime_frame = thread->last_frame();
  98   frame caller_frame = runtime_frame.sender(&reg_map);
  99   assert(caller_frame.is_compiled_frame(), "must be compiled");
 100   return caller_frame.is_deoptimized_frame();
 101 }
 102 
 103 // Stress deoptimization
 104 static void deopt_caller() {
 105   if ( !caller_is_deopted()) {
 106     JavaThread* thread = JavaThread::current();
 107     RegisterMap reg_map(thread, false);
 108     frame runtime_frame = thread->last_frame();
 109     frame caller_frame = runtime_frame.sender(&reg_map);
 110     // bypass VM_DeoptimizeFrame and deoptimize the frame directly
 111     Deoptimization::deoptimize_frame(thread, caller_frame.id());
 112     assert(caller_is_deopted(), "Must be deoptimized");
 113   }
 114 }
 115 
 116 
 117 void Runtime1::generate_blob_for(BufferBlob* buffer_blob, StubID id) {





























 118   assert(0 <= id && id < number_of_ids, "illegal stub id");
 119   ResourceMark rm;
 120   // create code buffer for code storage
 121   CodeBuffer code(buffer_blob->instructions_begin(),
 122                   buffer_blob->instructions_size());
 123 
 124   Compilation::setup_code_buffer(&code, 0);
 125 
 126   // create assembler for code generation
 127   StubAssembler* sasm = new StubAssembler(&code, name_for(id), id);
 128   // generate code for runtime stub
 129   OopMapSet* oop_maps;
 130   oop_maps = generate_code_for(id, sasm);
 131   assert(oop_maps == NULL || sasm->frame_size() != no_frame_size,
 132          "if stub has an oop map it must have a valid frame size");
 133 
 134 #ifdef ASSERT
 135   // Make sure that stubs that need oopmaps have them
 136   switch (id) {
 137     // These stubs don't need to have an oopmap
 138     case dtrace_object_alloc_id:
 139     case g1_pre_barrier_slow_id:
 140     case g1_post_barrier_slow_id:
 141     case slow_subtype_check_id:
 142     case fpu2long_stub_id:
 143     case unwind_exception_id:
 144 #ifndef TIERED


 155   }
 156 #endif
 157 
 158   // align so printing shows nop's instead of random code at the end (SimpleStubs are aligned)
 159   sasm->align(BytesPerWord);
 160   // make sure all code is in code buffer
 161   sasm->flush();
 162   // create blob - distinguish a few special cases
 163   CodeBlob* blob = RuntimeStub::new_runtime_stub(name_for(id),
 164                                                  &code,
 165                                                  CodeOffsets::frame_never_safe,
 166                                                  sasm->frame_size(),
 167                                                  oop_maps,
 168                                                  sasm->must_gc_arguments());
 169   // install blob
 170   assert(blob != NULL, "blob must exist");
 171   _blobs[id] = blob;
 172 }
 173 
 174 
 175 void Runtime1::initialize(BufferBlob* blob) {





 176   // platform-dependent initialization
 177   initialize_pd();
 178   // generate stubs
 179   for (int id = 0; id < number_of_ids; id++) generate_blob_for(blob, (StubID)id);
 180   // printing
 181 #ifndef PRODUCT
 182   if (PrintSimpleStubs) {
 183     ResourceMark rm;
 184     for (int id = 0; id < number_of_ids; id++) {
 185       _blobs[id]->print();
 186       if (_blobs[id]->oop_maps() != NULL) {
 187         _blobs[id]->oop_maps()->print();
 188       }
 189     }
 190   }
 191 #endif

 192 }
 193 
 194 
 195 CodeBlob* Runtime1::blob_for(StubID id) {
 196   assert(0 <= id && id < number_of_ids, "illegal stub id");

 197   return _blobs[id];
 198 }
 199 
 200 
 201 const char* Runtime1::name_for(StubID id) {
 202   assert(0 <= id && id < number_of_ids, "illegal stub id");
 203   return _blob_names[id];
 204 }
 205 
 206 const char* Runtime1::name_for_address(address entry) {
 207   for (int id = 0; id < number_of_ids; id++) {
 208     if (entry == entry_for((StubID)id)) return name_for((StubID)id);
 209   }
 210 
 211 #define FUNCTION_CASE(a, f) \
 212   if ((intptr_t)a == CAST_FROM_FN_PTR(intptr_t, f))  return #f
 213 
 214   FUNCTION_CASE(entry, os::javaTimeMillis);
 215   FUNCTION_CASE(entry, os::javaTimeNanos);
 216   FUNCTION_CASE(entry, SharedRuntime::OSR_migration_end);