< prev index next >

src/hotspot/share/c1/c1_LinearScan.cpp

Print this page

  46   // helper macro for short definition of timer
  47   #define TIME_LINEAR_SCAN(timer_name)  TraceTime _block_timer("", _total_timer.timer(LinearScanTimers::timer_name), TimeLinearScan || TimeEachLinearScan, Verbose);
  48 
  49 #else
  50   #define TIME_LINEAR_SCAN(timer_name)
  51 #endif
  52 
  53 #ifdef ASSERT
  54 
  55   // helper macro for short definition of trace-output inside code
  56   #define TRACE_LINEAR_SCAN(level, code)       \
  57     if (TraceLinearScanLevel >= level) {       \
  58       code;                                    \
  59     }
  60 #else
  61   #define TRACE_LINEAR_SCAN(level, code)
  62 #endif
  63 
  64 // Map BasicType to spill size in 32-bit words, matching VMReg's notion of words
  65 #ifdef _LP64
  66 static int type2spill_size[T_CONFLICT+1]={ -1, 0, 0, 0, 1, 1, 1, 2, 1, 1, 1, 2, 2, 2, 0, 2,  1, 2, 1, -1};
  67 #else
  68 static int type2spill_size[T_CONFLICT+1]={ -1, 0, 0, 0, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 0, 1, -1, 1, 1, -1};
  69 #endif
  70 
  71 
  72 // Implementation of LinearScan
  73 
  74 LinearScan::LinearScan(IR* ir, LIRGenerator* gen, FrameMap* frame_map)
  75  : _compilation(ir->compilation())
  76  , _ir(ir)
  77  , _gen(gen)
  78  , _frame_map(frame_map)
  79  , _cached_blocks(*ir->linear_scan_order())
  80  , _num_virtual_regs(gen->max_virtual_register_number())
  81  , _has_fpu_registers(false)
  82  , _num_calls(-1)
  83  , _max_spills(0)
  84  , _unused_spill_slot(-1)
  85  , _intervals(0)   // initialized later with correct length
  86  , _new_intervals_from_allocation(nullptr)
  87  , _sorted_intervals(nullptr)
  88  , _needs_full_resort(false)

 243   if (result > 2000) {
 244     bailout("too many stack slots used");
 245   }
 246 
 247   return result;
 248 }
 249 
 250 void LinearScan::assign_spill_slot(Interval* it) {
 251   // assign the canonical spill slot of the parent (if a part of the interval
 252   // is already spilled) or allocate a new spill slot
 253   if (it->canonical_spill_slot() >= 0) {
 254     it->assign_reg(it->canonical_spill_slot());
 255   } else {
 256     int spill = allocate_spill_slot(type2spill_size[it->type()] == 2);
 257     it->set_canonical_spill_slot(spill);
 258     it->assign_reg(spill);
 259   }
 260 }
 261 
 262 void LinearScan::propagate_spill_slots() {
 263   if (!frame_map()->finalize_frame(max_spills())) {
 264     bailout("frame too large");
 265   }
 266 }
 267 
 268 // create a new interval with a predefined reg_num
 269 // (only used for parent intervals that are created during the building phase)
 270 Interval* LinearScan::create_interval(int reg_num) {
 271   assert(_intervals.at(reg_num) == nullptr, "overwriting existing interval");
 272 
 273   Interval* interval = new Interval(reg_num);
 274   _intervals.at_put(reg_num, interval);
 275 
 276   // assign register number for precolored intervals
 277   if (reg_num < LIR_Opr::vreg_base) {
 278     interval->assign_reg(reg_num);
 279   }
 280   return interval;
 281 }
 282 
 283 // assign a new reg_num to the interval and append it to the list of intervals

2934     int pos = 0;
2935     while (pos < nof_stack) {
2936       Value expression = cur_state->stack_at(pos);
2937       pos += append_scope_value(op_id, expression, expressions);
2938 
2939       assert(expressions->length() == pos, "must match");
2940     }
2941     assert(expressions->length() == cur_state->stack_size(), "wrong number of stack entries");
2942   }
2943 
2944   // describe monitors
2945   int nof_locks = cur_state->locks_size();
2946   if (nof_locks > 0) {
2947     int lock_offset = cur_state->caller_state() != nullptr ? cur_state->caller_state()->total_locks_size() : 0;
2948     monitors = new GrowableArray<MonitorValue*>(nof_locks);
2949     for (int i = 0; i < nof_locks; i++) {
2950       monitors->append(location_for_monitor_index(lock_offset + i));
2951     }
2952   }
2953 
2954   return new IRScopeDebugInfo(cur_scope, cur_state->bci(), locals, expressions, monitors, caller_debug_info);
2955 }
2956 
2957 
2958 void LinearScan::compute_debug_info(CodeEmitInfo* info, int op_id) {
2959   TRACE_LINEAR_SCAN(3, tty->print_cr("creating debug information at op_id %d", op_id));
2960 
2961   IRScope* innermost_scope = info->scope();
2962   ValueStack* innermost_state = info->stack();
2963 
2964   assert(innermost_scope != nullptr && innermost_state != nullptr, "why is it missing?");
2965 
2966   DEBUG_ONLY(check_stack_depth(info, innermost_state->stack_size()));
2967 
2968   if (info->_scope_debug_info == nullptr) {
2969     // compute debug information
2970     info->_scope_debug_info = compute_debug_info_for_scope(op_id, innermost_scope, innermost_state, innermost_state);
2971   } else {
2972     // debug information already set. Check that it is correct from the current point of view
2973     DEBUG_ONLY(assert_equal(info->_scope_debug_info, compute_debug_info_for_scope(op_id, innermost_scope, innermost_state, innermost_state)));
2974   }

  46   // helper macro for short definition of timer
  47   #define TIME_LINEAR_SCAN(timer_name)  TraceTime _block_timer("", _total_timer.timer(LinearScanTimers::timer_name), TimeLinearScan || TimeEachLinearScan, Verbose);
  48 
  49 #else
  50   #define TIME_LINEAR_SCAN(timer_name)
  51 #endif
  52 
  53 #ifdef ASSERT
  54 
  55   // helper macro for short definition of trace-output inside code
  56   #define TRACE_LINEAR_SCAN(level, code)       \
  57     if (TraceLinearScanLevel >= level) {       \
  58       code;                                    \
  59     }
  60 #else
  61   #define TRACE_LINEAR_SCAN(level, code)
  62 #endif
  63 
  64 // Map BasicType to spill size in 32-bit words, matching VMReg's notion of words
  65 #ifdef _LP64
  66 static int type2spill_size[T_CONFLICT+1]={ -1, 0, 0, 0, 1, 1, 1, 2, 1, 1, 1, 2, 2, 2, 2, 0, 2,  1, 2, 1, -1};
  67 #else
  68 static int type2spill_size[T_CONFLICT+1]={ -1, 0, 0, 0, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 0, 1, -1, 1, 1, -1};
  69 #endif
  70 
  71 
  72 // Implementation of LinearScan
  73 
  74 LinearScan::LinearScan(IR* ir, LIRGenerator* gen, FrameMap* frame_map)
  75  : _compilation(ir->compilation())
  76  , _ir(ir)
  77  , _gen(gen)
  78  , _frame_map(frame_map)
  79  , _cached_blocks(*ir->linear_scan_order())
  80  , _num_virtual_regs(gen->max_virtual_register_number())
  81  , _has_fpu_registers(false)
  82  , _num_calls(-1)
  83  , _max_spills(0)
  84  , _unused_spill_slot(-1)
  85  , _intervals(0)   // initialized later with correct length
  86  , _new_intervals_from_allocation(nullptr)
  87  , _sorted_intervals(nullptr)
  88  , _needs_full_resort(false)

 243   if (result > 2000) {
 244     bailout("too many stack slots used");
 245   }
 246 
 247   return result;
 248 }
 249 
 250 void LinearScan::assign_spill_slot(Interval* it) {
 251   // assign the canonical spill slot of the parent (if a part of the interval
 252   // is already spilled) or allocate a new spill slot
 253   if (it->canonical_spill_slot() >= 0) {
 254     it->assign_reg(it->canonical_spill_slot());
 255   } else {
 256     int spill = allocate_spill_slot(type2spill_size[it->type()] == 2);
 257     it->set_canonical_spill_slot(spill);
 258     it->assign_reg(spill);
 259   }
 260 }
 261 
 262 void LinearScan::propagate_spill_slots() {
 263   if (!frame_map()->finalize_frame(max_spills(), compilation()->needs_stack_repair())) {
 264     bailout("frame too large");
 265   }
 266 }
 267 
 268 // create a new interval with a predefined reg_num
 269 // (only used for parent intervals that are created during the building phase)
 270 Interval* LinearScan::create_interval(int reg_num) {
 271   assert(_intervals.at(reg_num) == nullptr, "overwriting existing interval");
 272 
 273   Interval* interval = new Interval(reg_num);
 274   _intervals.at_put(reg_num, interval);
 275 
 276   // assign register number for precolored intervals
 277   if (reg_num < LIR_Opr::vreg_base) {
 278     interval->assign_reg(reg_num);
 279   }
 280   return interval;
 281 }
 282 
 283 // assign a new reg_num to the interval and append it to the list of intervals

2934     int pos = 0;
2935     while (pos < nof_stack) {
2936       Value expression = cur_state->stack_at(pos);
2937       pos += append_scope_value(op_id, expression, expressions);
2938 
2939       assert(expressions->length() == pos, "must match");
2940     }
2941     assert(expressions->length() == cur_state->stack_size(), "wrong number of stack entries");
2942   }
2943 
2944   // describe monitors
2945   int nof_locks = cur_state->locks_size();
2946   if (nof_locks > 0) {
2947     int lock_offset = cur_state->caller_state() != nullptr ? cur_state->caller_state()->total_locks_size() : 0;
2948     monitors = new GrowableArray<MonitorValue*>(nof_locks);
2949     for (int i = 0; i < nof_locks; i++) {
2950       monitors->append(location_for_monitor_index(lock_offset + i));
2951     }
2952   }
2953 
2954   return new IRScopeDebugInfo(cur_scope, cur_state->bci(), locals, expressions, monitors, caller_debug_info, cur_state->should_reexecute());
2955 }
2956 
2957 
2958 void LinearScan::compute_debug_info(CodeEmitInfo* info, int op_id) {
2959   TRACE_LINEAR_SCAN(3, tty->print_cr("creating debug information at op_id %d", op_id));
2960 
2961   IRScope* innermost_scope = info->scope();
2962   ValueStack* innermost_state = info->stack();
2963 
2964   assert(innermost_scope != nullptr && innermost_state != nullptr, "why is it missing?");
2965 
2966   DEBUG_ONLY(check_stack_depth(info, innermost_state->stack_size()));
2967 
2968   if (info->_scope_debug_info == nullptr) {
2969     // compute debug information
2970     info->_scope_debug_info = compute_debug_info_for_scope(op_id, innermost_scope, innermost_state, innermost_state);
2971   } else {
2972     // debug information already set. Check that it is correct from the current point of view
2973     DEBUG_ONLY(assert_equal(info->_scope_debug_info, compute_debug_info_for_scope(op_id, innermost_scope, innermost_state, innermost_state)));
2974   }
< prev index next >