src/share/vm/oops/methodData.hpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/oops

src/share/vm/oops/methodData.hpp

Print this page
rev 6953 : 8057038: Speculative traps not robust when compilation and class unloading are concurrent
Summary: speculative traps can be removed from MDO while being copied by compiler
Reviewed-by:


2090   // State of RTM code generation during compilation of the method
2091   int               _rtm_state;
2092 #endif
2093 
2094   // Number of loops and blocks is computed when compiling the first
2095   // time with C1. It is used to determine if method is trivial.
2096   short             _num_loops;
2097   short             _num_blocks;
2098   // Highest compile level this method has ever seen.
2099   u1                _highest_comp_level;
2100   // Same for OSR level
2101   u1                _highest_osr_comp_level;
2102   // Does this method contain anything worth profiling?
2103   bool              _would_profile;
2104 
2105   // Size of _data array in bytes.  (Excludes header and extra_data fields.)
2106   int _data_size;
2107 
2108   // data index for the area dedicated to parameters. -1 if no
2109   // parameter profiling.

2110   int _parameters_type_data_di;




2111 
2112   // Beginning of the data entries
2113   intptr_t _data[1];
2114 
2115   // Helper for size computation
2116   static int compute_data_size(BytecodeStream* stream);
2117   static int bytecode_cell_count(Bytecodes::Code code);
2118   static bool is_speculative_trap_bytecode(Bytecodes::Code code);
2119   enum { no_profile_data = -1, variable_cell_count = -2 };
2120 
2121   // Helper for initialization
2122   DataLayout* data_layout_at(int data_index) const {
2123     assert(data_index % sizeof(intptr_t) == 0, "unaligned");
2124     return (DataLayout*) (((address)_data) + data_index);
2125   }
2126 
2127   // Initialize an individual data segment.  Returns the size of
2128   // the segment in bytes.
2129   int initialize_data(BytecodeStream* stream, int data_index);
2130 
2131   // Helper for data_at
2132   DataLayout* limit_data_position() const {
2133     return (DataLayout*)((address)data_base() + _data_size);
2134   }
2135   bool out_of_bounds(int data_index) const {
2136     return data_index >= data_size();
2137   }
2138 
2139   // Give each of the data entries a chance to perform specific
2140   // data initialization.
2141   void post_initialize(BytecodeStream* stream);
2142 
2143   // hint accessors
2144   int      hint_di() const  { return _hint_di; }
2145   void set_hint_di(int di)  {
2146     assert(!out_of_bounds(di), "hint_di out of bounds");
2147     _hint_di = di;
2148   }
2149   ProfileData* data_before(int bci) {
2150     // avoid SEGV on this edge case
2151     if (data_size() == 0)
2152       return NULL;
2153     int hint = hint_di();


2356     }
2357     if (data != NULL) {
2358       return data;
2359     }
2360     data = bci_to_extra_data(bci, m, true);
2361     if (data != NULL) {
2362       return data;
2363     }
2364     // If SpeculativeTrapData allocation fails try to allocate a
2365     // regular entry
2366     data = bci_to_data(bci);
2367     if (data != NULL) {
2368       return data;
2369     }
2370     return bci_to_extra_data(bci, NULL, true);
2371   }
2372 
2373   // Add a handful of extra data records, for trap tracking.
2374   DataLayout* extra_data_base() const { return limit_data_position(); }
2375   DataLayout* extra_data_limit() const { return (DataLayout*)((address)this + size_in_bytes()); }
2376   int extra_data_size() const { return (address)extra_data_limit()
2377                                - (address)extra_data_base(); }

2378   static DataLayout* next_extra(DataLayout* dp);
2379 
2380   // Return (uint)-1 for overflow.
2381   uint trap_count(int reason) const {
2382     assert((uint)reason < _trap_hist_limit, "oob");
2383     return (int)((_trap_hist._array[reason]+1) & _trap_hist_mask) - 1;
2384   }
2385   // For loops:
2386   static uint trap_reason_limit() { return _trap_hist_limit; }
2387   static uint trap_count_limit()  { return _trap_hist_mask; }
2388   uint inc_trap_count(int reason) {
2389     // Count another trap, anywhere in this method.
2390     assert(reason >= 0, "must be single trap");
2391     if ((uint)reason < _trap_hist_limit) {
2392       uint cnt1 = 1 + _trap_hist._array[reason];
2393       if ((cnt1 & _trap_hist_mask) != 0) {  // if no counter overflow...
2394         _trap_hist._array[reason] = cnt1;
2395         return cnt1;
2396       } else {
2397         return _trap_hist_mask + (++_nof_overflow_traps);


2412     _nof_overflow_recompiles += 1;
2413   }
2414   uint decompile_count() const {
2415     return _nof_decompiles;
2416   }
2417   void inc_decompile_count() {
2418     _nof_decompiles += 1;
2419     if (decompile_count() > (uint)PerMethodRecompilationCutoff) {
2420       method()->set_not_compilable(CompLevel_full_optimization, true, "decompile_count > PerMethodRecompilationCutoff");
2421     }
2422   }
2423   uint tenure_traps() const {
2424     return _tenure_traps;
2425   }
2426   void inc_tenure_traps() {
2427     _tenure_traps += 1;
2428   }
2429 
2430   // Return pointer to area dedicated to parameters in MDO
2431   ParametersTypeData* parameters_type_data() const {
2432     return _parameters_type_data_di != -1 ? data_layout_at(_parameters_type_data_di)->data_in()->as_ParametersTypeData() : NULL;

2433   }
2434 
2435   int parameters_type_data_di() const {
2436     assert(_parameters_type_data_di != -1, "no args type data");
2437     return _parameters_type_data_di;
2438   }
2439 
2440   // Support for code generation
2441   static ByteSize data_offset() {
2442     return byte_offset_of(MethodData, _data[0]);
2443   }
2444 
2445   static ByteSize invocation_counter_offset() {
2446     return byte_offset_of(MethodData, _invocation_counter);
2447   }
2448   static ByteSize backedge_counter_offset() {
2449     return byte_offset_of(MethodData, _backedge_counter);
2450   }
2451 
2452   static ByteSize parameters_type_data_di_offset() {
2453     return byte_offset_of(MethodData, _parameters_type_data_di);
2454   }
2455 
2456   // Deallocation support - no pointer fields to deallocate


2463   void print_on      (outputStream* st) const;
2464   void print_value_on(outputStream* st) const;
2465 
2466   // printing support for method data
2467   void print_data_on(outputStream* st) const;
2468 
2469   const char* internal_name() const { return "{method data}"; }
2470 
2471   // verification
2472   void verify_on(outputStream* st);
2473   void verify_data_on(outputStream* st);
2474 
2475   static bool profile_parameters_for_method(methodHandle m);
2476   static bool profile_arguments();
2477   static bool profile_arguments_jsr292_only();
2478   static bool profile_return();
2479   static bool profile_parameters();
2480   static bool profile_return_jsr292_only();
2481 
2482   void clean_method_data(BoolObjectClosure* is_alive);
2483 
2484   void clean_weak_method_links();

2485 };
2486 
2487 #endif // SHARE_VM_OOPS_METHODDATAOOP_HPP


2090   // State of RTM code generation during compilation of the method
2091   int               _rtm_state;
2092 #endif
2093 
2094   // Number of loops and blocks is computed when compiling the first
2095   // time with C1. It is used to determine if method is trivial.
2096   short             _num_loops;
2097   short             _num_blocks;
2098   // Highest compile level this method has ever seen.
2099   u1                _highest_comp_level;
2100   // Same for OSR level
2101   u1                _highest_osr_comp_level;
2102   // Does this method contain anything worth profiling?
2103   bool              _would_profile;
2104 
2105   // Size of _data array in bytes.  (Excludes header and extra_data fields.)
2106   int _data_size;
2107 
2108   // data index for the area dedicated to parameters. -1 if no
2109   // parameter profiling.
2110   enum { no_parameters = -2, parameters_uninitialized = -1 };
2111   int _parameters_type_data_di;
2112   int parameters_size_in_bytes() const {
2113     ParametersTypeData* param = parameters_type_data();
2114     return param == NULL ? 0 : param->size_in_bytes();
2115   }
2116 
2117   // Beginning of the data entries
2118   intptr_t _data[1];
2119 
2120   // Helper for size computation
2121   static int compute_data_size(BytecodeStream* stream);
2122   static int bytecode_cell_count(Bytecodes::Code code);
2123   static bool is_speculative_trap_bytecode(Bytecodes::Code code);
2124   enum { no_profile_data = -1, variable_cell_count = -2 };
2125 
2126   // Helper for initialization
2127   DataLayout* data_layout_at(int data_index) const {
2128     assert(data_index % sizeof(intptr_t) == 0, "unaligned");
2129     return (DataLayout*) (((address)_data) + data_index);
2130   }
2131 
2132   // Initialize an individual data segment.  Returns the size of
2133   // the segment in bytes.
2134   int initialize_data(BytecodeStream* stream, int data_index);
2135 
2136   // Helper for data_at
2137   DataLayout* limit_data_position() const {
2138     return data_layout_at(_data_size);
2139   }
2140   bool out_of_bounds(int data_index) const {
2141     return data_index >= data_size();
2142   }
2143 
2144   // Give each of the data entries a chance to perform specific
2145   // data initialization.
2146   void post_initialize(BytecodeStream* stream);
2147 
2148   // hint accessors
2149   int      hint_di() const  { return _hint_di; }
2150   void set_hint_di(int di)  {
2151     assert(!out_of_bounds(di), "hint_di out of bounds");
2152     _hint_di = di;
2153   }
2154   ProfileData* data_before(int bci) {
2155     // avoid SEGV on this edge case
2156     if (data_size() == 0)
2157       return NULL;
2158     int hint = hint_di();


2361     }
2362     if (data != NULL) {
2363       return data;
2364     }
2365     data = bci_to_extra_data(bci, m, true);
2366     if (data != NULL) {
2367       return data;
2368     }
2369     // If SpeculativeTrapData allocation fails try to allocate a
2370     // regular entry
2371     data = bci_to_data(bci);
2372     if (data != NULL) {
2373       return data;
2374     }
2375     return bci_to_extra_data(bci, NULL, true);
2376   }
2377 
2378   // Add a handful of extra data records, for trap tracking.
2379   DataLayout* extra_data_base() const  { return limit_data_position(); }
2380   DataLayout* extra_data_limit() const { return (DataLayout*)((address)this + size_in_bytes()); }
2381   DataLayout* args_data_limit() const  { return (DataLayout*)((address)this + size_in_bytes() -
2382                                                               parameters_size_in_bytes()); }
2383   int extra_data_size() const          { return (address)extra_data_limit() - (address)extra_data_base(); }
2384   static DataLayout* next_extra(DataLayout* dp);
2385 
2386   // Return (uint)-1 for overflow.
2387   uint trap_count(int reason) const {
2388     assert((uint)reason < _trap_hist_limit, "oob");
2389     return (int)((_trap_hist._array[reason]+1) & _trap_hist_mask) - 1;
2390   }
2391   // For loops:
2392   static uint trap_reason_limit() { return _trap_hist_limit; }
2393   static uint trap_count_limit()  { return _trap_hist_mask; }
2394   uint inc_trap_count(int reason) {
2395     // Count another trap, anywhere in this method.
2396     assert(reason >= 0, "must be single trap");
2397     if ((uint)reason < _trap_hist_limit) {
2398       uint cnt1 = 1 + _trap_hist._array[reason];
2399       if ((cnt1 & _trap_hist_mask) != 0) {  // if no counter overflow...
2400         _trap_hist._array[reason] = cnt1;
2401         return cnt1;
2402       } else {
2403         return _trap_hist_mask + (++_nof_overflow_traps);


2418     _nof_overflow_recompiles += 1;
2419   }
2420   uint decompile_count() const {
2421     return _nof_decompiles;
2422   }
2423   void inc_decompile_count() {
2424     _nof_decompiles += 1;
2425     if (decompile_count() > (uint)PerMethodRecompilationCutoff) {
2426       method()->set_not_compilable(CompLevel_full_optimization, true, "decompile_count > PerMethodRecompilationCutoff");
2427     }
2428   }
2429   uint tenure_traps() const {
2430     return _tenure_traps;
2431   }
2432   void inc_tenure_traps() {
2433     _tenure_traps += 1;
2434   }
2435 
2436   // Return pointer to area dedicated to parameters in MDO
2437   ParametersTypeData* parameters_type_data() const {
2438     assert(_parameters_type_data_di != parameters_uninitialized, "called too early");
2439     return _parameters_type_data_di != no_parameters ? data_layout_at(_parameters_type_data_di)->data_in()->as_ParametersTypeData() : NULL;
2440   }
2441 
2442   int parameters_type_data_di() const {
2443     assert(_parameters_type_data_di != parameters_uninitialized && _parameters_type_data_di != no_parameters, "no args type data");
2444     return _parameters_type_data_di;
2445   }
2446 
2447   // Support for code generation
2448   static ByteSize data_offset() {
2449     return byte_offset_of(MethodData, _data[0]);
2450   }
2451 
2452   static ByteSize invocation_counter_offset() {
2453     return byte_offset_of(MethodData, _invocation_counter);
2454   }
2455   static ByteSize backedge_counter_offset() {
2456     return byte_offset_of(MethodData, _backedge_counter);
2457   }
2458 
2459   static ByteSize parameters_type_data_di_offset() {
2460     return byte_offset_of(MethodData, _parameters_type_data_di);
2461   }
2462 
2463   // Deallocation support - no pointer fields to deallocate


2470   void print_on      (outputStream* st) const;
2471   void print_value_on(outputStream* st) const;
2472 
2473   // printing support for method data
2474   void print_data_on(outputStream* st) const;
2475 
2476   const char* internal_name() const { return "{method data}"; }
2477 
2478   // verification
2479   void verify_on(outputStream* st);
2480   void verify_data_on(outputStream* st);
2481 
2482   static bool profile_parameters_for_method(methodHandle m);
2483   static bool profile_arguments();
2484   static bool profile_arguments_jsr292_only();
2485   static bool profile_return();
2486   static bool profile_parameters();
2487   static bool profile_return_jsr292_only();
2488 
2489   void clean_method_data(BoolObjectClosure* is_alive);

2490   void clean_weak_method_links();
2491   Mutex* extra_data_lock() { return &_extra_data_lock; }
2492 };
2493 
2494 #endif // SHARE_VM_OOPS_METHODDATAOOP_HPP
src/share/vm/oops/methodData.hpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File