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 }
|